@notectl/core 0.0.2 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1816 -0
- package/dist/notectl-core.js +1046 -2204
- package/dist/notectl-core.js.map +1 -1
- package/dist/notectl-core.mjs +7886 -0
- package/dist/notectl-core.mjs.map +1 -0
- package/package.json +31 -55
- package/dist/notectl-core.umd.cjs +0 -113
- package/dist/notectl-core.umd.cjs.map +0 -1
- package/dist/types/index.d.ts +0 -1090
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notectl-core.mjs","sources":["../src/model/Document.ts","../src/model/Selection.ts","../src/model/Schema.ts","../src/model/TypeBrands.ts","../src/model/AttrRegistry.ts","../src/model/NodeSpec.ts","../src/model/SchemaRegistry.ts","../src/model/NodeResolver.ts","../src/model/ContentModel.ts","../src/model/BuiltinSpecs.ts","../src/state/StepApplication.ts","../src/state/Transaction.ts","../src/state/EditorState.ts","../src/state/History.ts","../src/commands/Commands.ts","../src/input/KeyboardHandler.ts","../src/plugins/Plugin.ts","../src/plugins/EventBus.ts","../src/decorations/PositionMapping.ts","../src/decorations/Decoration.ts","../src/plugins/PluginManager.ts","../src/plugins/toolbar/ToolbarPlugin.ts","../src/plugins/toolbar/ToolbarItem.ts","../src/plugins/text-formatting/TextFormattingPlugin.ts","../src/plugins/heading/HeadingPlugin.ts","../src/plugins/link/LinkPlugin.ts","../src/plugins/list/ListPlugin.ts","../src/plugins/blockquote/BlockquotePlugin.ts","../src/plugins/strikethrough/StrikethroughPlugin.ts","../src/plugins/text-color/TextColorPlugin.ts","../src/plugins/horizontal-rule/HorizontalRulePlugin.ts","../src/plugins/text-alignment/TextAlignmentPlugin.ts","../src/plugins/font/FontPlugin.ts","../src/plugins/font-size/FontSizePlugin.ts","../src/plugins/font/StarterFonts.ts","../src/plugins/table/TableHelpers.ts","../src/plugins/table/TableCommands.ts","../src/plugins/table/TableNavigation.ts","../src/view/Reconciler.ts","../src/plugins/table/TableControls.ts","../src/plugins/table/TableNodeViews.ts","../src/plugins/table/TableSelection.ts","../src/plugins/table/TablePlugin.ts","../src/plugins/highlight/HighlightPlugin.ts","../src/plugins/super-sub/SuperSubPlugin.ts","../src/input/InputHandler.ts","../src/input/PasteHandler.ts","../src/view/SelectionSync.ts","../src/view/EditorView.ts","../src/editor/styles.ts","../src/editor/NotectlEditor.ts"],"sourcesContent":["/**\n * Core document model types for the Notectl editor.\n * All types are deeply readonly — mutations create new instances.\n */\n\nimport type { BlockId, InlineTypeName, MarkTypeName, NodeTypeName } from './TypeBrands.js';\n\n// --- Mark Types ---\n\n/** @deprecated Use {@link MarkTypeName} for new code. */\nexport type MarkType = MarkTypeName;\n\nexport interface Mark {\n\treadonly type: MarkTypeName;\n\treadonly attrs?: Readonly<Record<string, string | number | boolean>>;\n}\n\nexport interface BoldMark extends Mark {\n\treadonly type: MarkTypeName & 'bold';\n}\n\nexport interface ItalicMark extends Mark {\n\treadonly type: MarkTypeName & 'italic';\n}\n\nexport interface UnderlineMark extends Mark {\n\treadonly type: MarkTypeName & 'underline';\n}\n\n// --- Node Types ---\n\n/** @deprecated Use {@link NodeTypeName} for new code. */\nexport type NodeType = NodeTypeName;\n\nexport interface BlockAttrs {\n\treadonly [key: string]: string | number | boolean;\n}\n\nexport interface TextNode {\n\treadonly type: 'text';\n\treadonly text: string;\n\treadonly marks: readonly Mark[];\n}\n\n/** Atomic inline element (width 1 in offset space). */\nexport interface InlineNode {\n\treadonly type: 'inline';\n\treadonly inlineType: InlineTypeName;\n\treadonly attrs: Readonly<Record<string, string | number | boolean>>;\n}\n\n/** A child of a BlockNode: text, inline element, or nested block. */\nexport type ChildNode = TextNode | InlineNode | BlockNode;\n\nexport interface BlockNode {\n\treadonly id: BlockId;\n\treadonly type: NodeTypeName;\n\treadonly attrs?: BlockAttrs;\n\treadonly children: readonly ChildNode[];\n}\n\nexport interface Document {\n\treadonly children: readonly BlockNode[];\n}\n\n// --- Text Segment (for mark-preserving undo) ---\n\nexport interface TextSegment {\n\treadonly text: string;\n\treadonly marks: readonly Mark[];\n}\n\n/** A content segment: either text (with marks) or an inline node. */\nexport type ContentSegment =\n\t| { readonly kind: 'text'; readonly text: string; readonly marks: readonly Mark[] }\n\t| { readonly kind: 'inline'; readonly node: InlineNode };\n\n/** Extracts TextNode segments within a block for the given offset range. */\nexport function getBlockSegmentsInRange(\n\tblock: BlockNode,\n\tfrom: number,\n\tto: number,\n): readonly TextSegment[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tconst segments: TextSegment[] = [];\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tconst childWidth: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tconst childEnd: number = pos + childWidth;\n\n\t\tif (childEnd <= from || pos >= to) {\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isInlineNode(child)) {\n\t\t\t// InlineNodes are skipped for TextSegment extraction\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst sliceFrom: number = Math.max(0, from - pos);\n\t\tconst sliceTo: number = Math.min(child.text.length, to - pos);\n\t\tconst text: string = child.text.slice(sliceFrom, sliceTo);\n\n\t\tif (text.length > 0) {\n\t\t\tsegments.push({ text, marks: child.marks });\n\t\t}\n\n\t\tpos = childEnd;\n\t}\n\n\treturn segments;\n}\n\n/** Returns content segments (text and inline) for a block range. */\nexport function getBlockContentSegmentsInRange(\n\tblock: BlockNode,\n\tfrom: number,\n\tto: number,\n): readonly ContentSegment[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tconst segments: ContentSegment[] = [];\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tconst childWidth: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tconst childEnd: number = pos + childWidth;\n\n\t\tif (childEnd <= from || pos >= to) {\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isInlineNode(child)) {\n\t\t\tsegments.push({ kind: 'inline', node: child });\n\t\t} else {\n\t\t\tconst sliceFrom: number = Math.max(0, from - pos);\n\t\t\tconst sliceTo: number = Math.min(child.text.length, to - pos);\n\t\t\tconst text: string = child.text.slice(sliceFrom, sliceTo);\n\t\t\tif (text.length > 0) {\n\t\t\t\tsegments.push({ kind: 'text', text, marks: child.marks });\n\t\t\t}\n\t\t}\n\n\t\tpos = childEnd;\n\t}\n\n\treturn segments;\n}\n\n// --- Type Guards ---\n\n/** Checks whether a value is a {@link TextNode}. */\nexport function isTextNode(node: unknown): node is TextNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\t(node as TextNode).type === 'text' &&\n\t\ttypeof (node as TextNode).text === 'string'\n\t);\n}\n\n/** Checks whether a value is an {@link InlineNode}. */\nexport function isInlineNode(node: unknown): node is InlineNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\t(node as InlineNode).type === 'inline' &&\n\t\ttypeof (node as InlineNode).inlineType === 'string'\n\t);\n}\n\n/** Checks whether a value is a {@link BlockNode}. */\nexport function isBlockNode(node: unknown): node is BlockNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\ttypeof (node as BlockNode).id === 'string' &&\n\t\ttypeof (node as BlockNode).type === 'string' &&\n\t\t(node as BlockNode).type !== ('text' as string) &&\n\t\t(node as BlockNode).type !== ('inline' as string) &&\n\t\tArray.isArray((node as BlockNode).children)\n\t);\n}\n\n// --- Child Node Helpers ---\n\n/** Returns true if a block has only inline content (TextNodes and InlineNodes). */\nexport function isLeafBlock(node: BlockNode): boolean {\n\treturn node.children.every((c) => isTextNode(c) || isInlineNode(c));\n}\n\n/** Returns only the TextNode children of a block. */\nexport function getTextChildren(node: BlockNode): readonly TextNode[] {\n\treturn node.children.filter((c): c is TextNode => isTextNode(c));\n}\n\n/** Returns the inline content children (TextNode | InlineNode) of a block. */\nexport function getInlineChildren(node: BlockNode): readonly (TextNode | InlineNode)[] {\n\treturn node.children.filter((c): c is TextNode | InlineNode => isTextNode(c) || isInlineNode(c));\n}\n\n/** Returns only the BlockNode children of a block. */\nexport function getBlockChildren(node: BlockNode): readonly BlockNode[] {\n\treturn node.children.filter((c): c is BlockNode => isBlockNode(c));\n}\n\n// --- Factory Functions ---\n\n/** Generates a unique block ID using crypto.randomUUID(). */\nexport function generateBlockId(): BlockId {\n\treturn `block-${crypto.randomUUID()}` as BlockId;\n}\n\n/** Creates a new empty {@link Document} with a single empty paragraph. */\nexport function createDocument(children?: readonly BlockNode[]): Document {\n\treturn {\n\t\tchildren: children ?? [createBlockNode('paragraph' as NodeTypeName)],\n\t};\n}\n\n/** Creates a new {@link BlockNode}. */\nexport function createBlockNode(\n\ttype: NodeTypeName,\n\tchildren?: readonly ChildNode[],\n\tid?: BlockId,\n\tattrs?: BlockAttrs,\n): BlockNode {\n\treturn {\n\t\tid: id ?? generateBlockId(),\n\t\ttype,\n\t\t...(attrs ? { attrs } : {}),\n\t\tchildren: children ?? [createTextNode('')],\n\t};\n}\n\n/** Creates a new {@link TextNode}. */\nexport function createTextNode(text: string, marks?: readonly Mark[]): TextNode {\n\treturn {\n\t\ttype: 'text',\n\t\ttext,\n\t\tmarks: marks ?? [],\n\t};\n}\n\n/** Creates a new {@link InlineNode}. */\nexport function createInlineNode(\n\tinlineType: InlineTypeName,\n\tattrs?: Readonly<Record<string, string | number | boolean>>,\n): InlineNode {\n\treturn {\n\t\ttype: 'inline',\n\t\tinlineType,\n\t\tattrs: attrs ?? {},\n\t};\n}\n\n// --- Utility Functions ---\n\n/** Extracts plain text from a block (InlineNodes are skipped). */\nexport function getBlockText(block: BlockNode): string {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet text = '';\n\tfor (const child of inlineChildren) {\n\t\tif (isTextNode(child)) {\n\t\t\ttext += child.text;\n\t\t}\n\t}\n\treturn text;\n}\n\n/** Returns the length of a block's inline content (InlineNodes count as 1). */\nexport function getBlockLength(block: BlockNode): number {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet len = 0;\n\tfor (const child of inlineChildren) {\n\t\tlen += isInlineNode(child) ? 1 : child.text.length;\n\t}\n\treturn len;\n}\n\n/** Returns the marks active at the given offset (empty for InlineNode offsets). */\nexport function getBlockMarksAtOffset(block: BlockNode, offset: number): readonly Mark[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tif (isInlineNode(child)) {\n\t\t\tif (offset === pos) return [];\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst end: number = pos + child.text.length;\n\t\tif (offset >= pos && offset < end) {\n\t\t\treturn child.marks;\n\t\t}\n\t\tif (offset === pos && child.text.length === 0) {\n\t\t\treturn child.marks;\n\t\t}\n\t\tpos = end;\n\t}\n\n\t// Fall back to last text child's marks\n\tfor (let i: number = inlineChildren.length - 1; i >= 0; i--) {\n\t\tconst child: TextNode | InlineNode | undefined = inlineChildren[i];\n\t\tif (child && isTextNode(child)) {\n\t\t\treturn child.marks;\n\t\t}\n\t}\n\treturn [];\n}\n\n/** Checks whether two marks are equal by type and attrs. */\nexport function marksEqual(a: Mark, b: Mark): boolean {\n\tif (a.type !== b.type) return false;\n\tconst aAttrs = a.attrs;\n\tconst bAttrs = b.attrs;\n\tif (!aAttrs && !bAttrs) return true;\n\tif (!aAttrs || !bAttrs) return false;\n\tconst aKeys = Object.keys(aAttrs);\n\tconst bKeys = Object.keys(bAttrs);\n\tif (aKeys.length !== bKeys.length) return false;\n\treturn aKeys.every((key) => aAttrs[key] === bAttrs[key]);\n}\n\n/** Checks whether two mark arrays contain the same marks (order-independent). */\nexport function markSetsEqual(a: readonly Mark[], b: readonly Mark[]): boolean {\n\tif (a.length !== b.length) return false;\n\treturn a.every((markA) => b.some((markB) => marksEqual(markA, markB)));\n}\n\n/** Returns true if the mark set contains a mark of the given type. */\nexport function hasMark(marks: readonly Mark[], markType: MarkTypeName): boolean {\n\treturn marks.some((m) => m.type === markType);\n}\n\n/** Adds a mark to a mark set (no duplicates). */\nexport function addMarkToSet(marks: readonly Mark[], mark: Mark): readonly Mark[] {\n\tif (hasMark(marks, mark.type)) return marks;\n\treturn [...marks, mark];\n}\n\n/** Removes a mark type from a mark set. */\nexport function removeMarkFromSet(marks: readonly Mark[], markType: MarkTypeName): readonly Mark[] {\n\treturn marks.filter((m) => m.type !== markType);\n}\n\n/**\n * Normalizes text nodes within a block: merges adjacent nodes with identical marks,\n * removes empty text nodes (keeping at least one).\n */\nexport function normalizeTextNodes(nodes: readonly TextNode[]): readonly TextNode[] {\n\tif (nodes.length === 0) return [createTextNode('')];\n\n\tconst result: TextNode[] = [];\n\tfor (const node of nodes) {\n\t\tconst prev: TextNode | undefined = result[result.length - 1];\n\t\tif (prev && markSetsEqual(prev.marks, node.marks)) {\n\t\t\tresult[result.length - 1] = createTextNode(prev.text + node.text, prev.marks);\n\t\t} else if (node.text.length > 0 || result.length === 0) {\n\t\t\tresult.push(node);\n\t\t}\n\t}\n\n\treturn result.length === 0 ? [createTextNode('')] : result;\n}\n\n/**\n * Normalizes mixed inline content: merges adjacent TextNodes with same marks,\n * removes empty TextNodes adjacent to InlineNodes, preserves InlineNodes as-is.\n * Guarantees at least one TextNode exists if all text is empty.\n */\nexport function normalizeInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n): readonly (TextNode | InlineNode)[] {\n\tif (nodes.length === 0) return [createTextNode('')];\n\n\t// Fast path: no InlineNodes, delegate to normalizeTextNodes\n\tif (nodes.every((n): n is TextNode => isTextNode(n))) {\n\t\treturn normalizeTextNodes(nodes);\n\t}\n\n\tconst result: (TextNode | InlineNode)[] = [];\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tresult.push(node);\n\t\t\tcontinue;\n\t\t}\n\t\t// TextNode: try to merge with previous TextNode\n\t\tconst prev: TextNode | InlineNode | undefined = result[result.length - 1];\n\t\tif (prev && isTextNode(prev) && markSetsEqual(prev.marks, node.marks)) {\n\t\t\tresult[result.length - 1] = createTextNode(prev.text + node.text, prev.marks);\n\t\t} else if (node.text.length > 0 || result.length === 0) {\n\t\t\tresult.push(node);\n\t\t}\n\t}\n\n\t// Remove empty TextNodes that are adjacent to InlineNodes\n\tconst cleaned: (TextNode | InlineNode)[] = result.filter((node, i) => {\n\t\tif (isInlineNode(node)) return true;\n\t\tif (node.text.length > 0) return true;\n\t\t// Keep if it's the only node\n\t\tif (result.length === 1) return true;\n\t\t// Remove empty TextNode if adjacent to InlineNode\n\t\tconst prev: TextNode | InlineNode | undefined = result[i - 1];\n\t\tconst next: TextNode | InlineNode | undefined = result[i + 1];\n\t\tif ((prev && isInlineNode(prev)) || (next && isInlineNode(next))) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\t// Ensure at least one TextNode exists\n\tif (cleaned.length === 0) return [createTextNode('')];\n\tif (!cleaned.some((n) => isTextNode(n))) {\n\t\treturn [createTextNode(''), ...cleaned];\n\t}\n\n\treturn cleaned;\n}\n\n/** Yields each inline child with its offset range. InlineNodes have width 1. */\nexport function* walkInlineContent(children: readonly (TextNode | InlineNode)[]): Generator<{\n\treadonly child: TextNode | InlineNode;\n\treadonly from: number;\n\treadonly to: number;\n}> {\n\tlet pos = 0;\n\tfor (const child of children) {\n\t\tconst width: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tyield { child, from: pos, to: pos + width };\n\t\tpos += width;\n\t}\n}\n\n/** Returns the content at a specific offset: text char, inline node, or null. */\nexport function getContentAtOffset(\n\tblock: BlockNode,\n\toffset: number,\n):\n\t| { readonly kind: 'text'; readonly char: string; readonly marks: readonly Mark[] }\n\t| { readonly kind: 'inline'; readonly node: InlineNode }\n\t| null {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\n\tfor (const { child, from } of walkInlineContent(inlineChildren)) {\n\t\tif (isInlineNode(child)) {\n\t\t\tif (offset === from) return { kind: 'inline', node: child };\n\t\t\tcontinue;\n\t\t}\n\t\tconst localOffset: number = offset - from;\n\t\tif (localOffset >= 0 && localOffset < child.text.length) {\n\t\t\treturn {\n\t\t\t\tkind: 'text',\n\t\t\t\tchar: child.text[localOffset] ?? '',\n\t\t\t\tmarks: child.marks,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * Selection model for the Notectl editor.\n * A selection is defined by an anchor and head position within the document.\n */\n\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface Position {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\t/** Path from root block to leaf block (optional, for nested structures). */\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface Selection {\n\treadonly anchor: Position;\n\treadonly head: Position;\n}\n\nexport interface SelectionRange {\n\treadonly from: Position;\n\treadonly to: Position;\n}\n\n/** A selection that selects an entire node (e.g. for table selection). */\nexport interface NodeSelection {\n\treadonly type: 'node';\n\treadonly nodeId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** Creates a Position, optionally with a path. */\nexport function createPosition(\n\tblockId: BlockId,\n\toffset: number,\n\tpath?: readonly BlockId[],\n): Position {\n\treturn path ? { blockId, offset, path } : { blockId, offset };\n}\n\n/** Creates a selection with distinct anchor and head. */\nexport function createSelection(anchor: Position, head: Position): Selection {\n\treturn { anchor, head };\n}\n\n/** Creates a collapsed selection (cursor) at the given position. */\nexport function createCollapsedSelection(blockId: BlockId, offset: number): Selection {\n\tconst pos: Position = { blockId, offset };\n\treturn { anchor: pos, head: pos };\n}\n\n/** Returns true if the selection is collapsed (cursor with no range). */\nexport function isCollapsed(sel: Selection): boolean {\n\treturn sel.anchor.blockId === sel.head.blockId && sel.anchor.offset === sel.head.offset;\n}\n\n/**\n * Returns true if the selection direction is forward (anchor before head).\n * When anchor and head are in the same block, compares offsets.\n * Cross-block ordering uses document order (not determinable here — caller provides block order).\n */\nexport function isForward(sel: Selection, blockOrder?: readonly BlockId[]): boolean {\n\tif (sel.anchor.blockId === sel.head.blockId) {\n\t\treturn sel.anchor.offset <= sel.head.offset;\n\t}\n\tif (blockOrder) {\n\t\tconst anchorIdx = blockOrder.indexOf(sel.anchor.blockId);\n\t\tconst headIdx = blockOrder.indexOf(sel.head.blockId);\n\t\treturn anchorIdx <= headIdx;\n\t}\n\treturn true;\n}\n\n/**\n * Returns a normalized range where `from` is always before `to`.\n */\nexport function selectionRange(sel: Selection, blockOrder?: readonly BlockId[]): SelectionRange {\n\tif (isForward(sel, blockOrder)) {\n\t\treturn { from: sel.anchor, to: sel.head };\n\t}\n\treturn { from: sel.head, to: sel.anchor };\n}\n","/**\n * Schema definition for the Notectl editor.\n * Defines which node types and marks are allowed.\n */\n\nimport type { NodeSpec } from './NodeSpec.js';\nimport type { SchemaRegistry } from './SchemaRegistry.js';\n\nexport interface Schema {\n\treadonly nodeTypes: readonly string[];\n\treadonly markTypes: readonly string[];\n\t/** Looks up the full NodeSpec for a given type. Available when created via schemaFromRegistry. */\n\treadonly getNodeSpec?: (type: string) => NodeSpec | undefined;\n}\n\n/** Creates the default schema with paragraph nodes and bold/italic/underline marks. */\nexport function defaultSchema(): Schema {\n\treturn {\n\t\tnodeTypes: ['paragraph'],\n\t\tmarkTypes: ['bold', 'italic', 'underline'],\n\t\tgetNodeSpec: () => undefined,\n\t};\n}\n\n/** Derives a Schema from a SchemaRegistry's registered specs. */\nexport function schemaFromRegistry(registry: SchemaRegistry): Schema {\n\treturn {\n\t\tnodeTypes: registry.getNodeTypes(),\n\t\tmarkTypes: registry.getMarkTypes(),\n\t\tgetNodeSpec: (type: string) => registry.getNodeSpec(type),\n\t};\n}\n\n/** Checks whether the given mark type is allowed by the schema. */\nexport function isMarkAllowed(schema: Schema, markType: string): boolean {\n\treturn schema.markTypes.includes(markType);\n}\n\n/** Checks whether the given node type is allowed by the schema. */\nexport function isNodeTypeAllowed(schema: Schema, nodeType: string): boolean {\n\treturn schema.nodeTypes.includes(nodeType);\n}\n","/**\n * Branded (nominal) types for semantic string distinctions.\n * Prevents accidental interchange of structurally identical IDs.\n */\n\ndeclare const __brand: unique symbol;\ntype Brand<T, B extends string> = T & { readonly [__brand]: B };\n\n/** Unique identifier for a block node in the document tree. */\nexport type BlockId = Brand<string, 'BlockId'>;\n\n/** Semantic name for a node type (e.g. 'paragraph', 'heading'). */\nexport type NodeTypeName = Brand<string, 'NodeTypeName'>;\n\n/** Semantic name for a mark type (e.g. 'bold', 'link'). */\nexport type MarkTypeName = Brand<string, 'MarkTypeName'>;\n\n/** Unique identifier for a plugin. */\nexport type PluginId = Brand<string, 'PluginId'>;\n\n/** Registered command name. */\nexport type CommandName = Brand<string, 'CommandName'>;\n\n/** Semantic name for an inline node type (e.g. 'image', 'mention'). */\nexport type InlineTypeName = Brand<string, 'InlineTypeName'>;\n\n// --- Constructor Functions ---\n\nexport function blockId(id: string): BlockId {\n\treturn id as BlockId;\n}\n\nexport function nodeType(name: string): NodeTypeName {\n\treturn name as NodeTypeName;\n}\n\nexport function markType(name: string): MarkTypeName {\n\treturn name as MarkTypeName;\n}\n\nexport function pluginId(id: string): PluginId {\n\treturn id as PluginId;\n}\n\nexport function commandName(name: string): CommandName {\n\treturn name as CommandName;\n}\n\nexport function inlineType(name: string): InlineTypeName {\n\treturn name as InlineTypeName;\n}\n","/**\n * Module-augmentable attribute registries for type-safe node/mark attributes.\n *\n * Plugins extend these interfaces via `declare module`:\n * @example\n * declare module '../../model/AttrRegistry.js' {\n * interface NodeAttrRegistry {\n * heading: { level: HeadingLevel; textAlign?: TextAlignment };\n * }\n * }\n */\n\nimport type { TextAlignment } from '../plugins/text-alignment/TextAlignmentPlugin.js';\nimport type { BlockNode, InlineNode, Mark } from './Document.js';\nimport { isInlineNode } from './Document.js';\n\n/** Plugins augment this interface to register typed node attributes. */\nexport interface NodeAttrRegistry {\n\tparagraph: { textAlign?: TextAlignment };\n}\n\n/** Plugins augment this interface to register typed mark attributes. */\nexport interface MarkAttrRegistry {\n\tbold: Record<string, never>;\n\titalic: Record<string, never>;\n\tunderline: Record<string, never>;\n}\n\n/** Resolves typed attributes for known node types, falls back for unknown. */\nexport type NodeAttrsFor<T extends string> = T extends keyof NodeAttrRegistry\n\t? NodeAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Resolves typed attributes for known mark types, falls back for unknown. */\nexport type MarkAttrsFor<T extends string> = T extends keyof MarkAttrRegistry\n\t? MarkAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Narrows a BlockNode to a typed variant with known attributes. */\nexport function isNodeOfType<T extends keyof NodeAttrRegistry>(\n\tnode: BlockNode,\n\ttype: T,\n): node is BlockNode & { readonly type: T; readonly attrs: NodeAttrRegistry[T] } {\n\treturn (node.type as string) === type;\n}\n\n/** Narrows a Mark to a typed variant with known attributes. */\nexport function isMarkOfType<T extends keyof MarkAttrRegistry>(\n\tmark: Mark,\n\ttype: T,\n): mark is Mark & { readonly type: T; readonly attrs: MarkAttrRegistry[T] } {\n\treturn (mark.type as string) === type;\n}\n\n// --- InlineNode Attribute Registry ---\n\n/** Plugins augment this interface to register typed inline node attributes. */\n// biome-ignore lint/suspicious/noEmptyInterface: module augmentation requires interface\nexport interface InlineNodeAttrRegistry {}\n\n/** Resolves typed attributes for known inline node types, falls back for unknown. */\nexport type InlineNodeAttrsFor<T extends string> = T extends keyof InlineNodeAttrRegistry\n\t? InlineNodeAttrRegistry[T]\n\t: Record<string, string | number | boolean>;\n\n/** Narrows an InlineNode to a typed variant with known attributes. */\nexport function isInlineNodeOfType<T extends keyof InlineNodeAttrRegistry>(\n\tnode: InlineNode,\n\tinlineNodeType: T,\n): node is InlineNode & {\n\treadonly inlineType: T;\n\treadonly attrs: InlineNodeAttrRegistry[T];\n} {\n\treturn isInlineNode(node) && (node.inlineType as string) === inlineNodeType;\n}\n","/**\n * NodeSpec: defines how a block-node type behaves and renders to the DOM.\n */\n\nimport type { NodeAttrsFor } from './AttrRegistry.js';\nimport type { BlockNode } from './Document.js';\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface AttrSpec {\n\treadonly default?: string | number | boolean;\n}\n\n/** Describes which children a node type is allowed to contain. */\nexport interface ContentRule {\n\t/** Allowed child types or group names. */\n\treadonly allow: readonly string[];\n\treadonly min?: number;\n\treadonly max?: number;\n}\n\n/** Creates an HTMLElement with the required `data-block-id` attribute. */\nexport function createBlockElement(tag: string, blockId: BlockId): HTMLElement {\n\tconst el = document.createElement(tag);\n\tel.setAttribute('data-block-id', blockId);\n\treturn el;\n}\n\nexport interface NodeSpec<T extends string = string> {\n\treadonly type: T;\n\t/** Renders the block to a DOM element. Must set `data-block-id` on the root. */\n\ttoDOM(node: Omit<BlockNode, 'attrs'> & { readonly attrs: NodeAttrsFor<T> }): HTMLElement;\n\treadonly attrs?: Readonly<Record<string, AttrSpec>>;\n\t/** If true, the node contains no editable text (e.g. Image, HR). */\n\treadonly isVoid?: boolean;\n\t/** Content model: which children this node can contain. */\n\treadonly content?: ContentRule;\n\t/** Group membership: 'block' | 'inline' | custom. */\n\treadonly group?: string;\n\t/** If true, selection cannot cross this node's boundary (e.g. table_cell). */\n\treadonly isolating?: boolean;\n}\n","/**\n * SchemaRegistry: central registry for node specs, mark specs, node views,\n * keymaps, input rules, and toolbar items registered by plugins.\n */\n\nimport type { InputRule } from '../input/InputRule.js';\nimport type { Keymap } from '../input/Keymap.js';\nimport type { ToolbarItem } from '../plugins/toolbar/ToolbarItem.js';\nimport type { NodeViewFactory } from '../view/NodeView.js';\nimport type { InlineNodeSpec } from './InlineNodeSpec.js';\nimport type { MarkSpec } from './MarkSpec.js';\nimport type { NodeSpec } from './NodeSpec.js';\n\nexport class SchemaRegistry {\n\tprivate readonly _nodeSpecs = new Map<string, NodeSpec>();\n\tprivate readonly _markSpecs = new Map<string, MarkSpec>();\n\tprivate readonly _inlineNodeSpecs = new Map<string, InlineNodeSpec>();\n\tprivate readonly _nodeViews = new Map<string, NodeViewFactory>();\n\tprivate readonly _keymaps: Keymap[] = [];\n\tprivate readonly _inputRules: InputRule[] = [];\n\tprivate readonly _toolbarItems = new Map<string, ToolbarItem>();\n\tprivate readonly _toolbarItemPluginMap = new Map<string, string[]>();\n\n\t// --- NodeSpec ---\n\n\tregisterNodeSpec<T extends string>(spec: NodeSpec<T>): void {\n\t\tif (this._nodeSpecs.has(spec.type)) {\n\t\t\tthrow new Error(`NodeSpec for type \"${spec.type}\" is already registered.`);\n\t\t}\n\t\tthis._nodeSpecs.set(spec.type, spec);\n\t}\n\n\tgetNodeSpec(type: string): NodeSpec | undefined {\n\t\treturn this._nodeSpecs.get(type);\n\t}\n\n\tremoveNodeSpec(type: string): void {\n\t\tthis._nodeSpecs.delete(type);\n\t}\n\n\tgetNodeTypes(): string[] {\n\t\treturn [...this._nodeSpecs.keys()];\n\t}\n\n\t// --- MarkSpec ---\n\n\tregisterMarkSpec<T extends string>(spec: MarkSpec<T>): void {\n\t\tif (this._markSpecs.has(spec.type)) {\n\t\t\tthrow new Error(`MarkSpec for type \"${spec.type}\" is already registered.`);\n\t\t}\n\t\tthis._markSpecs.set(spec.type, spec);\n\t}\n\n\tgetMarkSpec(type: string): MarkSpec | undefined {\n\t\treturn this._markSpecs.get(type);\n\t}\n\n\tremoveMarkSpec(type: string): void {\n\t\tthis._markSpecs.delete(type);\n\t}\n\n\tgetMarkTypes(): string[] {\n\t\treturn [...this._markSpecs.keys()];\n\t}\n\n\t// --- InlineNodeSpec ---\n\n\tregisterInlineNodeSpec<T extends string>(spec: InlineNodeSpec<T>): void {\n\t\tif (this._inlineNodeSpecs.has(spec.type)) {\n\t\t\tthrow new Error(`InlineNodeSpec for type \"${spec.type}\" is already registered.`);\n\t\t}\n\t\tthis._inlineNodeSpecs.set(spec.type, spec);\n\t}\n\n\tgetInlineNodeSpec(type: string): InlineNodeSpec | undefined {\n\t\treturn this._inlineNodeSpecs.get(type);\n\t}\n\n\tremoveInlineNodeSpec(type: string): void {\n\t\tthis._inlineNodeSpecs.delete(type);\n\t}\n\n\tgetInlineNodeTypes(): string[] {\n\t\treturn [...this._inlineNodeSpecs.keys()];\n\t}\n\n\t// --- NodeView ---\n\n\tregisterNodeView(type: string, factory: NodeViewFactory): void {\n\t\tif (this._nodeViews.has(type)) {\n\t\t\tthrow new Error(`NodeView for type \"${type}\" is already registered.`);\n\t\t}\n\t\tthis._nodeViews.set(type, factory);\n\t}\n\n\tgetNodeViewFactory(type: string): NodeViewFactory | undefined {\n\t\treturn this._nodeViews.get(type);\n\t}\n\n\tremoveNodeView(type: string): void {\n\t\tthis._nodeViews.delete(type);\n\t}\n\n\t// --- Keymap ---\n\n\tregisterKeymap(keymap: Keymap): void {\n\t\tfor (const key of Object.keys(keymap)) {\n\t\t\tfor (const existing of this._keymaps) {\n\t\t\t\tif (key in existing) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[notectl] Keymap shortcut \"${key}\" is already registered and will be overridden.`,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._keymaps.push(keymap);\n\t}\n\n\tgetKeymaps(): readonly Keymap[] {\n\t\treturn this._keymaps;\n\t}\n\n\tremoveKeymap(keymap: Keymap): void {\n\t\tconst idx = this._keymaps.indexOf(keymap);\n\t\tif (idx !== -1) this._keymaps.splice(idx, 1);\n\t}\n\n\t// --- InputRule ---\n\n\tregisterInputRule(rule: InputRule): void {\n\t\tthis._inputRules.push(rule);\n\t}\n\n\tgetInputRules(): readonly InputRule[] {\n\t\treturn this._inputRules;\n\t}\n\n\tremoveInputRule(rule: InputRule): void {\n\t\tconst idx = this._inputRules.indexOf(rule);\n\t\tif (idx !== -1) this._inputRules.splice(idx, 1);\n\t}\n\n\t// --- ToolbarItem ---\n\n\tregisterToolbarItem(item: ToolbarItem, pluginId?: string): void {\n\t\tif (this._toolbarItems.has(item.id)) {\n\t\t\tthrow new Error(`ToolbarItem with id \"${item.id}\" is already registered.`);\n\t\t}\n\t\tthis._toolbarItems.set(item.id, item);\n\t\tif (pluginId) {\n\t\t\tconst ids = this._toolbarItemPluginMap.get(pluginId) ?? [];\n\t\t\tids.push(item.id);\n\t\t\tthis._toolbarItemPluginMap.set(pluginId, ids);\n\t\t}\n\t}\n\n\tgetToolbarItemsByPlugin(pluginId: string): ToolbarItem[] {\n\t\tconst ids = this._toolbarItemPluginMap.get(pluginId) ?? [];\n\t\tconst items: ToolbarItem[] = [];\n\t\tfor (const id of ids) {\n\t\t\tconst item = this._toolbarItems.get(id);\n\t\t\tif (item) items.push(item);\n\t\t}\n\t\treturn items;\n\t}\n\n\tgetToolbarItem(id: string): ToolbarItem | undefined {\n\t\treturn this._toolbarItems.get(id);\n\t}\n\n\tgetToolbarItems(): ToolbarItem[] {\n\t\treturn [...this._toolbarItems.values()];\n\t}\n\n\tremoveToolbarItem(id: string): void {\n\t\tthis._toolbarItems.delete(id);\n\t\tfor (const [pluginId, ids] of this._toolbarItemPluginMap) {\n\t\t\tconst idx = ids.indexOf(id);\n\t\t\tif (idx !== -1) {\n\t\t\t\tids.splice(idx, 1);\n\t\t\t\tif (ids.length === 0) this._toolbarItemPluginMap.delete(pluginId);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Bulk ---\n\n\tclear(): void {\n\t\tthis._nodeSpecs.clear();\n\t\tthis._markSpecs.clear();\n\t\tthis._inlineNodeSpecs.clear();\n\t\tthis._nodeViews.clear();\n\t\tthis._keymaps.length = 0;\n\t\tthis._inputRules.length = 0;\n\t\tthis._toolbarItems.clear();\n\t\tthis._toolbarItemPluginMap.clear();\n\t}\n}\n","/**\n * Utilities for resolving nodes by path within the document tree.\n * Supports both flat and recursive (nested) document structures.\n */\n\nimport type { BlockNode, Document } from './Document.js';\nimport { isBlockNode } from './Document.js';\n\n/**\n * Resolves a node in the document tree by its path (array of block IDs).\n * The path traces the lineage from the root block down to the target.\n */\nexport function resolveNodeByPath(doc: Document, path: readonly string[]): BlockNode | undefined {\n\tif (path.length === 0) return undefined;\n\n\tlet current: BlockNode | undefined = doc.children.find((b) => b.id === path[0]);\n\tif (!current) return undefined;\n\n\tfor (let i = 1; i < path.length; i++) {\n\t\tconst childId = path[i];\n\t\tif (!childId) return undefined;\n\t\tconst next: BlockNode | undefined = current?.children.find(\n\t\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t\t);\n\t\tif (!next) return undefined;\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\n/**\n * Resolves the parent of a node at the given path.\n * Returns the parent container (Document or BlockNode) and the child's index within it.\n */\nexport function resolveParentByPath(\n\tdoc: Document,\n\tpath: readonly string[],\n): { parent: Document | BlockNode; index: number } | undefined {\n\tif (path.length === 0) return undefined;\n\n\tif (path.length === 1) {\n\t\tconst index = doc.children.findIndex((b) => b.id === path[0]);\n\t\tif (index === -1) return undefined;\n\t\treturn { parent: doc, index };\n\t}\n\n\tconst parentPath = path.slice(0, -1);\n\tconst parent = resolveNodeByPath(doc, parentPath);\n\tif (!parent) return undefined;\n\n\tconst childId = path[path.length - 1];\n\tif (!childId) return undefined;\n\tconst index = parent.children.findIndex(\n\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t);\n\tif (index === -1) return undefined;\n\n\treturn { parent, index };\n}\n\n/**\n * Finds the path (array of block IDs) to a node by its ID.\n * Performs recursive DFS through the document tree.\n */\nexport function findNodePath(doc: Document, nodeId: string): string[] | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(block, nodeId);\n\t\tif (subPath) return [block.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\nfunction findNodePathInBlock(block: BlockNode, nodeId: string): string[] | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(child, nodeId);\n\t\tif (subPath) return [child.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\n/**\n * Walks all block nodes in the document tree in depth-first order.\n * Visits every BlockNode, including nested ones, with their full path.\n */\nexport function walkNodes(\n\tdoc: Document,\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tfor (const block of doc.children) {\n\t\twalkNodeRecursive(block, [block.id], callback);\n\t}\n}\n\nfunction walkNodeRecursive(\n\tnode: BlockNode,\n\tpath: string[],\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tcallback(node, path);\n\tfor (const child of node.children) {\n\t\tif (isBlockNode(child)) {\n\t\t\twalkNodeRecursive(child, [...path, child.id], callback);\n\t\t}\n\t}\n}\n\n/**\n * Finds a block node by ID anywhere in the document tree (recursive DFS).\n */\nexport function findNode(doc: Document, nodeId: string): BlockNode | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return block;\n\t\tconst found = findNodeInBlock(block, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\nfunction findNodeInBlock(block: BlockNode, nodeId: string): BlockNode | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return child;\n\t\tconst found = findNodeInBlock(child, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\n/**\n * Finds a block node and returns it together with its path.\n */\nexport function findNodeWithPath(\n\tdoc: Document,\n\tnodeId: string,\n): { node: BlockNode; path: string[] } | undefined {\n\tconst path = findNodePath(doc, nodeId);\n\tif (!path) return undefined;\n\tconst node = resolveNodeByPath(doc, path);\n\tif (!node) return undefined;\n\treturn { node, path };\n}\n","/**\n * Content model validation for nested document structures.\n * Validates whether a parent node type can contain given child types.\n */\n\nimport type { SchemaRegistry } from './SchemaRegistry.js';\n\n/**\n * Checks if a parent node type can contain a child node type,\n * using the content rules and group system from NodeSpec.\n */\nexport function canContain(\n\tregistry: SchemaRegistry,\n\tparentType: string,\n\tchildType: string,\n): boolean {\n\tconst parentSpec = registry.getNodeSpec(parentType);\n\tif (!parentSpec?.content) return true; // No content rule = anything allowed\n\n\tconst childSpec = registry.getNodeSpec(childType);\n\tconst childGroup = childSpec?.group;\n\n\tfor (const allowed of parentSpec.content.allow) {\n\t\tif (allowed === childType) return true;\n\t\tif (allowed === 'text') continue; // 'text' refers to TextNodes, not BlockNodes\n\t\tif (childGroup && allowed === childGroup) return true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Validates whether the given children types are valid for a parent node type.\n * Checks allow list, min/max constraints.\n */\nexport function validateContent(\n\tregistry: SchemaRegistry,\n\tparentType: string,\n\tchildTypes: readonly string[],\n): boolean {\n\tconst parentSpec = registry.getNodeSpec(parentType);\n\tif (!parentSpec?.content) return true;\n\n\tconst { min = 0, max = Number.POSITIVE_INFINITY } = parentSpec.content;\n\n\t// Check count constraints (only for block children, not text)\n\tconst blockChildTypes = childTypes.filter((t) => t !== 'text');\n\tif (blockChildTypes.length < min || blockChildTypes.length > max) return false;\n\n\t// Check each child is allowed\n\tfor (const childType of blockChildTypes) {\n\t\tif (!canContain(registry, parentType, childType)) return false;\n\t}\n\n\treturn true;\n}\n","/**\n * Registers built-in node specs on a SchemaRegistry.\n * Called during editor initialization before plugins.\n *\n * Note: Mark specs (bold, italic, underline) are registered by the\n * TextFormattingPlugin, not here. Only structural node types belong here.\n */\n\nimport { createBlockElement } from './NodeSpec.js';\nimport type { SchemaRegistry } from './SchemaRegistry.js';\n\n/** Registers the built-in paragraph NodeSpec. */\nexport function registerBuiltinSpecs(registry: SchemaRegistry): void {\n\tregistry.registerNodeSpec({\n\t\ttype: 'paragraph',\n\t\tgroup: 'block',\n\t\tcontent: { allow: ['text'] },\n\t\ttoDOM(node) {\n\t\t\treturn createBlockElement('p', node.id);\n\t\t},\n\t});\n}\n","/**\n * Pure step-application functions operating on Document.\n * Extracted from EditorState for reuse in TransactionBuilder.\n */\n\nimport {\n\ttype BlockNode,\n\ttype ChildNode,\n\ttype Document,\n\ttype InlineNode,\n\ttype Mark,\n\ttype TextNode,\n\ttype TextSegment,\n\taddMarkToSet,\n\tcreateBlockNode,\n\tcreateTextNode,\n\tgetBlockLength,\n\tgetInlineChildren,\n\tisBlockNode,\n\tisInlineNode,\n\tisTextNode,\n\tnormalizeInlineContent,\n\tremoveMarkFromSet,\n} from '../model/Document.js';\nimport type {\n\tAddMarkStep,\n\tDeleteTextStep,\n\tInsertInlineNodeStep,\n\tInsertNodeStep,\n\tInsertTextStep,\n\tMergeBlocksStep,\n\tRemoveInlineNodeStep,\n\tRemoveMarkStep,\n\tRemoveNodeStep,\n\tSetBlockTypeStep,\n\tSetInlineNodeAttrStep,\n\tSetNodeAttrStep,\n\tSplitBlockStep,\n\tStep,\n} from './Transaction.js';\n\n/** Applies a single step to a document and returns the new document. */\nexport function applyStep(doc: Document, step: Step): Document {\n\tswitch (step.type) {\n\t\tcase 'insertText':\n\t\t\treturn applyInsertText(doc, step);\n\t\tcase 'deleteText':\n\t\t\treturn applyDeleteText(doc, step);\n\t\tcase 'splitBlock':\n\t\t\treturn applySplitBlock(doc, step);\n\t\tcase 'mergeBlocks':\n\t\t\treturn applyMergeBlocks(doc, step);\n\t\tcase 'addMark':\n\t\t\treturn applyAddMark(doc, step);\n\t\tcase 'removeMark':\n\t\t\treturn applyRemoveMark(doc, step);\n\t\tcase 'setStoredMarks':\n\t\t\treturn doc; // Stored marks are handled at the state level, not document\n\t\tcase 'setBlockType':\n\t\t\treturn applySetBlockType(doc, step);\n\t\tcase 'insertNode':\n\t\t\treturn applyInsertNode(doc, step);\n\t\tcase 'removeNode':\n\t\t\treturn applyRemoveNode(doc, step);\n\t\tcase 'setNodeAttr':\n\t\t\treturn applySetNodeAttr(doc, step);\n\t\tcase 'insertInlineNode':\n\t\t\treturn applyInsertInlineNode(doc, step);\n\t\tcase 'removeInlineNode':\n\t\t\treturn applyRemoveInlineNode(doc, step);\n\t\tcase 'setInlineNodeAttr':\n\t\t\treturn applySetInlineNodeAttr(doc, step);\n\t}\n}\n\nfunction applyInsertText(doc: Document, step: InsertTextStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = step.segments\n\t\t\t? insertSegmentsIntoInlineContent(inlineChildren, step.offset, step.segments)\n\t\t\t: insertTextIntoInlineContent(inlineChildren, step.offset, step.text, step.marks);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\nfunction applyDeleteText(doc: Document, step: DeleteTextStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = deleteFromInlineContent(\n\t\t\tinlineChildren,\n\t\t\tstep.from,\n\t\t\tstep.to,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\nfunction applySplitBlock(doc: Document, step: SplitBlockStep): Document {\n\t// Try at top level first\n\tconst blockIndex: number = doc.children.findIndex((b) => b.id === step.blockId);\n\n\tif (blockIndex !== -1) {\n\t\tconst block: BlockNode | undefined = doc.children[blockIndex];\n\t\tif (!block) return doc;\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst len: number = getBlockLength(block);\n\t\tconst nodesBeforeSplit: (TextNode | InlineNode)[] = sliceInlineContent(\n\t\t\tinlineChildren,\n\t\t\t0,\n\t\t\tstep.offset,\n\t\t);\n\t\tconst nodesAfterSplit: (TextNode | InlineNode)[] = sliceInlineContent(\n\t\t\tinlineChildren,\n\t\t\tstep.offset,\n\t\t\tlen,\n\t\t);\n\n\t\tconst updatedBlock: BlockNode = {\n\t\t\t...block,\n\t\t\tchildren: normalizeInlineContent(nodesBeforeSplit),\n\t\t};\n\t\tconst newBlock: BlockNode = createBlockNode(\n\t\t\tblock.type,\n\t\t\tnormalizeInlineContent(nodesAfterSplit),\n\t\t\tstep.newBlockId,\n\t\t\tblock.attrs,\n\t\t);\n\n\t\tconst newChildren: BlockNode[] = [...doc.children];\n\t\tnewChildren.splice(blockIndex, 1, updatedBlock, newBlock);\n\t\treturn { children: newChildren };\n\t}\n\n\t// Recurse into block children\n\treturn {\n\t\tchildren: doc.children.map((child) => {\n\t\t\tconst mapped: BlockNode | null = splitBlockRecursive(child, step);\n\t\t\treturn mapped ?? child;\n\t\t}),\n\t};\n}\n\nfunction splitBlockRecursive(node: BlockNode, step: SplitBlockStep): BlockNode | null {\n\tconst idx: number = node.children.findIndex((c) => isBlockNode(c) && c.id === step.blockId);\n\tif (idx !== -1) {\n\t\tconst block: BlockNode = node.children[idx] as BlockNode;\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst len: number = getBlockLength(block);\n\t\tconst nodesBeforeSplit: (TextNode | InlineNode)[] = sliceInlineContent(\n\t\t\tinlineChildren,\n\t\t\t0,\n\t\t\tstep.offset,\n\t\t);\n\t\tconst nodesAfterSplit: (TextNode | InlineNode)[] = sliceInlineContent(\n\t\t\tinlineChildren,\n\t\t\tstep.offset,\n\t\t\tlen,\n\t\t);\n\n\t\tconst updatedBlock: BlockNode = {\n\t\t\t...block,\n\t\t\tchildren: normalizeInlineContent(nodesBeforeSplit),\n\t\t};\n\t\tconst newBlock: BlockNode = createBlockNode(\n\t\t\tblock.type,\n\t\t\tnormalizeInlineContent(nodesAfterSplit),\n\t\t\tstep.newBlockId,\n\t\t\tblock.attrs,\n\t\t);\n\n\t\tconst newChildren: ChildNode[] = [...node.children] as ChildNode[];\n\t\tnewChildren.splice(idx, 1, updatedBlock, newBlock);\n\t\treturn { ...node, children: newChildren };\n\t}\n\n\t// Recurse deeper\n\tlet changed = false;\n\tconst newChildren: ChildNode[] = node.children.map((child) => {\n\t\tif (!isBlockNode(child)) return child;\n\t\tconst mapped: BlockNode | null = splitBlockRecursive(child, step);\n\t\tif (mapped) {\n\t\t\tchanged = true;\n\t\t\treturn mapped;\n\t\t}\n\t\treturn child;\n\t});\n\n\treturn changed ? { ...node, children: newChildren } : null;\n}\n\nfunction applyMergeBlocks(doc: Document, step: MergeBlocksStep): Document {\n\t// Try at top level first\n\tconst targetIndex: number = doc.children.findIndex((b) => b.id === step.targetBlockId);\n\tconst sourceIndex: number = doc.children.findIndex((b) => b.id === step.sourceBlockId);\n\n\tif (targetIndex !== -1 && sourceIndex !== -1) {\n\t\tconst target: BlockNode | undefined = doc.children[targetIndex];\n\t\tconst source: BlockNode | undefined = doc.children[sourceIndex];\n\t\tif (!target || !source) return doc;\n\t\tconst targetInline: readonly (TextNode | InlineNode)[] = getInlineChildren(target);\n\t\tconst sourceInline: readonly (TextNode | InlineNode)[] = getInlineChildren(source);\n\t\tconst mergedChildren: readonly (TextNode | InlineNode)[] = normalizeInlineContent([\n\t\t\t...targetInline,\n\t\t\t...sourceInline,\n\t\t]);\n\t\tconst mergedBlock: BlockNode = { ...target, children: mergedChildren };\n\n\t\tconst newChildren: readonly BlockNode[] = doc.children.filter(\n\t\t\t(b) => b.id !== step.sourceBlockId,\n\t\t);\n\t\treturn {\n\t\t\tchildren: newChildren.map((b) => (b.id === step.targetBlockId ? mergedBlock : b)),\n\t\t};\n\t}\n\n\t// Recurse into block children\n\treturn {\n\t\tchildren: doc.children.map((child) => {\n\t\t\tconst mapped: BlockNode | null = mergeBlocksRecursive(child, step);\n\t\t\treturn mapped ?? child;\n\t\t}),\n\t};\n}\n\nfunction mergeBlocksRecursive(node: BlockNode, step: MergeBlocksStep): BlockNode | null {\n\tconst targetIdx: number = node.children.findIndex(\n\t\t(c) => isBlockNode(c) && c.id === step.targetBlockId,\n\t);\n\tconst sourceIdx: number = node.children.findIndex(\n\t\t(c) => isBlockNode(c) && c.id === step.sourceBlockId,\n\t);\n\n\tif (targetIdx !== -1 && sourceIdx !== -1) {\n\t\tconst target: BlockNode = node.children[targetIdx] as BlockNode;\n\t\tconst source: BlockNode = node.children[sourceIdx] as BlockNode;\n\t\tconst targetInline: readonly (TextNode | InlineNode)[] = getInlineChildren(target);\n\t\tconst sourceInline: readonly (TextNode | InlineNode)[] = getInlineChildren(source);\n\t\tconst mergedChildren: readonly (TextNode | InlineNode)[] = normalizeInlineContent([\n\t\t\t...targetInline,\n\t\t\t...sourceInline,\n\t\t]);\n\t\tconst mergedBlock: BlockNode = { ...target, children: mergedChildren };\n\n\t\tconst filtered: ChildNode[] = node.children.filter(\n\t\t\t(c) => !isBlockNode(c) || c.id !== step.sourceBlockId,\n\t\t);\n\t\tconst result: ChildNode[] = filtered.map((c) =>\n\t\t\tisBlockNode(c) && c.id === step.targetBlockId ? mergedBlock : c,\n\t\t);\n\t\treturn { ...node, children: result };\n\t}\n\n\t// Recurse deeper\n\tlet changed = false;\n\tconst newChildren: ChildNode[] = node.children.map((child) => {\n\t\tif (!isBlockNode(child)) return child;\n\t\tconst mapped: BlockNode | null = mergeBlocksRecursive(child, step);\n\t\tif (mapped) {\n\t\t\tchanged = true;\n\t\t\treturn mapped;\n\t\t}\n\t\treturn child;\n\t});\n\n\treturn changed ? { ...node, children: newChildren } : null;\n}\n\nfunction applyAddMark(doc: Document, step: AddMarkStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = applyMarkToInlineContent(\n\t\t\tinlineChildren,\n\t\t\tstep.from,\n\t\t\tstep.to,\n\t\t\tstep.mark,\n\t\t\ttrue,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\nfunction applyRemoveMark(doc: Document, step: RemoveMarkStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = applyMarkToInlineContent(\n\t\t\tinlineChildren,\n\t\t\tstep.from,\n\t\t\tstep.to,\n\t\t\tstep.mark,\n\t\t\tfalse,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\n// --- InlineNode Step Application ---\n\nfunction applyInsertInlineNode(doc: Document, step: InsertInlineNodeStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = insertInlineNodeAtOffset(\n\t\t\tinlineChildren,\n\t\t\tstep.offset,\n\t\t\tstep.node,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\nfunction applyRemoveInlineNode(doc: Document, step: RemoveInlineNodeStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = removeInlineNodeAtOffset(\n\t\t\tinlineChildren,\n\t\t\tstep.offset,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, normalizeInlineContent(newChildren)),\n\t\t};\n\t});\n}\n\nfunction applySetInlineNodeAttr(doc: Document, step: SetInlineNodeAttrStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => {\n\t\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\t\tconst newChildren: (TextNode | InlineNode)[] = setInlineNodeAttrsAtOffset(\n\t\t\tinlineChildren,\n\t\t\tstep.offset,\n\t\t\tstep.attrs,\n\t\t);\n\t\treturn {\n\t\t\t...block,\n\t\t\tchildren: replaceInlineChildren(block.children, newChildren),\n\t\t};\n\t});\n}\n\n// --- Helpers ---\n\nfunction mapBlock(doc: Document, blockId: string, fn: (block: BlockNode) => BlockNode): Document {\n\treturn {\n\t\tchildren: mapBlockInChildren(doc.children, blockId, fn) as BlockNode[],\n\t};\n}\n\nfunction mapBlockInChildren(\n\tchildren: readonly ChildNode[],\n\tblockId: string,\n\tfn: (block: BlockNode) => BlockNode,\n): ChildNode[] {\n\treturn children.map((child) => {\n\t\tif (!isBlockNode(child)) return child;\n\t\tif (child.id === blockId) return fn(child);\n\t\t// Recurse into block children\n\t\tconst mappedChildren: ChildNode[] = mapBlockInChildren(child.children, blockId, fn);\n\t\tif (mappedChildren === child.children) return child;\n\t\treturn { ...child, children: mappedChildren };\n\t});\n}\n\n/**\n * Replaces the inline content children of a ChildNode array,\n * preserving any BlockNode children in their original positions.\n */\nfunction replaceInlineChildren(\n\toriginal: readonly ChildNode[],\n\tnewInlineChildren: readonly (TextNode | InlineNode)[],\n): readonly ChildNode[] {\n\t// Fast path: if no block children exist, just return new inline nodes\n\tif (original.every((c) => isTextNode(c) || isInlineNode(c))) {\n\t\treturn newInlineChildren;\n\t}\n\t// Mixed: put inline nodes first, then block nodes (preserves structure)\n\tconst blockChildren: ChildNode[] = original.filter((c) => !isTextNode(c) && !isInlineNode(c));\n\treturn [...newInlineChildren, ...blockChildren];\n}\n\n/**\n * Inserts text into mixed inline content at the given offset.\n * Handles both TextNode and InlineNode children.\n */\nfunction insertTextIntoInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n\toffset: number,\n\ttext: string,\n\tmarks: readonly Mark[],\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\tlet inserted = false;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tif (!inserted && offset === pos) {\n\t\t\t\tresult.push(createTextNode(text, marks));\n\t\t\t\tinserted = true;\n\t\t\t}\n\t\t\tresult.push(node);\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (!inserted && offset >= pos && offset <= nodeEnd) {\n\t\t\tconst localOffset: number = offset - pos;\n\t\t\tconst before: string = node.text.slice(0, localOffset);\n\t\t\tconst after: string = node.text.slice(localOffset);\n\n\t\t\tif (before) result.push(createTextNode(before, node.marks));\n\t\t\tresult.push(createTextNode(text, marks));\n\t\t\tif (after) result.push(createTextNode(after, node.marks));\n\t\t\tinserted = true;\n\t\t} else {\n\t\t\tresult.push(node);\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\tif (!inserted) {\n\t\tresult.push(createTextNode(text, marks));\n\t}\n\n\treturn result;\n}\n\n/**\n * Inserts segments into mixed inline content at the given offset.\n */\nfunction insertSegmentsIntoInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n\toffset: number,\n\tsegments: readonly TextSegment[],\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\tlet inserted = false;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tif (!inserted && offset === pos) {\n\t\t\t\tfor (const seg of segments) {\n\t\t\t\t\tresult.push(createTextNode(seg.text, seg.marks));\n\t\t\t\t}\n\t\t\t\tinserted = true;\n\t\t\t}\n\t\t\tresult.push(node);\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (!inserted && offset >= pos && offset <= nodeEnd) {\n\t\t\tconst localOffset: number = offset - pos;\n\t\t\tconst before: string = node.text.slice(0, localOffset);\n\t\t\tconst after: string = node.text.slice(localOffset);\n\n\t\t\tif (before) result.push(createTextNode(before, node.marks));\n\t\t\tfor (const seg of segments) {\n\t\t\t\tresult.push(createTextNode(seg.text, seg.marks));\n\t\t\t}\n\t\t\tif (after) result.push(createTextNode(after, node.marks));\n\t\t\tinserted = true;\n\t\t} else {\n\t\t\tresult.push(node);\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\tif (!inserted) {\n\t\tfor (const seg of segments) {\n\t\t\tresult.push(createTextNode(seg.text, seg.marks));\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Deletes content from mixed inline content in the given range.\n * Removes InlineNodes that fall within the range.\n */\nfunction deleteFromInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n\tfrom: number,\n\tto: number,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tconst nodeEnd: number = pos + 1;\n\t\t\t// Keep if outside the delete range\n\t\t\tif (nodeEnd <= from || pos >= to) {\n\t\t\t\tresult.push(node);\n\t\t\t}\n\t\t\tpos = nodeEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (nodeEnd <= from || pos >= to) {\n\t\t\tresult.push(node);\n\t\t} else {\n\t\t\tconst deleteFrom: number = Math.max(0, from - pos);\n\t\t\tconst deleteTo: number = Math.min(node.text.length, to - pos);\n\t\t\tconst remaining: string = node.text.slice(0, deleteFrom) + node.text.slice(deleteTo);\n\t\t\tif (remaining.length > 0) {\n\t\t\t\tresult.push(createTextNode(remaining, node.marks));\n\t\t\t}\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\treturn result;\n}\n\n/**\n * Slices mixed inline content to the given range.\n * InlineNodes are preserved as atoms (included if within range).\n */\nfunction sliceInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n\tfrom: number,\n\tto: number,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tconst nodeEnd: number = pos + 1;\n\t\t\tif (nodeEnd > from && pos < to) {\n\t\t\t\tresult.push(node);\n\t\t\t}\n\t\t\tpos = nodeEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (nodeEnd <= from || pos >= to) {\n\t\t\t// Outside the slice range\n\t\t} else {\n\t\t\tconst sliceFrom: number = Math.max(0, from - pos);\n\t\t\tconst sliceTo: number = Math.min(node.text.length, to - pos);\n\t\t\tconst text: string = node.text.slice(sliceFrom, sliceTo);\n\t\t\tif (text.length > 0) {\n\t\t\t\tresult.push(createTextNode(text, node.marks));\n\t\t\t}\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\tif (result.length === 0) {\n\t\tresult.push(createTextNode(''));\n\t}\n\n\treturn result;\n}\n\n/**\n * Applies or removes a mark from mixed inline content in the given range.\n * InlineNodes are passed through unchanged (marks only apply to text).\n */\nfunction applyMarkToInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n\tfrom: number,\n\tto: number,\n\tmark: Mark,\n\tadd: boolean,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tresult.push(node);\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (nodeEnd <= from || pos >= to) {\n\t\t\tresult.push(node);\n\t\t} else if (pos >= from && nodeEnd <= to) {\n\t\t\tconst newMarks: readonly Mark[] = add\n\t\t\t\t? addMarkToSet(node.marks, mark)\n\t\t\t\t: removeMarkFromSet(node.marks, mark.type);\n\t\t\tresult.push(createTextNode(node.text, newMarks));\n\t\t} else {\n\t\t\tconst overlapStart: number = Math.max(0, from - pos);\n\t\t\tconst overlapEnd: number = Math.min(node.text.length, to - pos);\n\n\t\t\tconst beforeText: string = node.text.slice(0, overlapStart);\n\t\t\tconst insideText: string = node.text.slice(overlapStart, overlapEnd);\n\t\t\tconst afterText: string = node.text.slice(overlapEnd);\n\n\t\t\tif (beforeText) result.push(createTextNode(beforeText, node.marks));\n\t\t\tif (insideText) {\n\t\t\t\tconst newMarks: readonly Mark[] = add\n\t\t\t\t\t? addMarkToSet(node.marks, mark)\n\t\t\t\t\t: removeMarkFromSet(node.marks, mark.type);\n\t\t\t\tresult.push(createTextNode(insideText, newMarks));\n\t\t\t}\n\t\t\tif (afterText) result.push(createTextNode(afterText, node.marks));\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\treturn result;\n}\n\n/** Inserts an InlineNode at the given offset in mixed inline content. */\nfunction insertInlineNodeAtOffset(\n\tnodes: readonly (TextNode | InlineNode)[],\n\toffset: number,\n\tinlineNode: InlineNode,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\tlet inserted = false;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tif (!inserted && offset === pos) {\n\t\t\t\tresult.push(inlineNode);\n\t\t\t\tinserted = true;\n\t\t\t}\n\t\t\tresult.push(node);\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst nodeEnd: number = pos + node.text.length;\n\n\t\tif (!inserted && offset >= pos && offset <= nodeEnd) {\n\t\t\tconst localOffset: number = offset - pos;\n\t\t\tconst before: string = node.text.slice(0, localOffset);\n\t\t\tconst after: string = node.text.slice(localOffset);\n\n\t\t\tif (before) result.push(createTextNode(before, node.marks));\n\t\t\tresult.push(inlineNode);\n\t\t\tif (after) result.push(createTextNode(after, node.marks));\n\t\t\tinserted = true;\n\t\t} else {\n\t\t\tresult.push(node);\n\t\t}\n\n\t\tpos = nodeEnd;\n\t}\n\n\tif (!inserted) {\n\t\tresult.push(inlineNode);\n\t}\n\n\treturn result;\n}\n\n/** Removes the InlineNode at the given offset from mixed inline content. */\nfunction removeInlineNodeAtOffset(\n\tnodes: readonly (TextNode | InlineNode)[],\n\toffset: number,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tif (pos !== offset) {\n\t\t\t\tresult.push(node);\n\t\t\t}\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tresult.push(node);\n\t\tpos += node.text.length;\n\t}\n\n\treturn result;\n}\n\n/** Replaces the attrs of an InlineNode at the given offset. */\nfunction setInlineNodeAttrsAtOffset(\n\tnodes: readonly (TextNode | InlineNode)[],\n\toffset: number,\n\tattrs: Readonly<Record<string, string | number | boolean>>,\n): (TextNode | InlineNode)[] {\n\tconst result: (TextNode | InlineNode)[] = [];\n\tlet pos = 0;\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tif (pos === offset) {\n\t\t\t\tresult.push({ ...node, attrs });\n\t\t\t} else {\n\t\t\t\tresult.push(node);\n\t\t\t}\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tresult.push(node);\n\t\tpos += node.text.length;\n\t}\n\n\treturn result;\n}\n\nfunction applySetBlockType(doc: Document, step: SetBlockTypeStep): Document {\n\treturn mapBlock(doc, step.blockId, (block) => ({\n\t\t...block,\n\t\ttype: step.nodeType,\n\t\t...(step.attrs ? { attrs: step.attrs } : { attrs: undefined }),\n\t}));\n}\n\n// --- Structural Step Application ---\n\nfunction applyInsertNode(doc: Document, step: InsertNodeStep): Document {\n\tif (step.parentPath.length === 0) {\n\t\t// Insert at document root\n\t\tconst newChildren: BlockNode[] = [...doc.children];\n\t\tnewChildren.splice(step.index, 0, step.node);\n\t\treturn { children: newChildren };\n\t}\n\n\treturn mapNodeByPath(doc, step.parentPath, (parent) => {\n\t\tconst newChildren: ChildNode[] = [...parent.children];\n\t\tnewChildren.splice(step.index, 0, step.node);\n\t\treturn { ...parent, children: newChildren };\n\t});\n}\n\nfunction applyRemoveNode(doc: Document, step: RemoveNodeStep): Document {\n\tif (step.parentPath.length === 0) {\n\t\t// Remove from document root\n\t\tconst newChildren: BlockNode[] = [...doc.children];\n\t\tnewChildren.splice(step.index, 1);\n\t\treturn { children: newChildren };\n\t}\n\n\treturn mapNodeByPath(doc, step.parentPath, (parent) => {\n\t\tconst newChildren: ChildNode[] = [...parent.children];\n\t\tnewChildren.splice(step.index, 1);\n\t\treturn { ...parent, children: newChildren };\n\t});\n}\n\nfunction applySetNodeAttr(doc: Document, step: SetNodeAttrStep): Document {\n\tconst nodeId: string | undefined = step.path[step.path.length - 1];\n\tif (!nodeId) return doc;\n\n\treturn mapBlock(doc, nodeId, (block) => ({\n\t\t...block,\n\t\tattrs: step.attrs,\n\t}));\n}\n\n/**\n * Maps a node at the given path, replacing it with the result of fn.\n * Navigates down the path immutably, creating new parent nodes as needed.\n */\nfunction mapNodeByPath(\n\tdoc: Document,\n\tpath: readonly string[],\n\tfn: (node: BlockNode) => BlockNode,\n): Document {\n\tif (path.length === 0) return doc;\n\n\tconst rootId: string | undefined = path[0];\n\tif (!rootId) return doc;\n\treturn {\n\t\tchildren: doc.children.map((child) => {\n\t\t\tif (!isBlockNode(child) || child.id !== rootId) return child;\n\t\t\tif (path.length === 1) return fn(child);\n\t\t\treturn mapNodeByPathRecursive(child, path, 1, fn);\n\t\t}),\n\t};\n}\n\nfunction mapNodeByPathRecursive(\n\tnode: BlockNode,\n\tpath: readonly string[],\n\tdepth: number,\n\tfn: (node: BlockNode) => BlockNode,\n): BlockNode {\n\tconst targetId: string | undefined = path[depth];\n\tif (!targetId) return node;\n\tconst newChildren: ChildNode[] = node.children.map((child) => {\n\t\tif (!isBlockNode(child) || child.id !== targetId) return child;\n\t\tif (depth === path.length - 1) return fn(child);\n\t\treturn mapNodeByPathRecursive(child, path, depth + 1, fn);\n\t});\n\treturn { ...node, children: newChildren };\n}\n","/**\n * Transaction system for the Notectl editor.\n * Transactions describe atomic, invertible state changes.\n */\n\nimport type {\n\tBlockAttrs,\n\tBlockNode,\n\tDocument,\n\tInlineNode,\n\tMark,\n\tTextSegment,\n} from '../model/Document.js';\nimport {\n\tgetBlockLength,\n\tgetBlockMarksAtOffset,\n\tgetBlockSegmentsInRange,\n\tgetBlockText,\n\tgetContentAtOffset,\n\tgetInlineChildren,\n\tisBlockNode,\n\tisInlineNode,\n} from '../model/Document.js';\nimport { findNode, resolveNodeByPath } from '../model/NodeResolver.js';\nimport type { Selection } from '../model/Selection.js';\nimport type { BlockId, NodeTypeName } from '../model/TypeBrands.js';\nimport { applyStep } from './StepApplication.js';\n\n// --- Step Types ---\n\nexport interface InsertTextStep {\n\treadonly type: 'insertText';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly text: string;\n\treadonly marks: readonly Mark[];\n\treadonly segments?: readonly TextSegment[];\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface DeleteTextStep {\n\treadonly type: 'deleteText';\n\treadonly blockId: BlockId;\n\treadonly from: number;\n\treadonly to: number;\n\treadonly deletedText: string;\n\treadonly deletedMarks: readonly Mark[];\n\treadonly deletedSegments: readonly TextSegment[];\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface SplitBlockStep {\n\treadonly type: 'splitBlock';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly newBlockId: BlockId;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface MergeBlocksStep {\n\treadonly type: 'mergeBlocks';\n\treadonly targetBlockId: BlockId;\n\treadonly sourceBlockId: BlockId;\n\treadonly targetLengthBefore: number;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface AddMarkStep {\n\treadonly type: 'addMark';\n\treadonly blockId: BlockId;\n\treadonly from: number;\n\treadonly to: number;\n\treadonly mark: Mark;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface RemoveMarkStep {\n\treadonly type: 'removeMark';\n\treadonly blockId: BlockId;\n\treadonly from: number;\n\treadonly to: number;\n\treadonly mark: Mark;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface SetStoredMarksStep {\n\treadonly type: 'setStoredMarks';\n\treadonly marks: readonly Mark[] | null;\n\treadonly previousMarks: readonly Mark[] | null;\n}\n\nexport interface SetBlockTypeStep {\n\treadonly type: 'setBlockType';\n\treadonly blockId: BlockId;\n\treadonly nodeType: NodeTypeName;\n\treadonly attrs?: BlockAttrs;\n\treadonly previousNodeType: NodeTypeName;\n\treadonly previousAttrs?: BlockAttrs;\n\treadonly path?: readonly BlockId[];\n}\n\n// --- Structural Steps (for nested documents) ---\n\nexport interface InsertNodeStep {\n\treadonly type: 'insertNode';\n\treadonly parentPath: readonly BlockId[];\n\treadonly index: number;\n\treadonly node: BlockNode;\n}\n\nexport interface RemoveNodeStep {\n\treadonly type: 'removeNode';\n\treadonly parentPath: readonly BlockId[];\n\treadonly index: number;\n\treadonly removedNode: BlockNode;\n}\n\nexport interface SetNodeAttrStep {\n\treadonly type: 'setNodeAttr';\n\treadonly path: readonly BlockId[];\n\treadonly attrs: BlockAttrs | undefined;\n\treadonly previousAttrs?: BlockAttrs;\n}\n\n// --- InlineNode Steps ---\n\nexport interface InsertInlineNodeStep {\n\treadonly type: 'insertInlineNode';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly node: InlineNode;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface RemoveInlineNodeStep {\n\treadonly type: 'removeInlineNode';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly removedNode: InlineNode;\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface SetInlineNodeAttrStep {\n\treadonly type: 'setInlineNodeAttr';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly attrs: Readonly<Record<string, string | number | boolean>>;\n\treadonly previousAttrs: Readonly<Record<string, string | number | boolean>>;\n\treadonly path?: readonly BlockId[];\n}\n\nexport type Step =\n\t| InsertTextStep\n\t| DeleteTextStep\n\t| SplitBlockStep\n\t| MergeBlocksStep\n\t| AddMarkStep\n\t| RemoveMarkStep\n\t| SetStoredMarksStep\n\t| SetBlockTypeStep\n\t| InsertNodeStep\n\t| RemoveNodeStep\n\t| SetNodeAttrStep\n\t| InsertInlineNodeStep\n\t| RemoveInlineNodeStep\n\t| SetInlineNodeAttrStep;\n\n// --- Transaction ---\n\nexport type TransactionOrigin = 'input' | 'paste' | 'command' | 'history' | 'api';\n\nexport interface TransactionMetadata {\n\treadonly origin: TransactionOrigin;\n\treadonly timestamp: number;\n}\n\nexport interface Transaction {\n\treadonly steps: readonly Step[];\n\treadonly selectionBefore: Selection;\n\treadonly selectionAfter: Selection;\n\treadonly storedMarksAfter: readonly Mark[] | null;\n\treadonly metadata: TransactionMetadata;\n}\n\n// --- Step Inversion ---\n\n/** Inverts a single step for undo. */\nexport function invertStep(step: Step): Step {\n\tswitch (step.type) {\n\t\tcase 'insertText':\n\t\t\treturn {\n\t\t\t\ttype: 'deleteText',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\tfrom: step.offset,\n\t\t\t\tto: step.offset + step.text.length,\n\t\t\t\tdeletedText: step.text,\n\t\t\t\tdeletedMarks: step.marks,\n\t\t\t\tdeletedSegments: step.segments ?? [{ text: step.text, marks: [...step.marks] }],\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'deleteText':\n\t\t\treturn {\n\t\t\t\ttype: 'insertText',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\toffset: step.from,\n\t\t\t\ttext: step.deletedText,\n\t\t\t\tmarks: step.deletedMarks,\n\t\t\t\tsegments: step.deletedSegments,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'splitBlock':\n\t\t\treturn {\n\t\t\t\ttype: 'mergeBlocks',\n\t\t\t\ttargetBlockId: step.blockId,\n\t\t\t\tsourceBlockId: step.newBlockId,\n\t\t\t\ttargetLengthBefore: step.offset,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'mergeBlocks':\n\t\t\treturn {\n\t\t\t\ttype: 'splitBlock',\n\t\t\t\tblockId: step.targetBlockId,\n\t\t\t\toffset: step.targetLengthBefore,\n\t\t\t\tnewBlockId: step.sourceBlockId,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'addMark':\n\t\t\treturn {\n\t\t\t\ttype: 'removeMark',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\tfrom: step.from,\n\t\t\t\tto: step.to,\n\t\t\t\tmark: step.mark,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'removeMark':\n\t\t\treturn {\n\t\t\t\ttype: 'addMark',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\tfrom: step.from,\n\t\t\t\tto: step.to,\n\t\t\t\tmark: step.mark,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'setStoredMarks':\n\t\t\treturn {\n\t\t\t\ttype: 'setStoredMarks',\n\t\t\t\tmarks: step.previousMarks,\n\t\t\t\tpreviousMarks: step.marks,\n\t\t\t};\n\t\tcase 'setBlockType':\n\t\t\treturn {\n\t\t\t\ttype: 'setBlockType',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\tnodeType: step.previousNodeType,\n\t\t\t\tattrs: step.previousAttrs,\n\t\t\t\tpreviousNodeType: step.nodeType,\n\t\t\t\tpreviousAttrs: step.attrs,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'insertNode':\n\t\t\treturn {\n\t\t\t\ttype: 'removeNode',\n\t\t\t\tparentPath: step.parentPath,\n\t\t\t\tindex: step.index,\n\t\t\t\tremovedNode: step.node,\n\t\t\t};\n\t\tcase 'removeNode':\n\t\t\treturn {\n\t\t\t\ttype: 'insertNode',\n\t\t\t\tparentPath: step.parentPath,\n\t\t\t\tindex: step.index,\n\t\t\t\tnode: step.removedNode,\n\t\t\t};\n\t\tcase 'setNodeAttr':\n\t\t\treturn {\n\t\t\t\ttype: 'setNodeAttr',\n\t\t\t\tpath: step.path,\n\t\t\t\tattrs: step.previousAttrs,\n\t\t\t\tpreviousAttrs: step.attrs,\n\t\t\t};\n\t\tcase 'insertInlineNode':\n\t\t\treturn {\n\t\t\t\ttype: 'removeInlineNode',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\toffset: step.offset,\n\t\t\t\tremovedNode: step.node,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'removeInlineNode':\n\t\t\treturn {\n\t\t\t\ttype: 'insertInlineNode',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\toffset: step.offset,\n\t\t\t\tnode: step.removedNode,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t\tcase 'setInlineNodeAttr':\n\t\t\treturn {\n\t\t\t\ttype: 'setInlineNodeAttr',\n\t\t\t\tblockId: step.blockId,\n\t\t\t\toffset: step.offset,\n\t\t\t\tattrs: step.previousAttrs,\n\t\t\t\tpreviousAttrs: step.attrs,\n\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t};\n\t}\n}\n\n/** Inverts an entire transaction (reverses step order and swaps selections). */\nexport function invertTransaction(tr: Transaction): Transaction {\n\treturn {\n\t\tsteps: tr.steps.map(invertStep).reverse(),\n\t\tselectionBefore: tr.selectionAfter,\n\t\tselectionAfter: tr.selectionBefore,\n\t\tstoredMarksAfter: null,\n\t\tmetadata: {\n\t\t\torigin: 'history',\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t};\n}\n\n// --- TransactionBuilder ---\n\n/** Fluent API for building transactions. */\nexport class TransactionBuilder {\n\tprivate readonly steps: Step[] = [];\n\tprivate selection: Selection;\n\tprivate storedMarks: readonly Mark[] | null;\n\tprivate readonly selectionBefore: Selection;\n\tprivate readonly origin: TransactionOrigin;\n\tprivate workingDoc: Document | null;\n\n\tconstructor(\n\t\tcurrentSelection: Selection,\n\t\tcurrentStoredMarks: readonly Mark[] | null,\n\t\torigin: TransactionOrigin = 'api',\n\t\tdoc?: Document,\n\t) {\n\t\tthis.selection = currentSelection;\n\t\tthis.selectionBefore = currentSelection;\n\t\tthis.storedMarks = currentStoredMarks;\n\t\tthis.origin = origin;\n\t\tthis.workingDoc = doc ?? null;\n\t}\n\n\t/** Adds an insert-text step. Updates workingDoc if available. */\n\tinsertText(\n\t\tblockId: BlockId,\n\t\toffset: number,\n\t\ttext: string,\n\t\tmarks: readonly Mark[],\n\t\tsegments?: readonly TextSegment[],\n\t): this {\n\t\tconst step: InsertTextStep = {\n\t\t\ttype: 'insertText',\n\t\t\tblockId,\n\t\t\toffset,\n\t\t\ttext,\n\t\t\tmarks,\n\t\t\t...(segments ? { segments } : {}),\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Adds a delete-text step with explicit data. Updates workingDoc if available. */\n\tdeleteText(\n\t\tblockId: BlockId,\n\t\tfrom: number,\n\t\tto: number,\n\t\tdeletedText: string,\n\t\tdeletedMarks: readonly Mark[],\n\t\tdeletedSegments?: readonly TextSegment[],\n\t): this {\n\t\tlet segments: readonly TextSegment[];\n\t\tif (deletedSegments) {\n\t\t\tsegments = deletedSegments;\n\t\t} else if (this.workingDoc) {\n\t\t\tconst block = findNode(this.workingDoc, blockId);\n\t\t\tsegments = block\n\t\t\t\t? getBlockSegmentsInRange(block, from, to)\n\t\t\t\t: [{ text: deletedText, marks: [...deletedMarks] }];\n\t\t} else {\n\t\t\tsegments = [{ text: deletedText, marks: [...deletedMarks] }];\n\t\t}\n\t\tconst step: DeleteTextStep = {\n\t\t\ttype: 'deleteText',\n\t\t\tblockId,\n\t\t\tfrom,\n\t\t\tto,\n\t\t\tdeletedText,\n\t\t\tdeletedMarks,\n\t\t\tdeletedSegments: segments,\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Deletes text at the given range, auto-deriving deletedText, deletedMarks, and deletedSegments\n\t * from the working document. Requires a document to be provided at construction.\n\t */\n\tdeleteTextAt(blockId: BlockId, from: number, to: number): this {\n\t\tconst doc = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'deleteTextAt requires a document. Use state.transaction() or provide doc to constructor.',\n\t\t\t);\n\t\t}\n\n\t\tconst block = findNode(doc, blockId);\n\t\tif (!block) {\n\t\t\tthrow new Error(`Block \"${blockId}\" not found in working document.`);\n\t\t}\n\n\t\tconst text = getBlockText(block);\n\t\tconst deletedText = text.slice(from, to);\n\t\tconst deletedMarks = getBlockMarksAtOffset(block, from);\n\t\tconst deletedSegments = getBlockSegmentsInRange(block, from, to);\n\n\t\treturn this.deleteText(blockId, from, to, deletedText, deletedMarks, deletedSegments);\n\t}\n\n\t/** Adds a split-block step. Updates workingDoc if available. */\n\tsplitBlock(blockId: BlockId, offset: number, newBlockId: BlockId): this {\n\t\tconst step: SplitBlockStep = { type: 'splitBlock', blockId, offset, newBlockId };\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Adds a merge-blocks step with explicit targetLengthBefore. Updates workingDoc if available. */\n\tmergeBlocks(targetBlockId: BlockId, sourceBlockId: BlockId, targetLengthBefore: number): this {\n\t\tconst step: MergeBlocksStep = {\n\t\t\ttype: 'mergeBlocks',\n\t\t\ttargetBlockId,\n\t\t\tsourceBlockId,\n\t\t\ttargetLengthBefore,\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Merges two blocks, auto-deriving targetLengthBefore from the working document.\n\t * Requires a document to be provided at construction.\n\t */\n\tmergeBlocksAt(targetBlockId: BlockId, sourceBlockId: BlockId): this {\n\t\tconst doc = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'mergeBlocksAt requires a document. Use state.transaction() or provide doc to constructor.',\n\t\t\t);\n\t\t}\n\n\t\tconst targetBlock = findNode(doc, targetBlockId);\n\t\tif (!targetBlock) {\n\t\t\tthrow new Error(`Target block \"${targetBlockId}\" not found in working document.`);\n\t\t}\n\n\t\tconst targetLengthBefore = getBlockLength(targetBlock);\n\t\treturn this.mergeBlocks(targetBlockId, sourceBlockId, targetLengthBefore);\n\t}\n\n\t/** Adds an add-mark step. Updates workingDoc if available. */\n\taddMark(blockId: BlockId, from: number, to: number, mark: Mark): this {\n\t\tconst step: AddMarkStep = { type: 'addMark', blockId, from, to, mark };\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Adds a remove-mark step. Updates workingDoc if available. */\n\tremoveMark(blockId: BlockId, from: number, to: number, mark: Mark): this {\n\t\tconst step: RemoveMarkStep = { type: 'removeMark', blockId, from, to, mark };\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Adds a set-block-type step, changing a block's node type and optionally its attrs. */\n\tsetBlockType(blockId: BlockId, nodeType: NodeTypeName, attrs?: BlockAttrs): this {\n\t\tconst doc = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'setBlockType requires a document. Use state.transaction() or provide doc to constructor.',\n\t\t\t);\n\t\t}\n\t\tconst block = findNode(doc, blockId);\n\t\tif (!block) {\n\t\t\tthrow new Error(`Block \"${blockId}\" not found in working document.`);\n\t\t}\n\t\tconst step: SetBlockTypeStep = {\n\t\t\ttype: 'setBlockType',\n\t\t\tblockId,\n\t\t\tnodeType,\n\t\t\t...(attrs ? { attrs } : {}),\n\t\t\tpreviousNodeType: block.type,\n\t\t\t...(block.attrs ? { previousAttrs: block.attrs } : {}),\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Inserts a node as a child of the parent at the given path and index. */\n\tinsertNode(parentPath: readonly BlockId[], index: number, node: BlockNode): this {\n\t\tconst step: InsertNodeStep = { type: 'insertNode', parentPath, index, node };\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Removes a node at the given index from the parent at the given path. */\n\tremoveNode(parentPath: readonly BlockId[], index: number): this {\n\t\tconst doc = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'removeNode requires a document. Use state.transaction() or provide doc to constructor.',\n\t\t\t);\n\t\t}\n\n\t\tconst removedNode = resolveRemovedNode(doc, parentPath, index);\n\t\tif (!removedNode) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node at index ${index} not found under parent path [${parentPath.join(', ')}].`,\n\t\t\t);\n\t\t}\n\n\t\tconst step: RemoveNodeStep = { type: 'removeNode', parentPath, index, removedNode };\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Sets attributes on a node at the given path. */\n\tsetNodeAttr(path: readonly BlockId[], attrs: BlockAttrs): this {\n\t\tconst doc = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'setNodeAttr requires a document. Use state.transaction() or provide doc to constructor.',\n\t\t\t);\n\t\t}\n\n\t\tconst node = resolveNodeByPath(doc, path);\n\t\tif (!node) {\n\t\t\tthrow new Error(`Node not found at path [${path.join(', ')}].`);\n\t\t}\n\n\t\tconst step: SetNodeAttrStep = {\n\t\t\ttype: 'setNodeAttr',\n\t\t\tpath,\n\t\t\tattrs,\n\t\t\t...(node.attrs ? { previousAttrs: node.attrs } : {}),\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Inserts an InlineNode at the given offset within a block. */\n\tinsertInlineNode(blockId: BlockId, offset: number, node: InlineNode): this {\n\t\tconst step: InsertInlineNodeStep = {\n\t\t\ttype: 'insertInlineNode',\n\t\t\tblockId,\n\t\t\toffset,\n\t\t\tnode,\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Removes an InlineNode at the given offset, deriving removedNode from workingDoc. */\n\tremoveInlineNode(blockId: BlockId, offset: number): this {\n\t\tconst doc: Document | null = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'removeInlineNode requires a document. Use state.transaction() or provide doc.',\n\t\t\t);\n\t\t}\n\t\tconst block: BlockNode | undefined = findNode(doc, blockId);\n\t\tif (!block) {\n\t\t\tthrow new Error(`Block \"${blockId}\" not found in working document.`);\n\t\t}\n\t\tconst content = getContentAtOffset(block, offset);\n\t\tif (!content || content.kind !== 'inline') {\n\t\t\tthrow new Error(`No InlineNode at offset ${offset} in block \"${blockId}\".`);\n\t\t}\n\t\tconst step: RemoveInlineNodeStep = {\n\t\t\ttype: 'removeInlineNode',\n\t\t\tblockId,\n\t\t\toffset,\n\t\t\tremovedNode: content.node,\n\t\t};\n\t\tthis.steps.push(step);\n\t\tthis.advanceDoc(step);\n\t\treturn this;\n\t}\n\n\t/** Sets attributes on an InlineNode at the given offset. */\n\tsetInlineNodeAttr(\n\t\tblockId: BlockId,\n\t\toffset: number,\n\t\tattrs: Readonly<Record<string, string | number | boolean>>,\n\t): this {\n\t\tconst doc: Document | null = this.workingDoc;\n\t\tif (!doc) {\n\t\t\tthrow new Error(\n\t\t\t\t'setInlineNodeAttr requires a document. Use state.transaction() or provide doc.',\n\t\t\t);\n\t\t}\n\t\tconst block: BlockNode | undefined = findNode(doc, blockId);\n\t\tif (!block) {\n\t\t\tthrow new Error(`Block \"${blockId}\" not found in working document.`);\n\t\t}\n\t\tconst inlineChildren = getInlineChildren(block);\n\t\tlet pos = 0;\n\t\tfor (const child of inlineChildren) {\n\t\t\tif (isInlineNode(child) && pos === offset) {\n\t\t\t\tconst step: SetInlineNodeAttrStep = {\n\t\t\t\t\ttype: 'setInlineNodeAttr',\n\t\t\t\t\tblockId,\n\t\t\t\t\toffset,\n\t\t\t\t\tattrs,\n\t\t\t\t\tpreviousAttrs: child.attrs,\n\t\t\t\t};\n\t\t\t\tthis.steps.push(step);\n\t\t\t\tthis.advanceDoc(step);\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tpos += isInlineNode(child) ? 1 : child.text.length;\n\t\t}\n\t\tthrow new Error(`No InlineNode at offset ${offset} in block \"${blockId}\".`);\n\t}\n\n\t/** Sets the selection for the resulting state. */\n\tsetSelection(selection: Selection): this {\n\t\tthis.selection = selection;\n\t\treturn this;\n\t}\n\n\t/** Sets stored marks for the resulting state. */\n\tsetStoredMarks(marks: readonly Mark[] | null, previousMarks: readonly Mark[] | null): this {\n\t\tthis.steps.push({ type: 'setStoredMarks', marks, previousMarks });\n\t\tthis.storedMarks = marks;\n\t\treturn this;\n\t}\n\n\t/** Builds the final transaction. */\n\tbuild(): Transaction {\n\t\treturn {\n\t\t\tsteps: [...this.steps],\n\t\t\tselectionBefore: this.selectionBefore,\n\t\t\tselectionAfter: this.selection,\n\t\t\tstoredMarksAfter: this.storedMarks,\n\t\t\tmetadata: {\n\t\t\t\torigin: this.origin,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Advances the working document by applying a step. */\n\tprivate advanceDoc(step: Step): void {\n\t\tif (this.workingDoc) {\n\t\t\tthis.workingDoc = applyStep(this.workingDoc, step);\n\t\t}\n\t}\n}\n\n/** Helper to create a TransactionBuilder with input origin. */\nexport function inputTransaction(\n\tselection: Selection,\n\tstoredMarks: readonly Mark[] | null,\n): TransactionBuilder {\n\treturn new TransactionBuilder(selection, storedMarks, 'input');\n}\n\n/** Helper to create a TransactionBuilder with command origin. */\nexport function commandTransaction(\n\tselection: Selection,\n\tstoredMarks: readonly Mark[] | null,\n): TransactionBuilder {\n\treturn new TransactionBuilder(selection, storedMarks, 'command');\n}\n\n/** Resolves the block node to be removed from a parent path and index. */\nfunction resolveRemovedNode(\n\tdoc: Document,\n\tparentPath: readonly BlockId[],\n\tindex: number,\n): BlockNode | undefined {\n\tif (parentPath.length === 0) {\n\t\tconst child = doc.children[index];\n\t\treturn child && isBlockNode(child) ? child : undefined;\n\t}\n\tconst parent = resolveNodeByPath(doc, parentPath);\n\tif (!parent) return undefined;\n\tconst child = parent.children[index];\n\treturn child && isBlockNode(child) ? child : undefined;\n}\n","/**\n * Immutable editor state container.\n * Every mutation produces a new EditorState instance.\n */\n\nimport {\n\ttype BlockNode,\n\ttype Document,\n\ttype Mark,\n\tcreateDocument,\n\tgetBlockLength,\n\tisBlockNode,\n\tisLeafBlock,\n} from '../model/Document.js';\nimport { findNode, findNodePath } from '../model/NodeResolver.js';\nimport type { Schema } from '../model/Schema.js';\nimport { defaultSchema } from '../model/Schema.js';\nimport type { Position, Selection } from '../model/Selection.js';\nimport { createCollapsedSelection, createPosition, createSelection } from '../model/Selection.js';\nimport { type BlockId, blockId } from '../model/TypeBrands.js';\nimport { applyStep } from './StepApplication.js';\nimport type { Transaction } from './Transaction.js';\nimport { TransactionBuilder } from './Transaction.js';\n\nexport class EditorState {\n\treadonly doc: Document;\n\treadonly selection: Selection;\n\treadonly storedMarks: readonly Mark[] | null;\n\treadonly schema: Schema;\n\n\tprivate _blockMap: Map<BlockId, BlockNode> | null = null;\n\tprivate _blockOrder: readonly BlockId[] | null = null;\n\n\tprivate constructor(\n\t\tdoc: Document,\n\t\tselection: Selection,\n\t\tstoredMarks: readonly Mark[] | null,\n\t\tschema: Schema,\n\t) {\n\t\tthis.doc = doc;\n\t\tthis.selection = selection;\n\t\tthis.storedMarks = storedMarks;\n\t\tthis.schema = schema;\n\t}\n\n\t/** Creates a new EditorState with default document. */\n\tstatic create(options?: {\n\t\tdoc?: Document;\n\t\tselection?: Selection;\n\t\tschema?: Schema;\n\t}): EditorState {\n\t\tconst schema = options?.schema ?? defaultSchema();\n\t\tconst doc = options?.doc ?? createDocument();\n\t\tconst firstBlock = doc.children[0];\n\t\tconst selection =\n\t\t\toptions?.selection ?? createCollapsedSelection(firstBlock ? firstBlock.id : blockId(''), 0);\n\n\t\treturn new EditorState(doc, selection, null, schema);\n\t}\n\n\t/** Creates a TransactionBuilder from this state. */\n\ttransaction(\n\t\torigin: 'input' | 'paste' | 'command' | 'history' | 'api' = 'api',\n\t): TransactionBuilder {\n\t\treturn new TransactionBuilder(this.selection, this.storedMarks, origin, this.doc);\n\t}\n\n\t/** Applies a transaction and returns a new EditorState. */\n\tapply(tr: Transaction): EditorState {\n\t\tlet doc = this.doc;\n\n\t\tfor (const step of tr.steps) {\n\t\t\tdoc = applyStep(doc, step);\n\t\t}\n\n\t\tconst selection = validateSelection(doc, tr.selectionAfter);\n\t\treturn new EditorState(doc, selection, tr.storedMarksAfter, this.schema);\n\t}\n\n\t/** Finds a block by its ID anywhere in the tree. Uses a lazy-built Map for O(1) lookup. */\n\tgetBlock(blockId: BlockId): BlockNode | undefined {\n\t\tthis._blockMap ??= buildBlockMap(this.doc);\n\t\treturn this._blockMap.get(blockId);\n\t}\n\n\t/** Returns leaf-block IDs in depth-first order. Cached after first call. */\n\tgetBlockOrder(): readonly BlockId[] {\n\t\tthis._blockOrder ??= buildBlockOrder(this.doc);\n\t\treturn this._blockOrder;\n\t}\n\n\t/** Returns the path (array of block IDs) to a node. */\n\tgetNodePath(nodeId: BlockId): BlockId[] | undefined {\n\t\treturn findNodePath(this.doc, nodeId) as BlockId[] | undefined;\n\t}\n\n\t/** Returns the parent BlockNode of a node, or undefined for top-level blocks. */\n\tgetParent(nodeId: BlockId): BlockNode | undefined {\n\t\tconst path = findNodePath(this.doc, nodeId);\n\t\tif (!path || path.length <= 1) return undefined;\n\t\tconst parentId = path[path.length - 2] as BlockId | undefined;\n\t\tif (!parentId) return undefined;\n\t\treturn findNode(this.doc, parentId);\n\t}\n\n\t/** Serializes the state to JSON. */\n\ttoJSON(): object {\n\t\treturn {\n\t\t\tdoc: this.doc,\n\t\t\tselection: this.selection,\n\t\t};\n\t}\n\n\t/** Deserializes a state from JSON. */\n\tstatic fromJSON(json: { doc: Document; selection: Selection }, schema?: Schema): EditorState {\n\t\treturn new EditorState(json.doc, json.selection, null, schema ?? defaultSchema());\n\t}\n}\n\n/** Validates a position against the document, clamping or falling back as needed. */\nfunction validatePosition(doc: Document, pos: Position): Position {\n\tconst block = findNode(doc, pos.blockId);\n\tif (block) {\n\t\tconst length = getBlockLength(block);\n\t\tif (pos.offset > length) {\n\t\t\treturn createPosition(pos.blockId, length, pos.path);\n\t\t}\n\t\treturn pos;\n\t}\n\n\tconst firstBlock = doc.children[0];\n\tif (!firstBlock) return pos;\n\treturn createPosition(firstBlock.id, 0);\n}\n\n/** Validates a selection against the document, ensuring blockIds exist and offsets are in bounds. */\nfunction validateSelection(doc: Document, sel: Selection): Selection {\n\tconst anchor = validatePosition(doc, sel.anchor);\n\tconst head = validatePosition(doc, sel.head);\n\tif (anchor === sel.anchor && head === sel.head) return sel;\n\treturn createSelection(anchor, head);\n}\n\n/** Recursively builds a Map of blockId → BlockNode for all nodes in the tree. */\nfunction buildBlockMap(doc: Document): Map<BlockId, BlockNode> {\n\tconst map = new Map<BlockId, BlockNode>();\n\tfunction walk(blocks: readonly import('../model/Document.js').ChildNode[]): void {\n\t\tfor (const child of blocks) {\n\t\t\tif (isBlockNode(child)) {\n\t\t\t\tmap.set(child.id, child);\n\t\t\t\twalk(child.children);\n\t\t\t}\n\t\t}\n\t}\n\twalk(doc.children);\n\treturn map;\n}\n\n/** Returns leaf-block IDs in depth-first order. */\nfunction buildBlockOrder(doc: Document): BlockId[] {\n\tconst order: BlockId[] = [];\n\tfunction walk(blocks: readonly import('../model/Document.js').ChildNode[]): void {\n\t\tfor (const child of blocks) {\n\t\t\tif (isBlockNode(child)) {\n\t\t\t\tif (isLeafBlock(child)) {\n\t\t\t\t\torder.push(child.id);\n\t\t\t\t} else {\n\t\t\t\t\twalk(child.children);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\twalk(doc.children);\n\treturn order;\n}\n","/**\n * History manager for undo/redo with transaction grouping.\n */\n\nimport type { EditorState } from './EditorState.js';\nimport type { Step, Transaction } from './Transaction.js';\nimport { invertTransaction } from './Transaction.js';\n\nexport interface HistoryResult {\n\treadonly state: EditorState;\n\treadonly transaction: Transaction;\n}\n\ninterface HistoryGroup {\n\treadonly transactions: readonly Transaction[];\n\treadonly timestamp: number;\n}\n\nconst DEFAULT_GROUP_TIMEOUT_MS = 500;\nconst DEFAULT_MAX_DEPTH = 100;\n\nexport class HistoryManager {\n\tprivate undoStack: HistoryGroup[] = [];\n\tprivate redoStack: HistoryGroup[] = [];\n\tprivate readonly groupTimeoutMs: number;\n\tprivate readonly maxDepth: number;\n\tprivate lastOrigin: string | null = null;\n\n\tconstructor(options?: { groupTimeoutMs?: number; maxDepth?: number }) {\n\t\tthis.groupTimeoutMs = options?.groupTimeoutMs ?? DEFAULT_GROUP_TIMEOUT_MS;\n\t\tthis.maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;\n\t}\n\n\t/**\n\t * Pushes a transaction onto the undo stack.\n\t * Groups consecutive input transactions within the timeout window.\n\t */\n\tpush(tr: Transaction): void {\n\t\t// History and redo transactions are not pushed\n\t\tif (tr.metadata.origin === 'history') return;\n\n\t\tconst now = tr.metadata.timestamp;\n\t\tconst lastGroup = this.undoStack[this.undoStack.length - 1];\n\t\tconst shouldGroup =\n\t\t\tlastGroup &&\n\t\t\ttr.metadata.origin === 'input' &&\n\t\t\tthis.lastOrigin === 'input' &&\n\t\t\tnow - lastGroup.timestamp < this.groupTimeoutMs &&\n\t\t\tthis.isSameInputType(lastGroup.transactions, tr);\n\n\t\tif (shouldGroup && lastGroup) {\n\t\t\t// Merge into existing group\n\t\t\tthis.undoStack[this.undoStack.length - 1] = {\n\t\t\t\ttransactions: [...lastGroup.transactions, tr],\n\t\t\t\ttimestamp: now,\n\t\t\t};\n\t\t} else {\n\t\t\t// Start new group\n\t\t\tthis.undoStack.push({\n\t\t\t\ttransactions: [tr],\n\t\t\t\ttimestamp: now,\n\t\t\t});\n\t\t}\n\n\t\tthis.lastOrigin = tr.metadata.origin;\n\n\t\t// Clear redo stack on new input\n\t\tthis.redoStack = [];\n\n\t\t// Enforce max depth\n\t\twhile (this.undoStack.length > this.maxDepth) {\n\t\t\tthis.undoStack.shift();\n\t\t}\n\t}\n\n\t/** Undoes the last group and returns the new state with transaction, or null if nothing to undo. */\n\tundo(state: EditorState): HistoryResult | null {\n\t\tconst group = this.undoStack.pop();\n\t\tif (!group) return null;\n\n\t\tlet currentState = state;\n\t\tconst allSteps: Step[] = [];\n\n\t\t// Apply inverted transactions in reverse order\n\t\tfor (let i = group.transactions.length - 1; i >= 0; i--) {\n\t\t\tconst tr = group.transactions[i];\n\t\t\tif (!tr) continue;\n\t\t\tconst inverted = invertTransaction(tr);\n\t\t\tcurrentState = currentState.apply(inverted);\n\t\t\tallSteps.push(...inverted.steps);\n\t\t}\n\n\t\t// Push to redo stack\n\t\tthis.redoStack.push({\n\t\t\ttransactions: group.transactions,\n\t\t\ttimestamp: Date.now(),\n\t\t});\n\n\t\tthis.lastOrigin = null;\n\n\t\tconst transaction: Transaction = {\n\t\t\tsteps: allSteps,\n\t\t\tselectionBefore: state.selection,\n\t\t\tselectionAfter: currentState.selection,\n\t\t\tstoredMarksAfter: currentState.storedMarks,\n\t\t\tmetadata: { origin: 'history', timestamp: Date.now() },\n\t\t};\n\n\t\treturn { state: currentState, transaction };\n\t}\n\n\t/** Redoes the last undone group and returns the new state with transaction, or null if nothing to redo. */\n\tredo(state: EditorState): HistoryResult | null {\n\t\tconst group = this.redoStack.pop();\n\t\tif (!group) return null;\n\n\t\tlet currentState = state;\n\t\tconst allSteps: Step[] = [];\n\n\t\t// Re-apply transactions in original order\n\t\tfor (const tr of group.transactions) {\n\t\t\tcurrentState = currentState.apply(tr);\n\t\t\tallSteps.push(...tr.steps);\n\t\t}\n\n\t\t// Push back to undo stack\n\t\tthis.undoStack.push({\n\t\t\ttransactions: group.transactions,\n\t\t\ttimestamp: Date.now(),\n\t\t});\n\n\t\tthis.lastOrigin = null;\n\n\t\tconst transaction: Transaction = {\n\t\t\tsteps: allSteps,\n\t\t\tselectionBefore: state.selection,\n\t\t\tselectionAfter: currentState.selection,\n\t\t\tstoredMarksAfter: currentState.storedMarks,\n\t\t\tmetadata: { origin: 'history', timestamp: Date.now() },\n\t\t};\n\n\t\treturn { state: currentState, transaction };\n\t}\n\n\t/** Returns true if there are entries to undo. */\n\tcanUndo(): boolean {\n\t\treturn this.undoStack.length > 0;\n\t}\n\n\t/** Returns true if there are entries to redo. */\n\tcanRedo(): boolean {\n\t\treturn this.redoStack.length > 0;\n\t}\n\n\t/** Clears all history. */\n\tclear(): void {\n\t\tthis.undoStack = [];\n\t\tthis.redoStack = [];\n\t\tthis.lastOrigin = null;\n\t}\n\n\t/**\n\t * Checks if consecutive transactions are of the same \"type\" for grouping.\n\t * Groups text insertion together, deletion together, but not mixed.\n\t */\n\tprivate isSameInputType(existing: readonly Transaction[], incoming: Transaction): boolean {\n\t\tconst lastTr = existing[existing.length - 1];\n\t\tif (!lastTr) return false;\n\n\t\tconst lastStepType = lastTr.steps[0]?.type;\n\t\tconst incomingStepType = incoming.steps[0]?.type;\n\n\t\t// Group same step types (insertText with insertText, deleteText with deleteText)\n\t\treturn lastStepType === incomingStepType;\n\t}\n}\n","/**\n * Editor commands for formatting, text manipulation, and history.\n */\n\nimport {\n\ttype BlockNode,\n\ttype Mark,\n\ttype MarkType,\n\tgenerateBlockId,\n\tgetBlockLength,\n\tgetBlockMarksAtOffset,\n\tgetContentAtOffset,\n\tgetInlineChildren,\n\thasMark,\n\tisTextNode,\n} from '../model/Document.js';\nimport { isMarkAllowed } from '../model/Schema.js';\nimport {\n\tcreateCollapsedSelection,\n\tcreateSelection,\n\tisCollapsed,\n\tselectionRange,\n} from '../model/Selection.js';\nimport { type BlockId, markType as mkType } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { TransactionBuilder } from '../state/Transaction.js';\n\n// --- Feature Configuration ---\n\nexport interface FeatureConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n}\n\nconst defaultFeatures: FeatureConfig = { bold: true, italic: true, underline: true };\n\n// --- Mark Commands ---\n\n/**\n * Toggles a mark on the current selection.\n * If collapsed, toggles stored marks. If range, applies/removes from text.\n */\nexport function toggleMark(\n\tstate: EditorState,\n\tmarkType: MarkType,\n\tfeatures: FeatureConfig = defaultFeatures,\n): Transaction | null {\n\tif (isFeatureGated(markType, features)) return null;\n\tif (!isMarkAllowed(state.schema, markType)) return null;\n\n\tconst mark: Mark = { type: markType };\n\tconst sel = state.selection;\n\n\tif (isCollapsed(sel)) {\n\t\t// Toggle stored marks\n\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\tif (!anchorBlock) return null;\n\t\tconst currentMarks = state.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\tconst hasIt = hasMark(currentMarks, markType);\n\t\tconst newMarks = hasIt\n\t\t\t? currentMarks.filter((m) => m.type !== markType)\n\t\t\t: [...currentMarks, mark];\n\n\t\treturn state\n\t\t\t.transaction('command')\n\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t}\n\n\t// Range selection — apply/remove mark to all blocks in range\n\tconst blockOrder = state.getBlockOrder();\n\tconst range = selectionRange(sel, blockOrder);\n\tconst builder = state.transaction('command');\n\n\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t// Determine if we should add or remove\n\tconst shouldRemove = isMarkActiveInRange(state, markType);\n\n\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\tconst blockId = blockOrder[i];\n\t\tif (!blockId) continue;\n\t\tconst block = state.getBlock(blockId);\n\t\tif (!block) continue;\n\t\tconst blockLen = getBlockLength(block);\n\n\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\tif (from === to) continue;\n\n\t\tif (shouldRemove) {\n\t\t\tbuilder.removeMark(blockId, from, to, mark);\n\t\t} else {\n\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t}\n\t}\n\n\tbuilder.setSelection(sel);\n\treturn builder.build();\n}\n\n/** Checks if a mark is active across the entire selection range. */\nfunction isMarkActiveInRange(state: EditorState, markType: MarkType): boolean {\n\tconst sel = state.selection;\n\tconst blockOrder = state.getBlockOrder();\n\tconst range = selectionRange(sel, blockOrder);\n\n\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\tconst blockId = blockOrder[i];\n\t\tif (!blockId) continue;\n\t\tconst block = state.getBlock(blockId);\n\t\tif (!block) continue;\n\t\tconst blockLen = getBlockLength(block);\n\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\tif (!isMarkActiveInBlock(block, from, to, markType)) return false;\n\t}\n\n\treturn true;\n}\n\nfunction isMarkActiveInBlock(\n\tblock: BlockNode,\n\tfrom: number,\n\tto: number,\n\tmarkType: MarkType,\n): boolean {\n\tif (from === to) return false;\n\tlet pos = 0;\n\tfor (const child of getInlineChildren(block)) {\n\t\tif (isTextNode(child)) {\n\t\t\tconst childEnd = pos + child.text.length;\n\t\t\tif (childEnd > from && pos < to) {\n\t\t\t\tif (!hasMark(child.marks, markType)) return false;\n\t\t\t}\n\t\t\tpos = childEnd;\n\t\t} else {\n\t\t\t// InlineNode: skip (width 1, no marks)\n\t\t\tpos += 1;\n\t\t}\n\t}\n\treturn true;\n}\n\nexport function toggleBold(state: EditorState, features?: FeatureConfig): Transaction | null {\n\treturn toggleMark(state, mkType('bold'), features);\n}\n\nexport function toggleItalic(state: EditorState, features?: FeatureConfig): Transaction | null {\n\treturn toggleMark(state, mkType('italic'), features);\n}\n\nexport function toggleUnderline(state: EditorState, features?: FeatureConfig): Transaction | null {\n\treturn toggleMark(state, mkType('underline'), features);\n}\n\n// --- Text Commands ---\n\n/** Inserts text at the current selection, replacing any selected range. */\nexport function insertTextCommand(\n\tstate: EditorState,\n\ttext: string,\n\torigin: 'input' | 'paste' = 'input',\n): Transaction {\n\tconst sel = state.selection;\n\tconst builder = state.transaction(origin);\n\tconst marks = resolveActiveMarks(state);\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst range = isCollapsed(sel) ? null : selectionRange(sel, state.getBlockOrder());\n\tconst insertBlockId = range ? range.from.blockId : sel.anchor.blockId;\n\tconst insertOffset = range ? range.from.offset : sel.anchor.offset;\n\n\tbuilder.insertText(insertBlockId, insertOffset, text, marks);\n\tbuilder.setSelection(createCollapsedSelection(insertBlockId, insertOffset + text.length));\n\n\treturn builder.build();\n}\n\n/** Deletes the current selection. */\nexport function deleteSelectionCommand(state: EditorState): Transaction | null {\n\tif (isCollapsed(state.selection)) return null;\n\n\tconst builder = state.transaction('input');\n\taddDeleteSelectionSteps(state, builder);\n\n\tconst range = selectionRange(state.selection, state.getBlockOrder());\n\tbuilder.setSelection(createCollapsedSelection(range.from.blockId, range.from.offset));\n\n\treturn builder.build();\n}\n\n/** Handles backspace key. */\nexport function deleteBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tif (sel.anchor.offset > 0) {\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.deleteTextAt(block.id, sel.anchor.offset - 1, sel.anchor.offset)\n\t\t\t.setSelection(createCollapsedSelection(block.id, sel.anchor.offset - 1))\n\t\t\t.build();\n\t}\n\n\t// At start of block — merge with previous\n\treturn mergeBlockBackward(state);\n}\n\n/** Handles delete key. */\nexport function deleteForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tconst blockLen = getBlockLength(block);\n\n\tif (sel.anchor.offset < blockLen) {\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.deleteTextAt(block.id, sel.anchor.offset, sel.anchor.offset + 1)\n\t\t\t.setSelection(createCollapsedSelection(block.id, sel.anchor.offset))\n\t\t\t.build();\n\t}\n\n\t// At end of block — merge with next\n\treturn mergeBlockForward(state);\n}\n\n/** Handles Ctrl+Backspace: delete word backward. */\nexport function deleteWordBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tif (sel.anchor.offset === 0) {\n\t\treturn mergeBlockBackward(state);\n\t}\n\n\tconst wordStart = findWordBoundaryBackward(block, sel.anchor.offset);\n\n\treturn state\n\t\t.transaction('input')\n\t\t.deleteTextAt(block.id, wordStart, sel.anchor.offset)\n\t\t.setSelection(createCollapsedSelection(block.id, wordStart))\n\t\t.build();\n}\n\n/** Handles Ctrl+Delete: delete word forward. */\nexport function deleteWordForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tconst blockLen = getBlockLength(block);\n\tif (sel.anchor.offset === blockLen) {\n\t\treturn mergeBlockForward(state);\n\t}\n\n\tconst wordEnd = findWordBoundaryForward(block, sel.anchor.offset);\n\n\treturn state\n\t\t.transaction('input')\n\t\t.deleteTextAt(block.id, sel.anchor.offset, wordEnd)\n\t\t.setSelection(createCollapsedSelection(block.id, sel.anchor.offset))\n\t\t.build();\n}\n\n/** Handles Cmd+Backspace: delete to start of line/block. */\nexport function deleteSoftLineBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tif (sel.anchor.offset === 0) {\n\t\treturn mergeBlockBackward(state);\n\t}\n\n\treturn state\n\t\t.transaction('input')\n\t\t.deleteTextAt(block.id, 0, sel.anchor.offset)\n\t\t.setSelection(createCollapsedSelection(block.id, 0))\n\t\t.build();\n}\n\n/** Handles Cmd+Delete: delete to end of line/block. */\nexport function deleteSoftLineForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (!isCollapsed(sel)) {\n\t\treturn deleteSelectionCommand(state);\n\t}\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\n\tconst blockLen = getBlockLength(block);\n\tif (sel.anchor.offset === blockLen) {\n\t\treturn mergeBlockForward(state);\n\t}\n\n\treturn state\n\t\t.transaction('input')\n\t\t.deleteTextAt(block.id, sel.anchor.offset, blockLen)\n\t\t.setSelection(createCollapsedSelection(block.id, sel.anchor.offset))\n\t\t.build();\n}\n\n/** Splits the current block at the cursor position (Enter key). */\nexport function splitBlockCommand(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tconst builder = state.transaction('input');\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst blockId = isCollapsed(sel)\n\t\t? sel.anchor.blockId\n\t\t: selectionRange(sel, state.getBlockOrder()).from.blockId;\n\tconst offset = isCollapsed(sel)\n\t\t? sel.anchor.offset\n\t\t: selectionRange(sel, state.getBlockOrder()).from.offset;\n\n\tconst newBlockId = generateBlockId();\n\n\t// splitBlock operates at the same level in the tree — the StepApplication\n\t// handles this correctly because it looks up the block by ID recursively.\n\tbuilder.splitBlock(blockId, offset, newBlockId);\n\tbuilder.setSelection(createCollapsedSelection(newBlockId, 0));\n\n\treturn builder.build();\n}\n\n/** Checks whether two blocks share the same parent in the document tree. */\nexport function sharesParent(state: EditorState, blockIdA: BlockId, blockIdB: BlockId): boolean {\n\tconst pathA = state.getNodePath(blockIdA);\n\tconst pathB = state.getNodePath(blockIdB);\n\tif (!pathA || !pathB) return false;\n\tif (pathA.length !== pathB.length) return false;\n\t// Compare parent paths (all but last element)\n\tfor (let i = 0; i < pathA.length - 1; i++) {\n\t\tif (pathA[i] !== pathB[i]) return false;\n\t}\n\treturn true;\n}\n\n/** Checks whether a block is inside an isolating node (e.g. table_cell). */\nexport function isInsideIsolating(state: EditorState, blockId: BlockId): boolean {\n\tconst getNodeSpec = state.schema.getNodeSpec;\n\tif (!getNodeSpec) return false;\n\tconst path = state.getNodePath(blockId);\n\tif (!path || path.length <= 1) return false;\n\n\t// Check ancestors (not the block itself)\n\tfor (let i = 0; i < path.length - 1; i++) {\n\t\tconst ancestorId = path[i];\n\t\tif (!ancestorId) continue;\n\t\tconst ancestor = state.getBlock(ancestorId);\n\t\tif (!ancestor) continue;\n\t\tconst spec = getNodeSpec(ancestor.type);\n\t\tif (spec?.isolating) return true;\n\t}\n\treturn false;\n}\n\n/** Merges the current block with the previous block, respecting isolating boundaries. */\nexport function mergeBlockBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx <= 0) return null;\n\n\tconst prevBlockId = blockOrder[blockIdx - 1];\n\tif (!prevBlockId) return null;\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, prevBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\tconst prevBlock = state.getBlock(prevBlockId);\n\tif (!prevBlock) return null;\n\tconst prevLen = getBlockLength(prevBlock);\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(prevBlockId, sel.anchor.blockId)\n\t\t.setSelection(createCollapsedSelection(prevBlockId, prevLen))\n\t\t.build();\n}\n\n/** Merges the next block into the current block, respecting isolating boundaries. */\nfunction mergeBlockForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx >= blockOrder.length - 1) return null;\n\n\tconst nextBlockId = blockOrder[blockIdx + 1];\n\tif (!nextBlockId) return null;\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, nextBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(sel.anchor.blockId, nextBlockId)\n\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, sel.anchor.offset))\n\t\t.build();\n}\n\n/** Selects all content in the editor. */\nexport function selectAll(state: EditorState): Transaction {\n\tconst blocks = state.doc.children;\n\tconst firstBlock = blocks[0];\n\tconst lastBlock = blocks[blocks.length - 1];\n\tif (!firstBlock || !lastBlock)\n\t\treturn state.transaction('command').setSelection(state.selection).build();\n\tconst lastBlockLen = getBlockLength(lastBlock);\n\n\treturn state\n\t\t.transaction('command')\n\t\t.setSelection(\n\t\t\tcreateSelection(\n\t\t\t\t{ blockId: firstBlock.id, offset: 0 },\n\t\t\t\t{ blockId: lastBlock.id, offset: lastBlockLen },\n\t\t\t),\n\t\t)\n\t\t.build();\n}\n\n// --- Check Commands ---\n\n/** Checks if a mark is active at the current selection. */\nexport function isMarkActive(state: EditorState, markType: MarkType): boolean {\n\tconst sel = state.selection;\n\n\tif (isCollapsed(sel)) {\n\t\tif (state.storedMarks) {\n\t\t\treturn hasMark(state.storedMarks, markType);\n\t\t}\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\treturn hasMark(marks, markType);\n\t}\n\n\treturn isMarkActiveInRange(state, markType);\n}\n\n// --- Internal Helpers ---\n\nfunction resolveActiveMarks(state: EditorState): readonly Mark[] {\n\tif (state.storedMarks) return state.storedMarks;\n\n\tconst block = state.getBlock(state.selection.anchor.blockId);\n\tif (!block) return [];\n\n\treturn getBlockMarksAtOffset(block, state.selection.anchor.offset);\n}\n\nexport function addDeleteSelectionSteps(state: EditorState, builder: TransactionBuilder): void {\n\tconst blockOrder = state.getBlockOrder();\n\tconst range = selectionRange(state.selection, blockOrder);\n\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\tif (fromIdx === toIdx) {\n\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, range.to.offset);\n\t} else {\n\t\tconst firstBlock = state.getBlock(range.from.blockId);\n\t\tif (!firstBlock) return;\n\t\tconst firstLen = getBlockLength(firstBlock);\n\n\t\t// Delete from the end of first block\n\t\tif (range.from.offset < firstLen) {\n\t\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, firstLen);\n\t\t}\n\n\t\t// Delete from start of last block\n\t\tif (range.to.offset > 0) {\n\t\t\tbuilder.deleteTextAt(range.to.blockId, 0, range.to.offset);\n\t\t}\n\n\t\t// Delete middle blocks entirely and merge last into first\n\t\tfor (let i = fromIdx + 1; i < toIdx; i++) {\n\t\t\tconst midBlockId = blockOrder[i];\n\t\t\tif (!midBlockId) continue;\n\t\t\tconst midBlock = state.getBlock(midBlockId);\n\t\t\tif (!midBlock) continue;\n\t\t\tconst midLen = getBlockLength(midBlock);\n\t\t\tif (midLen > 0) {\n\t\t\t\tbuilder.deleteTextAt(midBlockId, 0, midLen);\n\t\t\t}\n\t\t\tbuilder.mergeBlocksAt(range.from.blockId, midBlockId);\n\t\t}\n\n\t\t// Merge last block into first\n\t\tbuilder.mergeBlocksAt(range.from.blockId, range.to.blockId);\n\t}\n}\n\n/**\n * Finds the word boundary backward from the given offset.\n * InlineNodes act as word boundaries.\n */\nfunction findWordBoundaryBackward(block: BlockNode, offset: number): number {\n\tlet pos = offset - 1;\n\t// Skip trailing whitespace\n\twhile (pos >= 0) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (!content || content.kind === 'inline') break;\n\t\tif (!/\\s/.test(content.char)) break;\n\t\tpos--;\n\t}\n\t// If at InlineNode, delete just it (treat as word boundary)\n\tif (pos >= 0) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (content?.kind === 'inline') return pos;\n\t}\n\t// Skip word characters until whitespace or InlineNode\n\twhile (pos >= 0) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (!content || content.kind === 'inline') break;\n\t\tif (/\\s/.test(content.char)) break;\n\t\tpos--;\n\t}\n\treturn pos + 1;\n}\n\n/**\n * Finds the word boundary forward from the given offset.\n * InlineNodes act as word boundaries.\n */\nfunction findWordBoundaryForward(block: BlockNode, offset: number): number {\n\tconst len = getBlockLength(block);\n\tlet pos = offset;\n\t// Skip word characters first\n\twhile (pos < len) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (!content || content.kind === 'inline') break;\n\t\tif (/\\s/.test(content.char)) break;\n\t\tpos++;\n\t}\n\t// If at InlineNode and haven't moved, delete just the InlineNode\n\tif (pos === offset && pos < len) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (content?.kind === 'inline') return pos + 1;\n\t}\n\t// Skip trailing whitespace\n\twhile (pos < len) {\n\t\tconst content = getContentAtOffset(block, pos);\n\t\tif (!content || content.kind === 'inline') break;\n\t\tif (!/\\s/.test(content.char)) break;\n\t\tpos++;\n\t}\n\treturn pos;\n}\n\nfunction isFeatureGated(type: MarkType, features: FeatureConfig): boolean {\n\tconst key = type as string;\n\tif (key === 'bold') return !features.bold;\n\tif (key === 'italic') return !features.italic;\n\tif (key === 'underline') return !features.underline;\n\treturn false;\n}\n","/**\n * Keyboard handler: intercepts keydown events for shortcuts.\n * Checks plugin-registered keymaps first, then falls back to built-in\n * structural shortcuts (undo, redo, select all).\n *\n * Mark-specific shortcuts (Mod-B, Mod-I, Mod-U) are registered by\n * their respective plugins via keymaps, not hardcoded here.\n */\n\nimport { selectAll } from '../commands/Commands.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { DispatchFn, GetStateFn, RedoFn, UndoFn } from './InputHandler.js';\n\nexport interface KeyboardHandlerOptions {\n\tgetState: GetStateFn;\n\tdispatch: DispatchFn;\n\tundo: UndoFn;\n\tredo: RedoFn;\n\tschemaRegistry?: SchemaRegistry;\n}\n\nexport class KeyboardHandler {\n\tprivate readonly getState: GetStateFn;\n\tprivate readonly dispatch: DispatchFn;\n\tprivate readonly undo: UndoFn;\n\tprivate readonly redo: RedoFn;\n\tprivate readonly schemaRegistry?: SchemaRegistry;\n\tprivate readonly handleKeydown: (e: KeyboardEvent) => void;\n\n\tconstructor(\n\t\tprivate readonly element: HTMLElement,\n\t\toptions: KeyboardHandlerOptions,\n\t) {\n\t\tthis.getState = options.getState;\n\t\tthis.dispatch = options.dispatch;\n\t\tthis.undo = options.undo;\n\t\tthis.redo = options.redo;\n\t\tthis.schemaRegistry = options.schemaRegistry;\n\n\t\tthis.handleKeydown = this.onKeydown.bind(this);\n\t\telement.addEventListener('keydown', this.handleKeydown);\n\t}\n\n\tprivate onKeydown(e: KeyboardEvent): void {\n\t\t// Try plugin keymaps first (last registered has highest precedence)\n\t\tif (this.schemaRegistry) {\n\t\t\tconst descriptor = normalizeKeyDescriptor(e);\n\t\t\tconst keymaps = this.schemaRegistry.getKeymaps();\n\t\t\t// Iterate in reverse so later-registered keymaps take precedence\n\t\t\tfor (let i = keymaps.length - 1; i >= 0; i--) {\n\t\t\t\tconst handler = keymaps[i]?.[descriptor];\n\t\t\t\tif (handler?.()) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fall back to built-in structural shortcuts\n\t\tconst mod = e.metaKey || e.ctrlKey;\n\t\tif (!mod) return;\n\n\t\tconst key = e.key.toLowerCase();\n\t\tconst state = this.getState();\n\t\tlet tr: Transaction | null = null;\n\n\t\tif (key === 'z' && !e.shiftKey) {\n\t\t\te.preventDefault();\n\t\t\tthis.undo();\n\t\t\treturn;\n\t\t}\n\n\t\tif ((key === 'z' && e.shiftKey) || (key === 'y' && !e.shiftKey)) {\n\t\t\te.preventDefault();\n\t\t\tthis.redo();\n\t\t\treturn;\n\t\t}\n\n\t\tif (key === 'a' && !e.shiftKey) {\n\t\t\te.preventDefault();\n\t\t\ttr = selectAll(state);\n\t\t}\n\n\t\tif (tr) {\n\t\t\tthis.dispatch(tr);\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.element.removeEventListener('keydown', this.handleKeydown);\n\t}\n}\n\n/**\n * Normalizes a KeyboardEvent into a consistent key descriptor string.\n * Format: `\"Mod-Shift-Alt-Key\"` where Mod = Ctrl/Cmd.\n */\nexport function normalizeKeyDescriptor(e: KeyboardEvent): string {\n\tconst parts: string[] = [];\n\tif (e.metaKey || e.ctrlKey) parts.push('Mod');\n\tif (e.shiftKey) parts.push('Shift');\n\tif (e.altKey) parts.push('Alt');\n\n\tlet key = e.key;\n\t// Normalize common keys\n\tif (key === ' ') key = 'Space';\n\telse if (key.length === 1) key = key.toUpperCase();\n\t// For special keys like Enter, Tab, Backspace, keep as-is\n\n\tparts.push(key);\n\treturn parts.join('-');\n}\n","/**\n * Plugin system types for the Notectl editor.\n */\n\nimport type { DecorationSet } from '../decorations/Decoration.js';\nimport type { InputRule } from '../input/InputRule.js';\nimport type { Keymap } from '../input/Keymap.js';\nimport type { InlineNodeSpec } from '../model/InlineNodeSpec.js';\nimport type { MarkSpec } from '../model/MarkSpec.js';\nimport type { NodeSpec } from '../model/NodeSpec.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { NodeViewFactory } from '../view/NodeView.js';\nimport type { ToolbarItem } from './toolbar/ToolbarItem.js';\n\n// --- Type-Safe Keys ---\n\n/** Type-safe event key for compile-time payload checking. */\nexport class EventKey<T> {\n\tdeclare readonly _type: T;\n\tconstructor(public readonly id: string) {}\n}\n\n/** Type-safe service key for compile-time type checking. */\nexport class ServiceKey<T> {\n\tdeclare readonly _type: T;\n\tconstructor(public readonly id: string) {}\n}\n\n// --- Command System ---\n\nexport type CommandHandler = () => boolean;\n\nexport interface CommandEntry {\n\treadonly name: string;\n\treadonly handler: CommandHandler;\n\treadonly pluginId: string;\n}\n\n// --- Event System ---\n\nexport type PluginEventCallback<T = unknown> = (payload: T) => void;\n\nexport interface PluginEventBus {\n\temit<T>(key: EventKey<T>, payload: T): void;\n\ton<T>(key: EventKey<T>, callback: PluginEventCallback<T>): () => void;\n\toff<T>(key: EventKey<T>, callback: PluginEventCallback<T>): void;\n}\n\n// --- Configuration ---\n\nexport type PluginConfig = Record<string, unknown>;\n\n// --- Middleware ---\n\nexport type MiddlewareNext = (tr: Transaction) => void;\nexport type TransactionMiddleware = (\n\ttr: Transaction,\n\tstate: EditorState,\n\tnext: MiddlewareNext,\n) => void;\n\n// --- Plugin Context ---\n\nexport interface PluginContext {\n\tgetState(): EditorState;\n\tdispatch(transaction: Transaction): void;\n\tgetContainer(): HTMLElement;\n\tgetPluginContainer(position: 'top' | 'bottom'): HTMLElement;\n\tregisterCommand(name: string, handler: CommandHandler): void;\n\texecuteCommand(name: string): boolean;\n\tgetEventBus(): PluginEventBus;\n\tregisterMiddleware(middleware: TransactionMiddleware, priority?: number): void;\n\tregisterService<T>(key: ServiceKey<T>, service: T): void;\n\tgetService<T>(key: ServiceKey<T>): T | undefined;\n\tupdateConfig(config: PluginConfig): void;\n\n\t// --- Schema Extension ---\n\tregisterNodeSpec<T extends string>(spec: NodeSpec<T>): void;\n\tregisterMarkSpec<T extends string>(spec: MarkSpec<T>): void;\n\tregisterNodeView(type: string, factory: NodeViewFactory): void;\n\tregisterKeymap(keymap: Keymap): void;\n\tregisterInputRule(rule: InputRule): void;\n\tregisterToolbarItem(item: ToolbarItem): void;\n\tregisterInlineNodeSpec<T extends string>(spec: InlineNodeSpec<T>): void;\n\tgetSchemaRegistry(): SchemaRegistry;\n}\n\n// --- Plugin Interface ---\n\nexport interface Plugin<TConfig extends Record<string, unknown> = Record<string, unknown>> {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly priority?: number;\n\treadonly dependencies?: readonly string[];\n\n\tinit(context: PluginContext): void | Promise<void>;\n\tdestroy?(): void | Promise<void>;\n\tonStateChange?(oldState: EditorState, newState: EditorState, tr: Transaction): void;\n\tonConfigure?(config: TConfig): void;\n\t/** Called after ALL plugins have been initialized. */\n\tonReady?(): void | Promise<void>;\n\t/**\n\t * Returns decorations for the given state.\n\t * Called after state.apply() but BEFORE reconciliation.\n\t * Plugins should cache and only recompute when needed.\n\t */\n\tdecorations?(state: EditorState, tr?: Transaction): DecorationSet;\n}\n","/**\n * Standalone event bus with error isolation and type-safe event keys.\n * Each listener is wrapped in try/catch — a failing listener never affects others.\n */\n\nimport type { EventKey, PluginEventCallback } from './Plugin.js';\n\nexport class EventBus {\n\tprivate readonly listeners = new Map<string, Set<PluginEventCallback>>();\n\n\t/** Emits an event to all registered listeners. Errors are caught per listener. */\n\temit<T>(key: EventKey<T>, payload: T): void {\n\t\tconst set = this.listeners.get(key.id);\n\t\tif (!set) return;\n\n\t\tfor (const listener of set) {\n\t\t\ttry {\n\t\t\t\tlistener(payload);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[EventBus] Listener error on \"${key.id}\":`, err);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Subscribes to an event. Returns an unsubscribe function. */\n\ton<T>(key: EventKey<T>, callback: PluginEventCallback<T>): () => void {\n\t\tconst id = key.id;\n\t\tif (!this.listeners.has(id)) {\n\t\t\tthis.listeners.set(id, new Set());\n\t\t}\n\t\tconst set = this.listeners.get(id) ?? new Set();\n\t\tset.add(callback as PluginEventCallback);\n\n\t\treturn () => {\n\t\t\tset.delete(callback as PluginEventCallback);\n\t\t\tif (set.size === 0) this.listeners.delete(id);\n\t\t};\n\t}\n\n\t/** Removes a specific listener from an event. */\n\toff<T>(key: EventKey<T>, callback: PluginEventCallback<T>): void {\n\t\tconst set = this.listeners.get(key.id);\n\t\tif (!set) return;\n\t\tset.delete(callback as PluginEventCallback);\n\t\tif (set.size === 0) this.listeners.delete(key.id);\n\t}\n\n\t/** Removes all listeners for all events. */\n\tclear(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n","/**\n * Pure functions for mapping decorations through transaction steps.\n * Handles position adjustments when the document changes — insertions,\n * deletions, splits, merges, and structural node removal.\n */\n\nimport type {\n\tDeleteTextStep,\n\tInsertTextStep,\n\tMergeBlocksStep,\n\tRemoveNodeStep,\n\tSplitBlockStep,\n\tStep,\n} from '../state/Transaction.js';\nimport type {\n\tDecoration,\n\tInlineDecoration,\n\tNodeDecoration,\n\tWidgetDecoration,\n} from './Decoration.js';\n\n/**\n * Maps a single decoration through a step.\n * Returns the mapped decoration, an array (when a split produces two),\n * or null if the decoration was deleted by the step.\n */\nexport function mapDecorationThroughStep(\n\tdeco: Decoration,\n\tstep: Step,\n): Decoration | readonly Decoration[] | null {\n\tswitch (deco.type) {\n\t\tcase 'inline':\n\t\t\treturn mapInline(deco, step);\n\t\tcase 'widget':\n\t\t\treturn mapWidget(deco, step);\n\t\tcase 'node':\n\t\t\treturn mapNode(deco, step);\n\t}\n}\n\nfunction mapInline(\n\tdeco: InlineDecoration,\n\tstep: Step,\n): InlineDecoration | readonly InlineDecoration[] | null {\n\tswitch (step.type) {\n\t\tcase 'insertText':\n\t\t\treturn mapInlineInsert(deco, step);\n\t\tcase 'deleteText':\n\t\t\treturn mapInlineDelete(deco, step);\n\t\tcase 'splitBlock':\n\t\t\treturn mapInlineSplit(deco, step);\n\t\tcase 'mergeBlocks':\n\t\t\treturn mapInlineMerge(deco, step);\n\t\tcase 'removeNode':\n\t\t\treturn removeIfBlockDeleted(deco, step);\n\t\tdefault:\n\t\t\treturn deco;\n\t}\n}\n\nfunction mapWidget(deco: WidgetDecoration, step: Step): WidgetDecoration | null {\n\tswitch (step.type) {\n\t\tcase 'insertText':\n\t\t\treturn mapWidgetInsert(deco, step);\n\t\tcase 'deleteText':\n\t\t\treturn mapWidgetDelete(deco, step);\n\t\tcase 'splitBlock':\n\t\t\treturn mapWidgetSplit(deco, step);\n\t\tcase 'mergeBlocks':\n\t\t\treturn mapWidgetMerge(deco, step);\n\t\tcase 'removeNode':\n\t\t\treturn removeIfBlockDeleted(deco, step);\n\t\tdefault:\n\t\t\treturn deco;\n\t}\n}\n\nfunction mapNode(deco: NodeDecoration, step: Step): NodeDecoration | null {\n\tswitch (step.type) {\n\t\tcase 'mergeBlocks':\n\t\t\treturn mapNodeMerge(deco, step);\n\t\tcase 'removeNode':\n\t\t\treturn removeIfBlockDeleted(deco, step);\n\t\tdefault:\n\t\t\treturn deco;\n\t}\n}\n\n// --- InsertText ---\n\nfunction mapInlineInsert(deco: InlineDecoration, step: InsertTextStep): InlineDecoration {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\tconst len: number = step.text.length;\n\t// from: assoc=-1 (stays at boundary — only shifts if insertion is strictly before)\n\tconst newFrom: number = deco.from > step.offset ? deco.from + len : deco.from;\n\t// to: assoc=1 (moves past insertion — shifts if insertion is at or before)\n\tconst newTo: number = deco.to >= step.offset ? deco.to + len : deco.to;\n\n\tif (newFrom === deco.from && newTo === deco.to) return deco;\n\treturn { ...deco, from: newFrom, to: newTo };\n}\n\nfunction mapWidgetInsert(deco: WidgetDecoration, step: InsertTextStep): WidgetDecoration {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\tconst len: number = step.text.length;\n\t// At boundary: side=-1 means \"before insertion\" (assoc=-1, stays), side=1 means \"after\" (moves)\n\tif (deco.offset > step.offset) {\n\t\treturn { ...deco, offset: deco.offset + len };\n\t}\n\tif (deco.offset === step.offset && deco.side >= 1) {\n\t\treturn { ...deco, offset: deco.offset + len };\n\t}\n\treturn deco;\n}\n\n// --- DeleteText ---\n\nfunction mapInlineDelete(deco: InlineDecoration, step: DeleteTextStep): InlineDecoration | null {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\tconst delLen: number = step.to - step.from;\n\tconst newFrom: number = clampAndShift(deco.from, step.from, step.to, delLen);\n\tconst newTo: number = clampAndShift(deco.to, step.from, step.to, delLen);\n\n\tif (newFrom >= newTo) return null;\n\tif (newFrom === deco.from && newTo === deco.to) return deco;\n\treturn { ...deco, from: newFrom, to: newTo };\n}\n\nfunction mapWidgetDelete(deco: WidgetDecoration, step: DeleteTextStep): WidgetDecoration | null {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\t// Widget strictly inside deleted range → deleted\n\tif (deco.offset > step.from && deco.offset < step.to) return null;\n\n\tconst delLen: number = step.to - step.from;\n\tif (deco.offset >= step.to) {\n\t\treturn { ...deco, offset: deco.offset - delLen };\n\t}\n\treturn deco;\n}\n\n// --- SplitBlock ---\n\nfunction mapInlineSplit(\n\tdeco: InlineDecoration,\n\tstep: SplitBlockStep,\n): InlineDecoration | readonly InlineDecoration[] {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\t// Entirely before split point → unchanged\n\tif (deco.to <= step.offset) return deco;\n\n\t// Entirely after split point → move to new block, adjust offsets\n\tif (deco.from >= step.offset) {\n\t\treturn {\n\t\t\t...deco,\n\t\t\tblockId: step.newBlockId,\n\t\t\tfrom: deco.from - step.offset,\n\t\t\tto: deco.to - step.offset,\n\t\t};\n\t}\n\n\t// Spanning the split point → split into two decorations\n\tconst left: InlineDecoration = { ...deco, to: step.offset };\n\tconst right: InlineDecoration = {\n\t\t...deco,\n\t\tblockId: step.newBlockId,\n\t\tfrom: 0,\n\t\tto: deco.to - step.offset,\n\t};\n\treturn [left, right];\n}\n\nfunction mapWidgetSplit(deco: WidgetDecoration, step: SplitBlockStep): WidgetDecoration {\n\tif (deco.blockId !== step.blockId) return deco;\n\n\t// Before split → stays\n\tif (deco.offset < step.offset) return deco;\n\n\t// After split → new block\n\tif (deco.offset > step.offset) {\n\t\treturn {\n\t\t\t...deco,\n\t\t\tblockId: step.newBlockId,\n\t\t\toffset: deco.offset - step.offset,\n\t\t};\n\t}\n\n\t// At boundary: side determines which block\n\tif (deco.side >= 1) {\n\t\treturn {\n\t\t\t...deco,\n\t\t\tblockId: step.newBlockId,\n\t\t\toffset: 0,\n\t\t};\n\t}\n\treturn deco;\n}\n\n// --- MergeBlocks ---\n\nfunction mapInlineMerge(deco: InlineDecoration, step: MergeBlocksStep): InlineDecoration {\n\tif (deco.blockId !== step.sourceBlockId) return deco;\n\n\treturn {\n\t\t...deco,\n\t\tblockId: step.targetBlockId,\n\t\tfrom: deco.from + step.targetLengthBefore,\n\t\tto: deco.to + step.targetLengthBefore,\n\t};\n}\n\nfunction mapWidgetMerge(deco: WidgetDecoration, step: MergeBlocksStep): WidgetDecoration {\n\tif (deco.blockId !== step.sourceBlockId) return deco;\n\n\treturn {\n\t\t...deco,\n\t\tblockId: step.targetBlockId,\n\t\toffset: deco.offset + step.targetLengthBefore,\n\t};\n}\n\nfunction mapNodeMerge(deco: NodeDecoration, step: MergeBlocksStep): NodeDecoration | null {\n\t// Source block disappears → delete its node decoration\n\tif (deco.blockId === step.sourceBlockId) return null;\n\treturn deco;\n}\n\n// --- RemoveNode ---\n\nfunction removeIfBlockDeleted<T extends Decoration>(deco: T, step: RemoveNodeStep): T | null {\n\tif (deco.blockId === step.removedNode.id) return null;\n\treturn deco;\n}\n\n// --- Helpers ---\n\nfunction clampAndShift(pos: number, delFrom: number, delTo: number, delLen: number): number {\n\tif (pos <= delFrom) return pos;\n\tif (pos >= delTo) return pos - delLen;\n\treturn delFrom;\n}\n","/**\n * Decoration types and DecorationSet for transient, view-only annotations.\n * Decorations are NOT part of the document model and do NOT affect undo/redo.\n */\n\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { mapDecorationThroughStep } from './PositionMapping.js';\n\n// --- Decoration Attrs ---\n\nexport interface DecorationAttrs {\n\treadonly class?: string;\n\treadonly style?: string;\n\treadonly nodeName?: string;\n\treadonly [key: string]: string | undefined;\n}\n\n// --- Decoration Types ---\n\nexport interface InlineDecoration {\n\treadonly type: 'inline';\n\treadonly blockId: BlockId;\n\treadonly from: number;\n\treadonly to: number;\n\treadonly attrs: DecorationAttrs;\n}\n\nexport interface NodeDecoration {\n\treadonly type: 'node';\n\treadonly blockId: BlockId;\n\treadonly attrs: DecorationAttrs;\n}\n\nexport interface WidgetDecoration {\n\treadonly type: 'widget';\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\treadonly toDOM: () => HTMLElement;\n\treadonly side: -1 | 1;\n\treadonly key?: string;\n}\n\nexport type Decoration = InlineDecoration | NodeDecoration | WidgetDecoration;\n\n// --- Factory Functions ---\n\n/** Creates an inline decoration for a text range within a block. */\nexport function inline(\n\tblockId: BlockId,\n\tfrom: number,\n\tto: number,\n\tattrs: DecorationAttrs,\n): InlineDecoration {\n\treturn { type: 'inline', blockId, from, to, attrs };\n}\n\n/** Creates a node decoration that applies to a whole block element. */\nexport function node(blockId: BlockId, attrs: DecorationAttrs): NodeDecoration {\n\treturn { type: 'node', blockId, attrs };\n}\n\n/** Creates a widget decoration that inserts a DOM element at a position. */\nexport function widget(\n\tblockId: BlockId,\n\toffset: number,\n\ttoDOM: () => HTMLElement,\n\toptions?: { readonly side?: -1 | 1; readonly key?: string },\n): WidgetDecoration {\n\treturn {\n\t\ttype: 'widget',\n\t\tblockId,\n\t\toffset,\n\t\ttoDOM,\n\t\tside: options?.side ?? -1,\n\t\tkey: options?.key,\n\t};\n}\n\n// --- DecorationSet ---\n\n/**\n * Immutable set of decorations indexed by block ID.\n * Provides efficient lookup and merging of decoration collections.\n */\nexport class DecorationSet {\n\tstatic readonly empty: DecorationSet = new DecorationSet(new Map());\n\n\tprivate constructor(private readonly byBlock: ReadonlyMap<BlockId, readonly Decoration[]>) {}\n\n\t/** Creates a DecorationSet from a flat array of decorations. */\n\tstatic create(decorations: readonly Decoration[]): DecorationSet {\n\t\tif (decorations.length === 0) return DecorationSet.empty;\n\n\t\tconst map = new Map<BlockId, Decoration[]>();\n\t\tfor (const deco of decorations) {\n\t\t\tconst existing = map.get(deco.blockId);\n\t\t\tif (existing) {\n\t\t\t\texisting.push(deco);\n\t\t\t} else {\n\t\t\t\tmap.set(deco.blockId, [deco]);\n\t\t\t}\n\t\t}\n\t\treturn new DecorationSet(map);\n\t}\n\n\t/** Returns all decorations for a given block. */\n\tfind(blockId: BlockId): readonly Decoration[] {\n\t\treturn this.byBlock.get(blockId) ?? [];\n\t}\n\n\t/** Returns only inline decorations for a given block. */\n\tfindInline(blockId: BlockId): readonly InlineDecoration[] {\n\t\tconst decos = this.byBlock.get(blockId);\n\t\tif (!decos) return [];\n\t\treturn decos.filter((d): d is InlineDecoration => d.type === 'inline');\n\t}\n\n\t/** Returns only node decorations for a given block. */\n\tfindNode(blockId: BlockId): readonly NodeDecoration[] {\n\t\tconst decos = this.byBlock.get(blockId);\n\t\tif (!decos) return [];\n\t\treturn decos.filter((d): d is NodeDecoration => d.type === 'node');\n\t}\n\n\t/** Returns only widget decorations for a given block. */\n\tfindWidget(blockId: BlockId): readonly WidgetDecoration[] {\n\t\tconst decos = this.byBlock.get(blockId);\n\t\tif (!decos) return [];\n\t\treturn decos.filter((d): d is WidgetDecoration => d.type === 'widget');\n\t}\n\n\t/** Returns a new DecorationSet with the given decorations added. */\n\tadd(decorations: readonly Decoration[]): DecorationSet {\n\t\tif (decorations.length === 0) return this;\n\t\tif (this.isEmpty) return DecorationSet.create(decorations);\n\n\t\tconst map = new Map<BlockId, Decoration[]>();\n\t\tfor (const [bid, decos] of this.byBlock) {\n\t\t\tmap.set(bid, [...decos]);\n\t\t}\n\t\tfor (const deco of decorations) {\n\t\t\tconst existing = map.get(deco.blockId);\n\t\t\tif (existing) {\n\t\t\t\texisting.push(deco);\n\t\t\t} else {\n\t\t\t\tmap.set(deco.blockId, [deco]);\n\t\t\t}\n\t\t}\n\t\treturn new DecorationSet(map);\n\t}\n\n\t/** Returns a new DecorationSet with decorations matching the predicate removed. */\n\tremove(predicate: (d: Decoration) => boolean): DecorationSet {\n\t\tconst map = new Map<BlockId, Decoration[]>();\n\t\tlet changed = false;\n\n\t\tfor (const [bid, decos] of this.byBlock) {\n\t\t\tconst filtered = decos.filter((d) => !predicate(d));\n\t\t\tif (filtered.length !== decos.length) changed = true;\n\t\t\tif (filtered.length > 0) {\n\t\t\t\tmap.set(bid, filtered);\n\t\t\t}\n\t\t}\n\n\t\tif (!changed) return this;\n\t\tif (map.size === 0) return DecorationSet.empty;\n\t\treturn new DecorationSet(map);\n\t}\n\n\t/** Returns a new DecorationSet merging this set with another. */\n\tmerge(other: DecorationSet): DecorationSet {\n\t\tif (other.isEmpty) return this;\n\t\tif (this.isEmpty) return other;\n\n\t\tconst map = new Map<BlockId, Decoration[]>();\n\t\tfor (const [bid, decos] of this.byBlock) {\n\t\t\tmap.set(bid, [...decos]);\n\t\t}\n\t\tfor (const [bid, decos] of other.byBlock) {\n\t\t\tconst existing = map.get(bid);\n\t\t\tif (existing) {\n\t\t\t\texisting.push(...decos);\n\t\t\t} else {\n\t\t\t\tmap.set(bid, [...decos]);\n\t\t\t}\n\t\t}\n\t\treturn new DecorationSet(map);\n\t}\n\n\t/** Checks equality — reference first, then structural comparison. */\n\tequals(other: DecorationSet): boolean {\n\t\tif (this === other) return true;\n\t\tif (this.byBlock.size !== other.byBlock.size) return false;\n\n\t\tfor (const [bid, decos] of this.byBlock) {\n\t\t\tconst otherDecos = other.byBlock.get(bid);\n\t\t\tif (!otherDecos) return false;\n\t\t\tif (!decorationArraysEqual(decos, otherDecos)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** True if the set contains no decorations. */\n\tget isEmpty(): boolean {\n\t\treturn this.byBlock.size === 0;\n\t}\n\n\t/**\n\t * Maps decorations through document changes described by a transaction.\n\t * Decorations that become invalid (e.g. fully deleted range) are removed.\n\t * Decorations that span a split point are split into two.\n\t */\n\tmap(tr: Transaction): DecorationSet {\n\t\tif (this.isEmpty || tr.steps.length === 0) return this;\n\n\t\tlet mapped: Decoration[] = [];\n\t\tfor (const decos of this.byBlock.values()) {\n\t\t\tfor (const d of decos) {\n\t\t\t\tmapped.push(d);\n\t\t\t}\n\t\t}\n\n\t\tfor (const step of tr.steps) {\n\t\t\tconst next: Decoration[] = [];\n\t\t\tfor (const deco of mapped) {\n\t\t\t\tconst result = mapDecorationThroughStep(deco, step);\n\t\t\t\tif (result === null) continue;\n\t\t\t\tif (Array.isArray(result)) {\n\t\t\t\t\tfor (const r of result) {\n\t\t\t\t\t\tnext.push(r);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnext.push(result as Decoration);\n\t\t\t\t}\n\t\t\t}\n\t\t\tmapped = next;\n\t\t}\n\n\t\tif (mapped.length === 0) return DecorationSet.empty;\n\t\treturn DecorationSet.create(mapped);\n\t}\n}\n\n// --- Helpers ---\n\n/** Compares two decoration arrays for structural equality. */\nexport function decorationArraysEqual(a: readonly Decoration[], b: readonly Decoration[]): boolean {\n\tif (a === b) return true;\n\tif (a.length !== b.length) return false;\n\n\tfor (let i = 0; i < a.length; i++) {\n\t\tconst ai = a[i];\n\t\tconst bi = b[i];\n\t\tif (!ai || !bi || !decorationsEqual(ai, bi)) return false;\n\t}\n\treturn true;\n}\n\n/** Compares two individual decorations for structural equality. */\nfunction decorationsEqual(a: Decoration, b: Decoration): boolean {\n\tif (a.type !== b.type) return false;\n\tif (a.blockId !== b.blockId) return false;\n\n\tswitch (a.type) {\n\t\tcase 'inline': {\n\t\t\tconst bi = b as InlineDecoration;\n\t\t\treturn a.from === bi.from && a.to === bi.to && attrsEqual(a.attrs, bi.attrs);\n\t\t}\n\t\tcase 'node': {\n\t\t\tconst bn = b as NodeDecoration;\n\t\t\treturn attrsEqual(a.attrs, bn.attrs);\n\t\t}\n\t\tcase 'widget': {\n\t\t\tconst bw = b as WidgetDecoration;\n\t\t\treturn (\n\t\t\t\ta.offset === bw.offset && a.side === bw.side && a.key === bw.key && a.toDOM === bw.toDOM\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Compares two DecorationAttrs objects. */\nfunction attrsEqual(a: DecorationAttrs, b: DecorationAttrs): boolean {\n\tif (a === b) return true;\n\tconst aKeys = Object.keys(a);\n\tconst bKeys = Object.keys(b);\n\tif (aKeys.length !== bKeys.length) return false;\n\tfor (const key of aKeys) {\n\t\tif (a[key] !== b[key]) return false;\n\t}\n\treturn true;\n}\n","/**\n * Plugin manager: handles plugin lifecycle, dependency resolution,\n * middleware chain, command/service registries, and error isolation.\n *\n * Per-plugin registration tracking ensures clean teardown —\n * commands, services, middleware, event subscriptions, and schema\n * registrations are automatically cleaned up when a plugin is destroyed.\n */\n\nimport { DecorationSet } from '../decorations/Decoration.js';\nimport type { InputRule } from '../input/InputRule.js';\nimport type { Keymap } from '../input/Keymap.js';\nimport { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { EventBus } from './EventBus.js';\nimport type {\n\tCommandEntry,\n\tCommandHandler,\n\tMiddlewareNext,\n\tPlugin,\n\tPluginConfig,\n\tPluginContext,\n\tPluginEventBus,\n\tServiceKey,\n\tTransactionMiddleware,\n} from './Plugin.js';\n\nconst DEFAULT_PRIORITY = 100;\n\ninterface MiddlewareEntry {\n\tmiddleware: TransactionMiddleware;\n\tpriority: number;\n}\n\ninterface PluginRegistrations {\n\tcommands: string[];\n\tservices: string[];\n\tmiddlewares: MiddlewareEntry[];\n\tunsubscribers: (() => void)[];\n\tnodeSpecs: string[];\n\tmarkSpecs: string[];\n\tinlineNodeSpecs: string[];\n\tnodeViews: string[];\n\tkeymaps: Keymap[];\n\tinputRules: InputRule[];\n\ttoolbarItems: string[];\n}\n\nexport interface PluginManagerInitOptions {\n\tgetState(): EditorState;\n\tdispatch(transaction: Transaction): void;\n\tgetContainer(): HTMLElement;\n\tgetPluginContainer(position: 'top' | 'bottom'): HTMLElement;\n\t/** Called after all plugin init() calls complete, before onReady(). */\n\tonBeforeReady?(): void | Promise<void>;\n}\n\nexport class PluginManager {\n\tprivate readonly plugins = new Map<string, Plugin>();\n\tprivate readonly commands = new Map<string, CommandEntry>();\n\tprivate readonly services = new Map<string, unknown>();\n\tprivate readonly middlewares: MiddlewareEntry[] = [];\n\tprivate readonly registrations = new Map<string, PluginRegistrations>();\n\tprivate readonly eventBus = new EventBus();\n\treadonly schemaRegistry = new SchemaRegistry();\n\tprivate middlewareSorted: MiddlewareEntry[] | null = null;\n\tprivate initOrder: string[] = [];\n\tprivate initialized = false;\n\tprivate initializing = false;\n\n\t/** Registers a plugin. Must be called before init(). */\n\tregister(plugin: Plugin): void {\n\t\tif (this.initialized || this.initializing) {\n\t\t\tthrow new Error(`Cannot register plugin \"${plugin.id}\" after initialization.`);\n\t\t}\n\t\tif (this.plugins.has(plugin.id)) {\n\t\t\tthrow new Error(`Plugin \"${plugin.id}\" is already registered.`);\n\t\t}\n\t\tthis.plugins.set(plugin.id, plugin);\n\t}\n\n\t/** Initializes all registered plugins in dependency/priority order. */\n\tasync init(options: PluginManagerInitOptions): Promise<void> {\n\t\tif (this.initialized || this.initializing) return;\n\t\tthis.initializing = true;\n\n\t\tthis.initOrder = this.resolveOrder();\n\n\t\tfor (const id of this.initOrder) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tif (!plugin) continue;\n\t\t\tconst context = this.createContext(id, options);\n\t\t\ttry {\n\t\t\t\tawait plugin.init(context);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[PluginManager] Plugin \"${id}\" failed to initialize:`, err);\n\t\t\t}\n\t\t}\n\n\t\t// Hook between init and onReady — lets the host rebuild schema/state\n\t\t// after all plugins have registered their specs but before plugins render.\n\t\tif (options.onBeforeReady) {\n\t\t\tawait options.onBeforeReady();\n\t\t}\n\n\t\t// Call onReady on all plugins after all init() calls have completed\n\t\tfor (const id of this.initOrder) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tif (!plugin?.onReady) continue;\n\t\t\ttry {\n\t\t\t\tawait plugin.onReady();\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[PluginManager] Plugin \"${id}\" error in onReady:`, err);\n\t\t\t}\n\t\t}\n\n\t\tthis.initialized = true;\n\t\tthis.initializing = false;\n\t}\n\n\t/** Notifies all plugins of a state change, in init order. */\n\tnotifyStateChange(oldState: EditorState, newState: EditorState, tr: Transaction): void {\n\t\tfor (const id of this.initOrder) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tif (!plugin?.onStateChange) continue;\n\t\t\ttry {\n\t\t\t\tplugin.onStateChange(oldState, newState, tr);\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[PluginManager] Plugin \"${id}\" error in onStateChange:`, err);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Collects and merges decorations from all plugins. */\n\tcollectDecorations(state: EditorState, tr?: Transaction): DecorationSet {\n\t\tlet result: DecorationSet = DecorationSet.empty;\n\t\tfor (const id of this.initOrder) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tif (!plugin?.decorations) continue;\n\t\t\ttry {\n\t\t\t\tconst decos = plugin.decorations(state, tr);\n\t\t\t\tif (!decos.isEmpty) {\n\t\t\t\t\tresult = result.merge(decos);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[PluginManager] Plugin \"${id}\" error in decorations():`, err);\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Dispatches a transaction through the middleware chain, then calls the final dispatch.\n\t * If no middleware is registered, calls finalDispatch directly.\n\t */\n\tdispatchWithMiddleware(\n\t\ttr: Transaction,\n\t\tstate: EditorState,\n\t\tfinalDispatch: (tr: Transaction) => void,\n\t): void {\n\t\tif (this.middlewares.length === 0) {\n\t\t\tfinalDispatch(tr);\n\t\t\treturn;\n\t\t}\n\n\t\tconst sorted = this.getSortedMiddleware();\n\t\tlet index = 0;\n\t\tlet dispatched = false;\n\n\t\tconst next: MiddlewareNext = (currentTr) => {\n\t\t\tif (index < sorted.length) {\n\t\t\t\tconst entry = sorted[index++];\n\t\t\t\tif (!entry) return;\n\t\t\t\tlet called = false;\n\t\t\t\tconst guardedNext: MiddlewareNext = (tr) => {\n\t\t\t\t\tif (called) return;\n\t\t\t\t\tcalled = true;\n\t\t\t\t\tnext(tr);\n\t\t\t\t};\n\t\t\t\ttry {\n\t\t\t\t\tentry.middleware(currentTr, state, guardedNext);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error('[PluginManager] Middleware error:', err);\n\t\t\t\t\tguardedNext(currentTr);\n\t\t\t\t}\n\t\t\t} else if (!dispatched) {\n\t\t\t\tdispatched = true;\n\t\t\t\tfinalDispatch(currentTr);\n\t\t\t}\n\t\t};\n\n\t\tnext(tr);\n\t}\n\n\t/** Executes a named command. Returns false if command not found. */\n\texecuteCommand(name: string): boolean {\n\t\tconst entry = this.commands.get(name);\n\t\tif (!entry) return false;\n\t\ttry {\n\t\t\treturn entry.handler();\n\t\t} catch (err) {\n\t\t\tconsole.error(`[PluginManager] Command \"${name}\" error:`, err);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Configures a plugin at runtime via onConfigure(). */\n\tconfigurePlugin(pluginId: string, config: PluginConfig): void {\n\t\tconst plugin = this.plugins.get(pluginId);\n\t\tif (!plugin) {\n\t\t\tthrow new Error(`Plugin \"${pluginId}\" not found.`);\n\t\t}\n\t\tif (!plugin.onConfigure) return;\n\t\ttry {\n\t\t\tplugin.onConfigure(config);\n\t\t} catch (err) {\n\t\t\tconsole.error(`[PluginManager] Plugin \"${pluginId}\" error in onConfigure:`, err);\n\t\t}\n\t}\n\n\t/** Returns all registered plugin IDs. */\n\tgetPluginIds(): string[] {\n\t\treturn [...this.plugins.keys()];\n\t}\n\n\t/** Gets a plugin by ID. */\n\tget(id: string): Plugin | undefined {\n\t\treturn this.plugins.get(id);\n\t}\n\n\t/** Gets a registered service by typed key. */\n\tgetService<T>(key: ServiceKey<T>): T | undefined {\n\t\treturn this.services.get(key.id) as T | undefined;\n\t}\n\n\t/** Destroys all plugins in reverse init order. */\n\tasync destroy(): Promise<void> {\n\t\tconst reversed = [...this.initOrder].reverse();\n\t\tfor (const id of reversed) {\n\t\t\tawait this.destroyPlugin(id);\n\t\t}\n\t\tthis.plugins.clear();\n\t\tthis.commands.clear();\n\t\tthis.services.clear();\n\t\tthis.middlewares.length = 0;\n\t\tthis.middlewareSorted = null;\n\t\tthis.eventBus.clear();\n\t\tthis.registrations.clear();\n\t\tthis.schemaRegistry.clear();\n\t\tthis.initOrder = [];\n\t\tthis.initialized = false;\n\t}\n\n\t// --- Private ---\n\n\tprivate async destroyPlugin(id: string): Promise<void> {\n\t\tconst plugin = this.plugins.get(id);\n\t\tif (plugin?.destroy) {\n\t\t\ttry {\n\t\t\t\tawait plugin.destroy();\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error(`[PluginManager] Plugin \"${id}\" error in destroy:`, err);\n\t\t\t}\n\t\t}\n\t\tthis.cleanupRegistrations(id);\n\t}\n\n\tprivate cleanupRegistrations(id: string): void {\n\t\tconst reg = this.registrations.get(id);\n\t\tif (!reg) return;\n\n\t\tfor (const name of reg.commands) this.commands.delete(name);\n\t\tfor (const serviceId of reg.services) this.services.delete(serviceId);\n\t\tfor (const entry of reg.middlewares) {\n\t\t\tconst idx = this.middlewares.indexOf(entry);\n\t\t\tif (idx !== -1) this.middlewares.splice(idx, 1);\n\t\t}\n\t\tfor (const unsub of reg.unsubscribers) unsub();\n\n\t\t// Clean up schema registrations\n\t\tfor (const type of reg.nodeSpecs) this.schemaRegistry.removeNodeSpec(type);\n\t\tfor (const type of reg.markSpecs) this.schemaRegistry.removeMarkSpec(type);\n\t\tfor (const type of reg.inlineNodeSpecs) {\n\t\t\tthis.schemaRegistry.removeInlineNodeSpec(type);\n\t\t}\n\t\tfor (const type of reg.nodeViews) this.schemaRegistry.removeNodeView(type);\n\t\tfor (const keymap of reg.keymaps) this.schemaRegistry.removeKeymap(keymap);\n\t\tfor (const rule of reg.inputRules) this.schemaRegistry.removeInputRule(rule);\n\t\tfor (const itemId of reg.toolbarItems) this.schemaRegistry.removeToolbarItem(itemId);\n\n\t\tthis.middlewareSorted = null;\n\t\tthis.registrations.delete(id);\n\t}\n\n\tprivate getSortedMiddleware(): MiddlewareEntry[] {\n\t\tif (!this.middlewareSorted) {\n\t\t\tthis.middlewareSorted = [...this.middlewares].sort((a, b) => a.priority - b.priority);\n\t\t}\n\t\treturn this.middlewareSorted;\n\t}\n\n\tprivate createContext(pluginId: string, options: PluginManagerInitOptions): PluginContext {\n\t\tconst reg: PluginRegistrations = {\n\t\t\tcommands: [],\n\t\t\tservices: [],\n\t\t\tmiddlewares: [],\n\t\t\tunsubscribers: [],\n\t\t\tnodeSpecs: [],\n\t\t\tmarkSpecs: [],\n\t\t\tinlineNodeSpecs: [],\n\t\t\tnodeViews: [],\n\t\t\tkeymaps: [],\n\t\t\tinputRules: [],\n\t\t\ttoolbarItems: [],\n\t\t};\n\t\tthis.registrations.set(pluginId, reg);\n\n\t\tconst pluginEventBus: PluginEventBus = {\n\t\t\temit: (key, payload) => this.eventBus.emit(key, payload),\n\t\t\ton: (key, callback) => {\n\t\t\t\tconst unsub = this.eventBus.on(key, callback);\n\t\t\t\treg.unsubscribers.push(unsub);\n\t\t\t\treturn unsub;\n\t\t\t},\n\t\t\toff: (key, callback) => this.eventBus.off(key, callback),\n\t\t};\n\n\t\treturn {\n\t\t\tgetState: options.getState,\n\t\t\tdispatch: options.dispatch,\n\t\t\tgetContainer: options.getContainer,\n\t\t\tgetPluginContainer: options.getPluginContainer,\n\n\t\t\tregisterCommand: (name: string, handler: CommandHandler) => {\n\t\t\t\tif (this.commands.has(name)) {\n\t\t\t\t\tconst existing = this.commands.get(name);\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Command \"${name}\" is already registered by plugin \"${existing?.pluginId}\".`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.commands.set(name, { name, handler, pluginId });\n\t\t\t\treg.commands.push(name);\n\t\t\t},\n\n\t\t\texecuteCommand: (name: string) => this.executeCommand(name),\n\n\t\t\tgetEventBus: () => pluginEventBus,\n\n\t\t\tregisterMiddleware: (middleware: TransactionMiddleware, priority = DEFAULT_PRIORITY) => {\n\t\t\t\tconst entry: MiddlewareEntry = { middleware, priority };\n\t\t\t\tthis.middlewares.push(entry);\n\t\t\t\treg.middlewares.push(entry);\n\t\t\t\tthis.middlewareSorted = null;\n\t\t\t},\n\n\t\t\tregisterService: <T>(key: ServiceKey<T>, service: T) => {\n\t\t\t\tif (this.services.has(key.id)) {\n\t\t\t\t\tthrow new Error(`Service \"${key.id}\" is already registered by another plugin.`);\n\t\t\t\t}\n\t\t\t\tthis.services.set(key.id, service);\n\t\t\t\treg.services.push(key.id);\n\t\t\t},\n\n\t\t\tgetService: <T>(key: ServiceKey<T>) => this.services.get(key.id) as T | undefined,\n\n\t\t\tupdateConfig: (config: PluginConfig) => {\n\t\t\t\tconst plugin = this.plugins.get(pluginId);\n\t\t\t\tif (plugin?.onConfigure) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tplugin.onConfigure(config);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(`[PluginManager] Plugin \"${pluginId}\" error in onConfigure:`, err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// --- Schema Extension Methods ---\n\n\t\t\tregisterNodeSpec: (spec) => {\n\t\t\t\tthis.schemaRegistry.registerNodeSpec(spec);\n\t\t\t\treg.nodeSpecs.push(spec.type);\n\t\t\t},\n\n\t\t\tregisterMarkSpec: (spec) => {\n\t\t\t\tthis.schemaRegistry.registerMarkSpec(spec);\n\t\t\t\treg.markSpecs.push(spec.type);\n\t\t\t},\n\n\t\t\tregisterNodeView: (type, factory) => {\n\t\t\t\tthis.schemaRegistry.registerNodeView(type, factory);\n\t\t\t\treg.nodeViews.push(type);\n\t\t\t},\n\n\t\t\tregisterKeymap: (keymap) => {\n\t\t\t\tthis.schemaRegistry.registerKeymap(keymap);\n\t\t\t\treg.keymaps.push(keymap);\n\t\t\t},\n\n\t\t\tregisterInputRule: (rule) => {\n\t\t\t\tthis.schemaRegistry.registerInputRule(rule);\n\t\t\t\treg.inputRules.push(rule);\n\t\t\t},\n\n\t\t\tregisterToolbarItem: (item) => {\n\t\t\t\tthis.schemaRegistry.registerToolbarItem(item, pluginId);\n\t\t\t\treg.toolbarItems.push(item.id);\n\t\t\t},\n\n\t\t\tregisterInlineNodeSpec: (spec) => {\n\t\t\t\tthis.schemaRegistry.registerInlineNodeSpec(spec);\n\t\t\t\treg.inlineNodeSpecs.push(spec.type);\n\t\t\t},\n\n\t\t\tgetSchemaRegistry: () => this.schemaRegistry,\n\t\t};\n\t}\n\n\t/**\n\t * Resolves plugin initialization order via topological sort + priority.\n\t * Throws on dependency cycles or missing dependencies.\n\t */\n\tprivate resolveOrder(): string[] {\n\t\tconst ids = [...this.plugins.keys()];\n\n\t\t// Validate dependencies exist\n\t\tfor (const id of ids) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tif (!plugin) continue;\n\t\t\tfor (const dep of plugin.dependencies ?? []) {\n\t\t\t\tif (!this.plugins.has(dep)) {\n\t\t\t\t\tthrow new Error(`Plugin \"${id}\" depends on \"${dep}\", which is not registered.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Topological sort (Kahn's algorithm)\n\t\tconst inDegree = new Map<string, number>();\n\t\tconst dependents = new Map<string, string[]>();\n\n\t\tfor (const id of ids) {\n\t\t\tinDegree.set(id, 0);\n\t\t\tdependents.set(id, []);\n\t\t}\n\n\t\tfor (const id of ids) {\n\t\t\tconst plugin = this.plugins.get(id);\n\t\t\tconst deps = plugin?.dependencies ?? [];\n\t\t\tinDegree.set(id, deps.length);\n\t\t\tfor (const dep of deps) {\n\t\t\t\tconst depList = dependents.get(dep);\n\t\t\t\tif (depList) depList.push(id);\n\t\t\t}\n\t\t}\n\n\t\tconst queue: string[] = [];\n\t\tfor (const [id, deg] of inDegree) {\n\t\t\tif (deg === 0) queue.push(id);\n\t\t}\n\n\t\tconst sorted: string[] = [];\n\t\twhile (queue.length > 0) {\n\t\t\tqueue.sort((a, b) => {\n\t\t\t\tconst pa = this.plugins.get(a)?.priority ?? DEFAULT_PRIORITY;\n\t\t\t\tconst pb = this.plugins.get(b)?.priority ?? DEFAULT_PRIORITY;\n\t\t\t\treturn pa - pb;\n\t\t\t});\n\n\t\t\tconst id = queue.shift();\n\t\t\tif (!id) break;\n\t\t\tsorted.push(id);\n\n\t\t\tfor (const dep of dependents.get(id) ?? []) {\n\t\t\t\tconst newDeg = (inDegree.get(dep) ?? 0) - 1;\n\t\t\t\tinDegree.set(dep, newDeg);\n\t\t\t\tif (newDeg === 0) queue.push(dep);\n\t\t\t}\n\t\t}\n\n\t\tif (sorted.length !== ids.length) {\n\t\t\tconst missing = ids.filter((id) => !sorted.includes(id));\n\t\t\tthrow new Error(`Circular dependency detected among plugins: ${missing.join(', ')}`);\n\t\t}\n\n\t\treturn sorted;\n\t}\n}\n","/**\n * Toolbar plugin: renders toolbar items registered by other plugins.\n * Acts as a pure rendering engine — has no knowledge of specific features.\n * Supports buttons, dropdowns, grid pickers, and custom popups.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport { ServiceKey } from '../Plugin.js';\nimport type { Plugin, PluginConfig, PluginContext } from '../Plugin.js';\nimport type { DropdownConfig, GridPickerConfig, ToolbarItem } from './ToolbarItem.js';\n\n// --- Layout Config ---\n\nexport interface ToolbarLayoutConfig {\n\treadonly groups: ReadonlyArray<ReadonlyArray<string>>;\n}\n\n// --- Typed Service API ---\n\nexport interface ToolbarServiceAPI {\n\t/** Re-reads isActive/isEnabled from state and updates all buttons. */\n\trefresh(): void;\n}\n\nexport const ToolbarServiceKey = new ServiceKey<ToolbarServiceAPI>('toolbar');\n\n// --- Plugin ---\n\ninterface ToolbarButton {\n\telement: HTMLButtonElement;\n\titem: ToolbarItem;\n}\n\nexport class ToolbarPlugin implements Plugin {\n\treadonly id = 'toolbar';\n\treadonly name = 'Toolbar';\n\treadonly priority = 10;\n\n\tprivate context: PluginContext | null = null;\n\tprivate toolbarElement: HTMLElement | null = null;\n\tprivate buttons: ToolbarButton[] = [];\n\tprivate activePopup: HTMLElement | null = null;\n\tprivate closePopupHandler: ((e: MouseEvent) => void) | null = null;\n\tprivate readonly hiddenItems = new Set<string>();\n\tprivate tooltipElement: HTMLElement | null = null;\n\tprivate tooltipTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate readonly layoutConfig: ToolbarLayoutConfig | null;\n\n\tconstructor(layoutConfig?: ToolbarLayoutConfig) {\n\t\tthis.layoutConfig = layoutConfig ?? null;\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.context = context;\n\n\t\tcontext.registerService(ToolbarServiceKey, {\n\t\t\trefresh: () => this.updateButtonStates(context.getState()),\n\t\t});\n\n\t\tthis.createToolbarElement();\n\t\tthis.createTooltipElement();\n\t}\n\n\tonReady(): void {\n\t\tthis.renderItems();\n\t}\n\n\tdestroy(): void {\n\t\tthis.closePopup();\n\t\tthis.hideTooltip();\n\t\tif (this.tooltipElement) {\n\t\t\tthis.tooltipElement.remove();\n\t\t\tthis.tooltipElement = null;\n\t\t}\n\t\tif (this.toolbarElement) {\n\t\t\tthis.toolbarElement.remove();\n\t\t\tthis.toolbarElement = null;\n\t\t}\n\t\tthis.buttons = [];\n\t\tthis.context = null;\n\t}\n\n\tonStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\tthis.updateButtonStates(newState);\n\t}\n\n\tonConfigure(config: PluginConfig): void {\n\t\tfor (const [key, value] of Object.entries(config)) {\n\t\t\tif (value === false) {\n\t\t\t\tthis.hiddenItems.add(key);\n\t\t\t} else {\n\t\t\t\tthis.hiddenItems.delete(key);\n\t\t\t}\n\t\t}\n\t\tthis.renderItems();\n\t}\n\n\t// --- Tooltip ---\n\n\tprivate createTooltipElement(): void {\n\t\tthis.tooltipElement = document.createElement('div');\n\t\tthis.tooltipElement.className = 'notectl-toolbar-tooltip';\n\t\tthis.tooltipElement.setAttribute('role', 'tooltip');\n\t\tthis.tooltipElement.style.display = 'none';\n\t}\n\n\tprivate showTooltip(button: HTMLButtonElement): void {\n\t\tthis.hideTooltip();\n\n\t\tif (this.activePopup || button.disabled) return;\n\n\t\tconst text = button.getAttribute('data-tooltip');\n\t\tif (!text || !this.tooltipElement) return;\n\n\t\tthis.tooltipTimer = setTimeout(() => {\n\t\t\tif (!this.tooltipElement || this.activePopup) return;\n\n\t\t\tthis.tooltipElement.textContent = text;\n\t\t\tthis.tooltipElement.style.display = '';\n\n\t\t\t// Append to shadow root to escape overflow:hidden on .notectl-editor\n\t\t\tconst root = button.getRootNode();\n\t\t\tif (root instanceof ShadowRoot && !this.tooltipElement.parentNode) {\n\t\t\t\troot.appendChild(this.tooltipElement);\n\t\t\t} else if (!(root instanceof ShadowRoot) && !this.tooltipElement.parentNode) {\n\t\t\t\tdocument.body.appendChild(this.tooltipElement);\n\t\t\t}\n\n\t\t\t// Position with fixed coordinates so clipping is impossible\n\t\t\tconst rect = button.getBoundingClientRect();\n\t\t\tthis.tooltipElement.style.position = 'fixed';\n\t\t\tthis.tooltipElement.style.top = `${rect.bottom + 6}px`;\n\t\t\tthis.tooltipElement.style.left = `${rect.left + rect.width / 2}px`;\n\t\t\tthis.tooltipElement.style.transform = 'translateX(-50%)';\n\t\t}, 500);\n\t}\n\n\tprivate hideTooltip(): void {\n\t\tif (this.tooltipTimer) {\n\t\t\tclearTimeout(this.tooltipTimer);\n\t\t\tthis.tooltipTimer = null;\n\t\t}\n\t\tif (this.tooltipElement) {\n\t\t\tthis.tooltipElement.style.display = 'none';\n\t\t}\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate createToolbarElement(): void {\n\t\tif (!this.context) return;\n\n\t\tif (this.toolbarElement) {\n\t\t\tthis.toolbarElement.remove();\n\t\t}\n\t\tthis.buttons = [];\n\n\t\tconst container = this.context.getPluginContainer('top');\n\t\tthis.toolbarElement = document.createElement('div');\n\t\tthis.toolbarElement.setAttribute('role', 'toolbar');\n\t\tthis.toolbarElement.setAttribute('aria-label', 'Formatting options');\n\t\tthis.toolbarElement.className = 'notectl-toolbar';\n\n\t\tcontainer.appendChild(this.toolbarElement);\n\t}\n\n\tprivate renderItems(): void {\n\t\tif (!this.context || !this.toolbarElement) return;\n\n\t\t// Remove existing buttons\n\t\tfor (const btn of this.buttons) {\n\t\t\tbtn.element.remove();\n\t\t}\n\t\tthis.buttons = [];\n\n\t\t// Remove existing separators\n\t\tfor (const sep of this.toolbarElement.querySelectorAll('.notectl-toolbar-separator')) {\n\t\t\tsep.remove();\n\t\t}\n\n\t\tif (this.layoutConfig) {\n\t\t\tthis.renderItemsByLayout();\n\t\t} else {\n\t\t\tthis.renderItemsByPriority();\n\t\t}\n\n\t\t// Re-attach toolbar if it was removed but has visible buttons\n\t\tif (this.buttons.length > 0 && !this.toolbarElement.parentElement) {\n\t\t\tconst container = this.context.getPluginContainer('top');\n\t\t\tcontainer.appendChild(this.toolbarElement);\n\t\t}\n\n\t\tthis.updateButtonStates(this.context.getState());\n\t}\n\n\tprivate renderItemsByLayout(): void {\n\t\tif (!this.context || !this.toolbarElement || !this.layoutConfig) return;\n\n\t\tconst registry = this.context.getSchemaRegistry();\n\t\tlet firstGroup = true;\n\n\t\tfor (const groupPluginIds of this.layoutConfig.groups) {\n\t\t\tconst groupItems: ToolbarItem[] = [];\n\t\t\tfor (const pId of groupPluginIds) {\n\t\t\t\tconst items = registry\n\t\t\t\t\t.getToolbarItemsByPlugin(pId)\n\t\t\t\t\t.filter((item) => !this.hiddenItems.has(item.id));\n\t\t\t\t// Sort within plugin by priority (bold before italic etc.)\n\t\t\t\titems.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));\n\t\t\t\tgroupItems.push(...items);\n\t\t\t}\n\n\t\t\tif (groupItems.length === 0) continue;\n\n\t\t\tif (!firstGroup) {\n\t\t\t\tconst sep = document.createElement('span');\n\t\t\t\tsep.className = 'notectl-toolbar-separator';\n\t\t\t\tsep.setAttribute('role', 'separator');\n\t\t\t\tthis.toolbarElement.appendChild(sep);\n\t\t\t}\n\t\t\tfirstGroup = false;\n\n\t\t\tfor (const item of groupItems) {\n\t\t\t\tconst btn = this.createButton(item);\n\t\t\t\tthis.toolbarElement.appendChild(btn.element);\n\t\t\t\tthis.buttons.push(btn);\n\t\t\t}\n\t\t}\n\n\t\tif (this.buttons.length === 0) {\n\t\t\tthis.toolbarElement.remove();\n\t\t}\n\t}\n\n\tprivate renderItemsByPriority(): void {\n\t\tif (!this.context || !this.toolbarElement) return;\n\n\t\tconst registry = this.context.getSchemaRegistry();\n\t\tconst items = registry.getToolbarItems().filter((item) => !this.hiddenItems.has(item.id));\n\t\tif (items.length === 0) {\n\t\t\tthis.toolbarElement.remove();\n\t\t\treturn;\n\t\t}\n\n\t\t// Sort by priority (lower = further left)\n\t\tconst sorted = [...items].sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));\n\n\t\tconst hasSeparatorAfter = sorted.some((item) => item.separatorAfter);\n\n\t\tif (hasSeparatorAfter) {\n\t\t\tfor (let i = 0; i < sorted.length; i++) {\n\t\t\t\tconst item = sorted[i];\n\t\t\t\tif (!item) continue;\n\t\t\t\tconst btn = this.createButton(item);\n\t\t\t\tthis.toolbarElement.appendChild(btn.element);\n\t\t\t\tthis.buttons.push(btn);\n\n\t\t\t\tif (item.separatorAfter && i < sorted.length - 1) {\n\t\t\t\t\tconst sep = document.createElement('span');\n\t\t\t\t\tsep.className = 'notectl-toolbar-separator';\n\t\t\t\t\tsep.setAttribute('role', 'separator');\n\t\t\t\t\tthis.toolbarElement.appendChild(sep);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst groups = new Map<string, ToolbarItem[]>();\n\t\t\tfor (const item of sorted) {\n\t\t\t\tconst list = groups.get(item.group) ?? [];\n\t\t\t\tlist.push(item);\n\t\t\t\tgroups.set(item.group, list);\n\t\t\t}\n\n\t\t\tlet firstGroup = true;\n\t\t\tfor (const [, groupItems] of groups) {\n\t\t\t\tif (!firstGroup) {\n\t\t\t\t\tconst sep = document.createElement('span');\n\t\t\t\t\tsep.className = 'notectl-toolbar-separator';\n\t\t\t\t\tsep.setAttribute('role', 'separator');\n\t\t\t\t\tthis.toolbarElement.appendChild(sep);\n\t\t\t\t}\n\t\t\t\tfirstGroup = false;\n\n\t\t\t\tfor (const item of groupItems) {\n\t\t\t\t\tconst btn = this.createButton(item);\n\t\t\t\t\tthis.toolbarElement.appendChild(btn.element);\n\t\t\t\t\tthis.buttons.push(btn);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate createButton(item: ToolbarItem): ToolbarButton {\n\t\tconst btn = document.createElement('button');\n\t\tbtn.type = 'button';\n\t\tbtn.className = `notectl-toolbar-btn notectl-toolbar-btn--${item.id}`;\n\t\tbtn.setAttribute('aria-pressed', 'false');\n\t\tbtn.setAttribute('aria-label', item.label);\n\t\tbtn.setAttribute('data-toolbar-item', item.id);\n\t\tbtn.setAttribute('data-tooltip', item.tooltip ?? item.label);\n\n\t\tconst span = document.createElement('span');\n\t\tspan.className = 'notectl-toolbar-btn__icon';\n\t\tspan.innerHTML = item.icon;\n\t\tbtn.appendChild(span);\n\n\t\tbtn.addEventListener('mousedown', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.hideTooltip();\n\t\t\tif (item.popupType) {\n\t\t\t\tthis.togglePopup(btn, item);\n\t\t\t} else {\n\t\t\t\tthis.context?.executeCommand(item.command);\n\t\t\t}\n\t\t});\n\n\t\tbtn.addEventListener('mouseenter', () => this.showTooltip(btn));\n\t\tbtn.addEventListener('mouseleave', () => this.hideTooltip());\n\n\t\treturn { element: btn, item };\n\t}\n\n\tprivate activePopupButton: HTMLButtonElement | null = null;\n\n\tprivate togglePopup(button: HTMLButtonElement, item: ToolbarItem): void {\n\t\tif (this.activePopup) {\n\t\t\tthis.closePopup();\n\t\t\treturn;\n\t\t}\n\n\t\tconst popup = document.createElement('div');\n\t\tpopup.className = 'notectl-toolbar-popup';\n\n\t\tswitch (item.popupType) {\n\t\t\tcase 'gridPicker':\n\t\t\t\tthis.renderGridPicker(popup, item.popupConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'dropdown':\n\t\t\t\tthis.renderDropdown(popup, item.popupConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'custom':\n\t\t\t\tif (this.context) item.renderPopup(popup, this.context);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Position below the button using fixed coordinates to escape overflow:hidden\n\t\tconst rect = button.getBoundingClientRect();\n\t\tpopup.style.position = 'fixed';\n\t\tpopup.style.top = `${rect.bottom + 2}px`;\n\t\tpopup.style.left = `${rect.left}px`;\n\t\tpopup.style.zIndex = '10000';\n\n\t\t// Append to shadow root directly to avoid clipping by .notectl-editor\n\t\tconst root = button.getRootNode();\n\t\tif (root instanceof ShadowRoot) {\n\t\t\troot.appendChild(popup);\n\t\t} else {\n\t\t\tdocument.body.appendChild(popup);\n\t\t}\n\n\t\tthis.activePopup = popup;\n\t\tthis.activePopupButton = button;\n\t\tbutton.classList.add('notectl-toolbar-btn--popup-open');\n\n\t\tthis.closePopupHandler = (e: MouseEvent) => {\n\t\t\tif (!popup.contains(e.target as Node) && e.target !== button) {\n\t\t\t\tthis.closePopup();\n\t\t\t}\n\t\t};\n\t\tsetTimeout(() => {\n\t\t\tif (this.closePopupHandler) {\n\t\t\t\tdocument.addEventListener('mousedown', this.closePopupHandler);\n\t\t\t}\n\t\t}, 0);\n\t}\n\n\tprivate closePopup(): void {\n\t\tif (this.activePopupButton) {\n\t\t\tthis.activePopupButton.classList.remove('notectl-toolbar-btn--popup-open');\n\t\t\tthis.activePopupButton = null;\n\t\t}\n\t\tif (this.activePopup) {\n\t\t\tthis.activePopup.remove();\n\t\t\tthis.activePopup = null;\n\t\t}\n\t\tif (this.closePopupHandler) {\n\t\t\tdocument.removeEventListener('mousedown', this.closePopupHandler);\n\t\t\tthis.closePopupHandler = null;\n\t\t}\n\t}\n\n\tprivate renderGridPicker(container: HTMLElement, config: GridPickerConfig): void {\n\t\tcontainer.className += ' notectl-grid-picker';\n\t\tconst grid = document.createElement('div');\n\t\tgrid.className = 'notectl-grid-picker__grid';\n\t\tgrid.style.display = 'grid';\n\t\tgrid.style.gridTemplateColumns = `repeat(${config.maxCols}, 1fr)`;\n\t\tgrid.style.gap = '2px';\n\t\tgrid.style.padding = '8px';\n\n\t\tconst label = document.createElement('div');\n\t\tlabel.className = 'notectl-grid-picker__label';\n\t\tlabel.textContent = '1 x 1';\n\t\tlabel.style.textAlign = 'center';\n\t\tlabel.style.padding = '4px';\n\t\tlabel.style.fontSize = '12px';\n\n\t\tfor (let r = 1; r <= config.maxRows; r++) {\n\t\t\tfor (let c = 1; c <= config.maxCols; c++) {\n\t\t\t\tconst cell = document.createElement('div');\n\t\t\t\tcell.className = 'notectl-grid-picker__cell';\n\t\t\t\tcell.style.width = '20px';\n\t\t\t\tcell.style.height = '20px';\n\t\t\t\tcell.style.border = '1px solid #ccc';\n\t\t\t\tcell.style.cursor = 'pointer';\n\t\t\t\tcell.setAttribute('data-row', String(r));\n\t\t\t\tcell.setAttribute('data-col', String(c));\n\n\t\t\t\tcell.addEventListener('mouseenter', () => {\n\t\t\t\t\tconst cells = grid.querySelectorAll('.notectl-grid-picker__cell');\n\t\t\t\t\tfor (const other of cells) {\n\t\t\t\t\t\tconst otherR = Number(other.getAttribute('data-row'));\n\t\t\t\t\t\tconst otherC = Number(other.getAttribute('data-col'));\n\t\t\t\t\t\t(other as HTMLElement).style.background = otherR <= r && otherC <= c ? '#4a9eff' : '';\n\t\t\t\t\t}\n\t\t\t\t\tlabel.textContent = `${r} x ${c}`;\n\t\t\t\t});\n\n\t\t\t\tcell.addEventListener('mousedown', (e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tconfig.onSelect(r, c);\n\t\t\t\t\tthis.closePopup();\n\t\t\t\t});\n\n\t\t\t\tgrid.appendChild(cell);\n\t\t\t}\n\t\t}\n\n\t\tcontainer.appendChild(grid);\n\t\tcontainer.appendChild(label);\n\t}\n\n\tprivate renderDropdown(container: HTMLElement, config: DropdownConfig): void {\n\t\tcontainer.classList.add('notectl-dropdown');\n\t\tfor (const item of config.items) {\n\t\t\tconst btn = document.createElement('button');\n\t\t\tbtn.type = 'button';\n\t\t\tbtn.className = 'notectl-dropdown__item';\n\n\t\t\tif (item.icon) {\n\t\t\t\tconst iconSpan = document.createElement('span');\n\t\t\t\ticonSpan.className = 'notectl-dropdown__item-icon';\n\t\t\t\ticonSpan.innerHTML = item.icon;\n\t\t\t\tbtn.appendChild(iconSpan);\n\t\t\t}\n\n\t\t\tconst labelSpan = document.createElement('span');\n\t\t\tlabelSpan.className = 'notectl-dropdown__item-label';\n\t\t\tlabelSpan.textContent = item.label;\n\t\t\tbtn.appendChild(labelSpan);\n\n\t\t\tbtn.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.context?.executeCommand(item.command);\n\t\t\t\tthis.closePopup();\n\t\t\t});\n\n\t\t\tcontainer.appendChild(btn);\n\t\t}\n\t}\n\n\tprivate updateButtonStates(state: EditorState): void {\n\t\tfor (const btn of this.buttons) {\n\t\t\tconst active = btn.item.isActive?.(state) ?? false;\n\t\t\tconst enabled = btn.item.isEnabled?.(state) ?? true;\n\t\t\tbtn.element.setAttribute('aria-pressed', String(active));\n\t\t\tbtn.element.classList.toggle('notectl-toolbar-btn--active', active);\n\t\t\tbtn.element.disabled = !enabled;\n\t\t\tif (!enabled) {\n\t\t\t\tbtn.element.setAttribute('aria-disabled', 'true');\n\t\t\t} else {\n\t\t\t\tbtn.element.removeAttribute('aria-disabled');\n\t\t\t}\n\t\t}\n\t}\n}\n","/**\n * ToolbarItem: describes a toolbar button registered by a plugin.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\n\nexport interface GridPickerConfig {\n\treadonly maxRows: number;\n\treadonly maxCols: number;\n\tonSelect(rows: number, cols: number): void;\n}\n\nexport interface DropdownConfig {\n\treadonly items: readonly { label: string; command: string; icon?: string }[];\n}\n\nexport type ToolbarGroup = 'format' | 'block' | 'insert' | (string & {});\nexport type PopupType = 'gridPicker' | 'dropdown' | 'custom';\n\ninterface ToolbarItemBase {\n\treadonly id: string;\n\t/** Grouping key: 'format' | 'insert' | 'block' or custom. */\n\treadonly group: ToolbarGroup;\n\t/** Icon content: inline SVG markup or plain text. Rendered via innerHTML. */\n\treadonly icon: string;\n\treadonly label: string;\n\t/** Tooltip shown on hover, e.g. \"Bold (Ctrl+B)\". Falls back to label. */\n\treadonly tooltip?: string;\n\t/** Command name to execute on click. */\n\treadonly command: string;\n\t/**\n\t * Lower priority renders further left.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly priority?: number;\n\t/**\n\t * When true, a visual separator is rendered after this item.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly separatorAfter?: boolean;\n\tisActive?(state: EditorState): boolean;\n\tisEnabled?(state: EditorState): boolean;\n}\n\ninterface ToolbarItemNoPopup extends ToolbarItemBase {\n\treadonly popupType?: undefined;\n}\n\ninterface ToolbarItemGridPicker extends ToolbarItemBase {\n\treadonly popupType: 'gridPicker';\n\treadonly popupConfig: GridPickerConfig;\n}\n\ninterface ToolbarItemDropdown extends ToolbarItemBase {\n\treadonly popupType: 'dropdown';\n\treadonly popupConfig: DropdownConfig;\n}\n\ninterface ToolbarItemCustomPopup extends ToolbarItemBase {\n\treadonly popupType: 'custom';\n\trenderPopup(container: HTMLElement, context: PluginContext): void;\n}\n\nexport type ToolbarItem =\n\t| ToolbarItemNoPopup\n\t| ToolbarItemGridPicker\n\t| ToolbarItemDropdown\n\t| ToolbarItemCustomPopup;\n\n/**\n * Formats a keymap binding string into a human-readable shortcut,\n * using platform-appropriate modifier symbols (⌘ on Mac, Ctrl on others).\n *\n * @example formatShortcut('Mod-B') → \"Ctrl+B\" or \"⌘B\"\n * @example formatShortcut('Mod-Shift-X') → \"Ctrl+Shift+X\" or \"⌘⇧X\"\n */\nexport function formatShortcut(binding: string): string {\n\tconst isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad|iPod/.test(navigator.platform);\n\tif (isMac) {\n\t\treturn binding\n\t\t\t.replace(/Mod/g, '⌘')\n\t\t\t.replace(/Shift/g, '⇧')\n\t\t\t.replace(/Alt/g, '⌥')\n\t\t\t.replace(/-/g, '');\n\t}\n\treturn binding.replace(/Mod/g, 'Ctrl').replace(/-/g, '+');\n}\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\t/** When true, a separator is rendered after the last text-formatting toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\tlabel: 'Bold',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\tlabel: 'Italic',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\tlabel: 'Underline',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\t// Determine which marks will have visible toolbar items\n\t\tconst visibleToolbarMarks = enabledMarks.filter((def) => this.isToolbarVisible(def.configKey));\n\t\tconst lastVisibleMark = visibleToolbarMarks.at(-1);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tconst isSeparatorTarget = this.config.separatorAfter && def === lastVisibleMark;\n\t\t\tthis.registerMark(context, def, isSeparatorTarget);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(\n\t\tcontext: PluginContext,\n\t\tdef: MarkDefinition,\n\t\tseparatorAfter?: boolean,\n\t): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel: def.label,\n\t\t\t\ttooltip: `${def.label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\tseparatorAfter,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: def.label,\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'bold' → 'toggleBold'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n","/**\n * HeadingPlugin: registers Title, Subtitle, and H1–H6 heading block types\n * with NodeSpec, toggle commands, keyboard shortcuts, input rules, and a\n * combobox-style toolbar dropdown that reflects the current block type.\n */\n\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport { createCollapsedSelection, isCollapsed } from '../../model/Selection.js';\nimport { type NodeTypeName, nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport type { TextAlignment } from '../text-alignment/TextAlignmentPlugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\theading: { level: HeadingLevel; textAlign?: TextAlignment };\n\t\ttitle: { textAlign?: TextAlignment };\n\t\tsubtitle: { textAlign?: TextAlignment };\n\t}\n}\n\n// --- Configuration ---\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingConfig {\n\t/** Which heading levels to enable. Defaults to [1, 2, 3, 4, 5, 6]. */\n\treadonly levels: readonly HeadingLevel[];\n\t/** When true, a separator is rendered after the heading toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: HeadingConfig = {\n\tlevels: [1, 2, 3, 4, 5, 6],\n};\n\n// --- Heading Tag Mapping ---\n\nconst HEADING_TAGS: Record<HeadingLevel, string> = {\n\t1: 'h1',\n\t2: 'h2',\n\t3: 'h3',\n\t4: 'h4',\n\t5: 'h5',\n\t6: 'h6',\n};\n\n// --- Display Labels ---\n\nconst HEADING_LABELS: Record<HeadingLevel, string> = {\n\t1: 'Heading 1',\n\t2: 'Heading 2',\n\t3: 'Heading 3',\n\t4: 'Heading 4',\n\t5: 'Heading 5',\n\t6: 'Heading 6',\n};\n\nconst TITLE_LABEL = 'Title';\nconst SUBTITLE_LABEL = 'Subtitle';\nconst PARAGRAPH_LABEL = 'Paragraph';\n\n// --- Picker Item Styling ---\n\ninterface PickerItemStyle {\n\treadonly fontSize: string;\n\treadonly fontWeight: string;\n\treadonly color?: string;\n}\n\n// --- Plugin ---\n\nexport class HeadingPlugin implements Plugin {\n\treadonly id = 'heading';\n\treadonly name = 'Heading';\n\treadonly priority = 30;\n\n\tprivate readonly config: HeadingConfig;\n\tprivate context: PluginContext | null = null;\n\tprivate comboLabel: HTMLSpanElement | null = null;\n\n\tconstructor(config?: Partial<HeadingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.context = context;\n\t\tthis.registerNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerInputRules(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tdestroy(): void {\n\t\tthis.context = null;\n\t\tthis.comboLabel = null;\n\t}\n\n\tonStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\tthis.updateComboLabel(newState);\n\t}\n\n\tprivate registerNodeSpecs(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'title',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\ttoDOM(node) {\n\t\t\t\tconst el = createBlockElement('h1', node.id);\n\t\t\t\tel.classList.add('notectl-title');\n\t\t\t\treturn el;\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'subtitle',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\ttoDOM(node) {\n\t\t\t\tconst el = createBlockElement('h2', node.id);\n\t\t\t\tel.classList.add('notectl-subtitle');\n\t\t\t\treturn el;\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'heading',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\tattrs: {\n\t\t\t\tlevel: { default: 1 },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst level = node.attrs?.level ?? 1;\n\t\t\t\tconst tag = HEADING_TAGS[level] ?? 'h1';\n\t\t\t\treturn createBlockElement(tag, node.id);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\t// Title / Subtitle\n\t\tcontext.registerCommand('setTitle', () => {\n\t\t\treturn this.toggleSpecialBlock(context, 'title');\n\t\t});\n\n\t\tcontext.registerCommand('setSubtitle', () => {\n\t\t\treturn this.toggleSpecialBlock(context, 'subtitle');\n\t\t});\n\n\t\t// Heading levels\n\t\tfor (const level of this.config.levels) {\n\t\t\tcontext.registerCommand(`setHeading${level}`, () => {\n\t\t\t\treturn this.toggleHeading(context, level);\n\t\t\t});\n\t\t}\n\n\t\t// Generic command that toggles back to paragraph\n\t\tcontext.registerCommand('toggleHeading', () => {\n\t\t\treturn this.toggleHeading(context, 1);\n\t\t});\n\n\t\t// Set paragraph (reset heading)\n\t\tcontext.registerCommand('setParagraph', () => {\n\t\t\treturn this.setBlockType(context, nodeType('paragraph'));\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\n\t\tfor (const level of this.config.levels) {\n\t\t\tif (level <= 6) {\n\t\t\t\tkeymap[`Mod-Shift-${level}`] = () => context.executeCommand(`setHeading${level}`);\n\t\t\t}\n\t\t}\n\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\tprivate registerInputRules(context: PluginContext): void {\n\t\tfor (const level of this.config.levels) {\n\t\t\tconst hashes = '#'.repeat(level);\n\t\t\tconst pattern = new RegExp(`^${hashes} $`);\n\n\t\t\tcontext.registerInputRule({\n\t\t\t\tpattern,\n\t\t\t\thandler(state, _match, start, _end) {\n\t\t\t\t\tconst sel = state.selection;\n\t\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\t\treturn state\n\t\t\t\t\t\t.transaction('input')\n\t\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, start, start + level + 1)\n\t\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('heading'), { level })\n\t\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t\t.build();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon: string = `<span class=\"notectl-heading-select__label\" data-heading-label>${PARAGRAPH_LABEL}</span><span class=\"notectl-heading-select__arrow\">\\u25BE</span>`;\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'heading',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: 'Block Type',\n\t\t\ttooltip: 'Block Type',\n\t\t\tcommand: 'setParagraph',\n\t\t\tpriority: 50,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderHeadingPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => {\n\t\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\t\treturn block?.type === 'heading' || block?.type === 'title' || block?.type === 'subtitle';\n\t\t\t},\n\t\t});\n\t}\n\n\t// --- Combo Label ---\n\n\tprivate updateComboLabel(state: EditorState): void {\n\t\tif (!this.comboLabel) {\n\t\t\tconst container: HTMLElement | undefined = this.context?.getPluginContainer('top');\n\t\t\tif (!container) return;\n\t\t\tthis.comboLabel = container.querySelector<HTMLSpanElement>('[data-heading-label]') ?? null;\n\t\t\tif (!this.comboLabel) return;\n\t\t}\n\n\t\tthis.comboLabel.textContent = this.getActiveLabel(state);\n\t}\n\n\tprivate getActiveLabel(state: EditorState): string {\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block) return PARAGRAPH_LABEL;\n\n\t\tif (block.type === 'title') return TITLE_LABEL;\n\t\tif (block.type === 'subtitle') return SUBTITLE_LABEL;\n\n\t\tif (block.type === 'heading') {\n\t\t\tconst level = block.attrs?.level as HeadingLevel | undefined;\n\t\t\tif (!level) return HEADING_LABELS[1];\n\t\t\treturn HEADING_LABELS[level] ?? HEADING_LABELS[1];\n\t\t}\n\n\t\treturn PARAGRAPH_LABEL;\n\t}\n\n\t// --- Custom Popup ---\n\n\tprivate dismissPopup(): void {\n\t\tsetTimeout(() => {\n\t\t\tdocument.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));\n\t\t}, 0);\n\t}\n\n\tprivate renderHeadingPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.classList.add('notectl-heading-picker');\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tconst currentType: string = block?.type ?? 'paragraph';\n\t\tconst activeLevel: HeadingLevel | null =\n\t\t\tcurrentType === 'heading' ? ((block?.attrs?.level as HeadingLevel) ?? 1) : null;\n\n\t\tconst list: HTMLDivElement = document.createElement('div');\n\t\tlist.className = 'notectl-heading-picker__list';\n\n\t\tconst addItem = (\n\t\t\tlabel: string,\n\t\t\tactive: boolean,\n\t\t\tcommand: string,\n\t\t\tstyle?: PickerItemStyle,\n\t\t): void => {\n\t\t\tlist.appendChild(\n\t\t\t\tthis.createPickerItem(\n\t\t\t\t\tlabel,\n\t\t\t\t\tactive,\n\t\t\t\t\t(e: MouseEvent) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tcontext.executeCommand(command);\n\t\t\t\t\t\tthis.dismissPopup();\n\t\t\t\t\t},\n\t\t\t\t\tstyle,\n\t\t\t\t),\n\t\t\t);\n\t\t};\n\n\t\t// Paragraph\n\t\taddItem(PARAGRAPH_LABEL, currentType === 'paragraph', 'setParagraph');\n\n\t\t// Title\n\t\taddItem(TITLE_LABEL, currentType === 'title', 'setTitle', {\n\t\t\tfontSize: '1.6em',\n\t\t\tfontWeight: '700',\n\t\t});\n\n\t\t// Subtitle\n\t\taddItem(SUBTITLE_LABEL, currentType === 'subtitle', 'setSubtitle', {\n\t\t\tfontSize: '1.3em',\n\t\t\tfontWeight: '500',\n\t\t});\n\n\t\t// Heading levels\n\t\tfor (const level of this.config.levels) {\n\t\t\taddItem(HEADING_LABELS[level], activeLevel === level, `setHeading${level}`, {\n\t\t\t\tfontSize: `${1.4 - level * 0.1}em`,\n\t\t\t\tfontWeight: '600',\n\t\t\t});\n\t\t}\n\n\t\tcontainer.appendChild(list);\n\t}\n\n\tprivate createPickerItem(\n\t\tlabel: string,\n\t\tisActive: boolean,\n\t\thandler: (e: MouseEvent) => void,\n\t\tstyle?: PickerItemStyle,\n\t): HTMLButtonElement {\n\t\tconst item: HTMLButtonElement = document.createElement('button');\n\t\titem.type = 'button';\n\t\titem.className = 'notectl-heading-picker__item';\n\n\t\tif (isActive) {\n\t\t\titem.classList.add('notectl-heading-picker__item--active');\n\t\t}\n\n\t\tconst check: HTMLSpanElement = document.createElement('span');\n\t\tcheck.className = 'notectl-heading-picker__check';\n\t\tcheck.textContent = isActive ? '\\u2713' : '';\n\t\titem.appendChild(check);\n\n\t\tconst labelSpan: HTMLSpanElement = document.createElement('span');\n\t\tlabelSpan.className = 'notectl-heading-picker__label';\n\t\tlabelSpan.textContent = label;\n\t\tif (style) {\n\t\t\tlabelSpan.style.fontSize = style.fontSize;\n\t\t\tlabelSpan.style.fontWeight = style.fontWeight;\n\t\t\tif (style.color) {\n\t\t\t\tlabelSpan.style.color = style.color;\n\t\t\t}\n\t\t}\n\t\titem.appendChild(labelSpan);\n\n\t\titem.addEventListener('mousedown', handler);\n\t\treturn item;\n\t}\n\n\t/**\n\t * Toggles between a special block type (title/subtitle) and paragraph.\n\t * If the block is already that type, resets to paragraph.\n\t */\n\tprivate toggleSpecialBlock(context: PluginContext, type: string): boolean {\n\t\tconst state = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tif (block.type === type) {\n\t\t\treturn this.setBlockType(context, nodeType('paragraph'));\n\t\t}\n\n\t\treturn this.setBlockType(context, nodeType(type) as NodeTypeName);\n\t}\n\n\t/**\n\t * Toggles between heading (at given level) and paragraph.\n\t * If the block is already a heading at the same level, resets to paragraph.\n\t */\n\tprivate toggleHeading(context: PluginContext, level: HeadingLevel): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tif (block.type === 'heading' && block.attrs?.level === level) {\n\t\t\treturn this.setBlockType(context, nodeType('paragraph'));\n\t\t}\n\n\t\treturn this.setBlockType(context, nodeType('heading'), { level });\n\t}\n\n\tprivate setBlockType(\n\t\tcontext: PluginContext,\n\t\ttype: NodeTypeName,\n\t\tattrs?: Record<string, string | number | boolean>,\n\t): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, type, attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n","/**\n * LinkPlugin: registers a link mark type with href attribute,\n * toggle command, keyboard shortcut (Mod-K), and toolbar button\n * with a URL input popup.\n */\n\nimport { getBlockMarksAtOffset, hasMark } from '../../model/Document.js';\nimport { isCollapsed, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tlink: { href: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface LinkConfig {\n\t/** Whether to add rel=\"noopener noreferrer\" and target=\"_blank\" by default. */\n\treadonly openInNewTab: boolean;\n\t/** When true, a separator is rendered after the link toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: LinkConfig = {\n\topenInNewTab: true,\n};\n\n// --- Plugin ---\n\nexport class LinkPlugin implements Plugin {\n\treadonly id = 'link';\n\treadonly name = 'Link';\n\treadonly priority = 25;\n\n\tprivate readonly config: LinkConfig;\n\n\tconstructor(config?: Partial<LinkConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tconst openInNewTab = this.config.openInNewTab;\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'link',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\thref: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst a = document.createElement('a');\n\t\t\t\tconst href = mark.attrs?.href ?? '';\n\t\t\t\ta.setAttribute('href', href);\n\t\t\t\tif (openInNewTab) {\n\t\t\t\t\ta.setAttribute('target', '_blank');\n\t\t\t\t\ta.setAttribute('rel', 'noopener noreferrer');\n\t\t\t\t}\n\t\t\t\treturn a;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('toggleLink', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.toggleLink(context, state);\n\t\t});\n\n\t\tcontext.registerCommand('setLink', () => {\n\t\t\t// setLink is called by the popup after URL input\n\t\t\t// The actual URL is set via the popup's custom render\n\t\t\treturn false;\n\t\t});\n\n\t\tcontext.registerCommand('removeLink', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.removeLink(context, state);\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-K': () => context.executeCommand('toggleLink'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'link',\n\t\t\tgroup: 'insert',\n\t\t\ticon,\n\t\t\tlabel: 'Link',\n\t\t\ttooltip: `Insert Link (${formatShortcut('Mod-K')})`,\n\t\t\tcommand: 'toggleLink',\n\t\t\tpriority: 60,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderLinkPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isLinkActive(state),\n\t\t\tisEnabled: (state) => !isCollapsed(state.selection),\n\t\t});\n\t}\n\n\tprivate isLinkActive(state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return false;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\treturn hasMark(marks, markType('link'));\n\t\t}\n\n\t\t// Check if link is active anywhere in selection\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\treturn hasMark(marks, markType('link'));\n\t}\n\n\tprivate toggleLink(context: PluginContext, state: EditorState): boolean {\n\t\tif (this.isLinkActive(state)) {\n\t\t\treturn this.removeLink(context, state);\n\t\t}\n\t\t// Adding links requires the toolbar popup for URL input\n\t\treturn false;\n\t}\n\n\tprivate addLink(context: PluginContext, state: EditorState, href: string): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isCollapsed(sel)) return false;\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\tconst mark = { type: markType('link'), attrs: { href } };\n\n\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeLink(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = isCollapsed(sel)\n\t\t\t? { from: sel.anchor, to: sel.anchor }\n\t\t\t: selectionRange(sel, blockOrder);\n\n\t\tconst builder = state.transaction('command');\n\n\t\tif (isCollapsed(sel)) {\n\t\t\t// Remove link from entire link span around cursor\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return false;\n\n\t\t\t// Find the extent of the link mark around the cursor.\n\t\t\t// Build a list of text children with their positions first,\n\t\t\t// then scan backward and forward from the cursor node.\n\t\t\tconst textChildren: { pos: number; end: number; hasLink: boolean }[] = [];\n\t\t\tlet pos = 0;\n\t\t\tfor (const child of block.children) {\n\t\t\t\tif (!('text' in child)) continue;\n\t\t\t\tconst end = pos + child.text.length;\n\t\t\t\ttextChildren.push({ pos, end, hasLink: hasMark(child.marks, markType('link')) });\n\t\t\t\tpos = end;\n\t\t\t}\n\n\t\t\t// Find the text child containing the cursor\n\t\t\tconst cursorIdx = textChildren.findIndex(\n\t\t\t\t(c) => sel.anchor.offset >= c.pos && sel.anchor.offset <= c.end,\n\t\t\t);\n\t\t\tconst cursorEntry = cursorIdx >= 0 ? textChildren[cursorIdx] : undefined;\n\t\t\tif (cursorIdx === -1 || !cursorEntry?.hasLink) return false;\n\n\t\t\t// Scan backward from cursor node to find link start\n\t\t\tlet startIdx = cursorIdx;\n\t\t\twhile (startIdx > 0 && textChildren[startIdx - 1]?.hasLink) {\n\t\t\t\tstartIdx--;\n\t\t\t}\n\n\t\t\t// Scan forward from cursor node to find link end\n\t\t\tlet endIdx = cursorIdx;\n\t\t\twhile (endIdx < textChildren.length - 1 && textChildren[endIdx + 1]?.hasLink) {\n\t\t\t\tendIdx++;\n\t\t\t}\n\n\t\t\tconst startEntry = textChildren[startIdx];\n\t\t\tconst endEntry = textChildren[endIdx];\n\t\t\tif (!startEntry || !endEntry) return false;\n\n\t\t\tconst linkStart = startEntry.pos;\n\t\t\tconst linkEnd = endEntry.end;\n\n\t\t\tbuilder.removeMark(sel.anchor.blockId, linkStart, linkEnd, { type: markType('link') });\n\t\t} else {\n\t\t\t// Remove link from selection range\n\t\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\t\tconst blockId = blockOrder[i];\n\t\t\t\tif (!blockId) continue;\n\t\t\t\tconst block = state.getBlock(blockId);\n\t\t\t\tif (!block) continue;\n\t\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t\t0,\n\t\t\t\t);\n\n\t\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\t\tif (from !== to) {\n\t\t\t\t\tbuilder.removeMark(blockId, from, to, { type: markType('link') });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate renderLinkPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.style.padding = '8px';\n\t\tcontainer.style.minWidth = '200px';\n\n\t\tconst state = context.getState();\n\t\tconst isActive = this.isLinkActive(state);\n\n\t\tif (isActive) {\n\t\t\t// Show remove link button\n\t\t\tconst removeBtn = document.createElement('button');\n\t\t\tremoveBtn.type = 'button';\n\t\t\tremoveBtn.textContent = 'Remove Link';\n\t\t\tremoveBtn.style.cssText = 'width:100%;padding:6px 12px;cursor:pointer;';\n\t\t\tremoveBtn.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tcontext.executeCommand('removeLink');\n\t\t\t});\n\t\t\tcontainer.appendChild(removeBtn);\n\t\t} else {\n\t\t\t// Show URL input\n\t\t\tconst input = document.createElement('input');\n\t\t\tinput.type = 'url';\n\t\t\tinput.placeholder = 'https://...';\n\t\t\tinput.style.cssText = 'width:100%;padding:4px;box-sizing:border-box;';\n\n\t\t\tconst applyBtn = document.createElement('button');\n\t\t\tapplyBtn.type = 'button';\n\t\t\tapplyBtn.textContent = 'Apply';\n\t\t\tapplyBtn.style.cssText = 'width:100%;padding:6px 12px;margin-top:4px;cursor:pointer;';\n\n\t\t\tapplyBtn.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tconst href = input.value.trim();\n\t\t\t\tif (href) {\n\t\t\t\t\tthis.addLink(context, context.getState(), href);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tinput.addEventListener('keydown', (e) => {\n\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tconst href = input.value.trim();\n\t\t\t\t\tif (href) {\n\t\t\t\t\t\tthis.addLink(context, context.getState(), href);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tcontainer.appendChild(input);\n\t\t\tcontainer.appendChild(applyBtn);\n\n\t\t\t// Auto-focus input\n\t\t\trequestAnimationFrame(() => input.focus());\n\t\t}\n\t}\n}\n","/**\n * ListPlugin: registers ordered, unordered, and checklist block types\n * with NodeSpecs, toggle commands, indent/outdent (Tab/Shift-Tab),\n * input rules, and toolbar buttons.\n *\n * List items are modeled as flat blocks with a `listType` and `indent` attribute,\n * allowing simple nesting representation without deep tree structures.\n */\n\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport { generateBlockId, getBlockText } from '../../model/Document.js';\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport { createCollapsedSelection, isCollapsed } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\nexport type ListType = 'bullet' | 'ordered' | 'checklist';\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\tlist_item: { listType: ListType; indent: number; checked: boolean };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface ListConfig {\n\t/** Which list types to enable. Defaults to all. */\n\treadonly types: readonly ListType[];\n\t/** Maximum indent depth. Defaults to 4. */\n\treadonly maxIndent: number;\n\t/** When true, a separator is rendered after the last list toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: ListConfig = {\n\ttypes: ['bullet', 'ordered', 'checklist'],\n\tmaxIndent: 4,\n};\n\n// --- List Type Metadata ---\n\ninterface ListTypeDefinition {\n\treadonly type: ListType;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly inputPattern: RegExp;\n\treadonly inputPrefix: string;\n}\n\nconst BULLET_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z\"/></svg>';\nconst NUMBERED_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z\"/></svg>';\nconst CHECKLIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M22 7h-9v2h9V7zm0 8h-9v2h9v-2zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z\"/></svg>';\n\nconst LIST_TYPE_DEFINITIONS: readonly ListTypeDefinition[] = [\n\t{\n\t\ttype: 'bullet',\n\t\tlabel: 'Bullet List',\n\t\ticon: BULLET_LIST_ICON,\n\t\tinputPattern: /^[-*] $/,\n\t\tinputPrefix: '- ',\n\t},\n\t{\n\t\ttype: 'ordered',\n\t\tlabel: 'Numbered List',\n\t\ticon: NUMBERED_LIST_ICON,\n\t\tinputPattern: /^\\d+\\. $/,\n\t\tinputPrefix: '1. ',\n\t},\n\t{\n\t\ttype: 'checklist',\n\t\tlabel: 'Checklist',\n\t\ticon: CHECKLIST_ICON,\n\t\tinputPattern: /^\\[[ x]] $/,\n\t\tinputPrefix: '[ ] ',\n\t},\n];\n\n// --- Plugin ---\n\nexport class ListPlugin implements Plugin {\n\treadonly id = 'list';\n\treadonly name = 'List';\n\treadonly priority = 35;\n\n\tprivate readonly config: ListConfig;\n\n\tconstructor(config?: Partial<ListConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerInputRules(context);\n\t\tthis.registerToolbarItems(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'list_item',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\tattrs: {\n\t\t\t\tlistType: { default: 'bullet' },\n\t\t\t\tindent: { default: 0 },\n\t\t\t\tchecked: { default: false },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst indent = node.attrs?.indent ?? 0;\n\t\t\t\tconst checked = node.attrs?.checked ?? false;\n\n\t\t\t\tconst li = createBlockElement('div', node.id);\n\t\t\t\tli.setAttribute('data-list-type', listType);\n\t\t\t\tli.setAttribute('data-indent', String(indent));\n\t\t\t\tli.className = `notectl-list-item notectl-list-item--${listType}`;\n\n\t\t\t\tif (indent > 0) {\n\t\t\t\t\tli.style.marginLeft = `${indent * 24}px`;\n\t\t\t\t}\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\tli.setAttribute('data-checked', String(checked));\n\t\t\t\t}\n\n\t\t\t\treturn li;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerCommand(`toggleList:${def.type}`, () => {\n\t\t\t\treturn this.toggleList(context, def.type);\n\t\t\t});\n\t\t}\n\n\t\tcontext.registerCommand('indentListItem', () => {\n\t\t\treturn this.indent(context);\n\t\t});\n\n\t\tcontext.registerCommand('outdentListItem', () => {\n\t\t\treturn this.outdent(context);\n\t\t});\n\n\t\tif (this.config.types.includes('checklist')) {\n\t\t\tcontext.registerCommand('toggleChecklistItem', () => {\n\t\t\t\treturn this.toggleChecked(context);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\tEnter: () => this.handleEnter(context),\n\t\t\tBackspace: () => this.handleBackspace(context),\n\t\t\tTab: () => this.indent(context),\n\t\t\t'Shift-Tab': () => this.outdent(context),\n\t\t});\n\t}\n\n\tprivate registerInputRules(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerInputRule({\n\t\t\t\tpattern: def.inputPattern,\n\t\t\t\thandler: (state, match, start, _end) => {\n\t\t\t\t\tconst sel = state.selection;\n\t\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\t\tconst matchStr = match[0] ?? '';\n\t\t\t\t\tconst matchLen = matchStr.length;\n\t\t\t\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\t\t\t\tlistType: def.type,\n\t\t\t\t\t\tindent: 0,\n\t\t\t\t\t};\n\t\t\t\t\tif (def.type === 'checklist') {\n\t\t\t\t\t\tattrs.checked = matchStr.includes('[x]');\n\t\t\t\t\t}\n\n\t\t\t\t\treturn state\n\t\t\t\t\t\t.transaction('input')\n\t\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, start, start + matchLen)\n\t\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t\t.build();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerToolbarItems(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\t\tconst lastType = enabledTypes.at(-1);\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: `list-${def.type}`,\n\t\t\t\tgroup: 'block',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel: def.label,\n\t\t\t\tcommand: `toggleList:${def.type}`,\n\t\t\t\tpriority: def.type === 'bullet' ? 70 : def.type === 'ordered' ? 71 : 72,\n\t\t\t\tseparatorAfter: this.config.separatorAfter && def === lastType,\n\t\t\t\tisActive: (state) => this.isListActive(state, def.type),\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Command Implementations ---\n\n\tprivate toggleList(context: PluginContext, listType: ListType): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\t// If already this list type, convert back to paragraph\n\t\tif (block.type === 'list_item' && block.attrs?.listType === listType) {\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Convert to list item\n\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\tlistType,\n\t\t\tindent: isNodeOfType(block, 'list_item') ? block.attrs.indent : 0,\n\t\t};\n\t\tif (listType === 'checklist') {\n\t\t\tattrs.checked = false;\n\t\t}\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate indent(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\t\tif (block.attrs.indent >= this.config.maxIndent) return false;\n\n\t\treturn this.setIndent(context, state, block.attrs.indent + 1);\n\t}\n\n\tprivate outdent(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\t\tif (block.attrs.indent <= 0) return false;\n\n\t\treturn this.setIndent(context, state, block.attrs.indent - 1);\n\t}\n\n\tprivate setIndent(context: PluginContext, state: EditorState, indent: number): boolean {\n\t\tconst sel = state.selection;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tconst attrs = { ...block.attrs, indent } as Record<string, string | number | boolean>;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate toggleChecked(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item' || block.attrs?.listType !== 'checklist') {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst checked = !block.attrs?.checked;\n\t\tconst attrs = { ...block.attrs, checked } as Record<string, string | number | boolean>;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(state.selection.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(state.selection)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles Backspace at the start of a list item.\n\t * Converts the list item back to a paragraph, preserving text.\n\t */\n\tprivate handleBackspace(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (!isCollapsed(sel)) return false;\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item') return false;\n\t\tif (sel.anchor.offset !== 0) return false;\n\n\t\tconst tr = state\n\t\t\t.transaction('input')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles Enter inside a list item.\n\t * Empty item → exit list (convert to paragraph).\n\t * Non-empty item → split and create a new list item with the same type.\n\t */\n\tprivate handleEnter(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (!isCollapsed(sel)) return false;\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item') return false;\n\n\t\tconst text = getBlockText(block);\n\n\t\tif (text === '') {\n\t\t\t// Empty list item → convert to paragraph (exit list)\n\t\t\tconst tr = state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Non-empty → split block and set new block to same list type\n\t\tconst newBlockId = generateBlockId();\n\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\tlistType: isNodeOfType(block, 'list_item') ? block.attrs.listType : 'bullet',\n\t\t\tindent: isNodeOfType(block, 'list_item') ? block.attrs.indent : 0,\n\t\t};\n\t\tif (attrs.listType === 'checklist') {\n\t\t\tattrs.checked = false;\n\t\t}\n\n\t\tconst tr = state\n\t\t\t.transaction('input')\n\t\t\t.splitBlock(sel.anchor.blockId, sel.anchor.offset, newBlockId)\n\t\t\t.setBlockType(newBlockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(createCollapsedSelection(newBlockId, 0))\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t// --- Helpers ---\n\n\tprivate isListActive(state: EditorState, listType: ListType): boolean {\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\treturn block?.type === 'list_item' && block.attrs?.listType === listType;\n\t}\n\n\tprivate getEnabledTypes(): readonly ListTypeDefinition[] {\n\t\treturn LIST_TYPE_DEFINITIONS.filter((def) => this.config.types.includes(def.type));\n\t}\n}\n","/**\n * BlockquotePlugin: registers a blockquote block type with NodeSpec,\n * toggle command, keyboard shortcut, input rule, and a toolbar button.\n */\n\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport { isCollapsed } from '../../model/Selection.js';\nimport { type NodeTypeName, nodeType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\tblockquote: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface BlockquoteConfig {\n\t/** When true, a separator is rendered after the blockquote toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: BlockquoteConfig = {};\n\n// --- Plugin ---\n\nexport class BlockquotePlugin implements Plugin {\n\treadonly id = 'blockquote';\n\treadonly name = 'Blockquote';\n\treadonly priority = 35;\n\n\tprivate readonly config: BlockquoteConfig;\n\n\tconstructor(config?: Partial<BlockquoteConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerInputRule(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'blockquote',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\ttoDOM(node) {\n\t\t\t\treturn createBlockElement('blockquote', node.id);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('toggleBlockquote', () => {\n\t\t\treturn this.toggleBlockquote(context);\n\t\t});\n\n\t\tcontext.registerCommand('setBlockquote', () => {\n\t\t\treturn this.setBlockType(context, nodeType('blockquote'));\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift->': () => context.executeCommand('toggleBlockquote'),\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: /^> $/,\n\t\t\thandler(state, _match, start, _end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, start, start + 2)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('blockquote'))\n\t\t\t\t\t.setSelection(sel)\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'blockquote',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: 'Blockquote',\n\t\t\ttooltip: `Blockquote (${formatShortcut('Mod-Shift->')})`,\n\t\t\tcommand: 'toggleBlockquote',\n\t\t\tpriority: 55,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tisActive: (state) => {\n\t\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\t\treturn block?.type === 'blockquote';\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Toggles between blockquote and paragraph.\n\t * If the block is already a blockquote, resets to paragraph.\n\t */\n\tprivate toggleBlockquote(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tif (block.type === 'blockquote') {\n\t\t\treturn this.setBlockType(context, nodeType('paragraph'));\n\t\t}\n\n\t\treturn this.setBlockType(context, nodeType('blockquote'));\n\t}\n\n\tprivate setBlockType(\n\t\tcontext: PluginContext,\n\t\ttype: NodeTypeName,\n\t\tattrs?: Record<string, string | number | boolean>,\n\t): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, type, attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n","/**\n * StrikethroughPlugin: registers a strikethrough inline mark with MarkSpec,\n * toggle command, keyboard shortcut (Mod-Shift-X), and a toolbar button.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tstrikethrough: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface StrikethroughConfig {\n\t/** When true, a separator is rendered after the strikethrough toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: StrikethroughConfig = {};\n\n// --- Plugin ---\n\nexport class StrikethroughPlugin implements Plugin {\n\treadonly id = 'strikethrough';\n\treadonly name = 'Strikethrough';\n\treadonly priority = 22;\n\n\tprivate readonly config: StrikethroughConfig;\n\n\tconstructor(config?: Partial<StrikethroughConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommand(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'strikethrough',\n\t\t\trank: 3,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement('s');\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommand(context: PluginContext): void {\n\t\tcontext.registerCommand('toggleStrikethrough', () => {\n\t\t\tconst tr = toggleMark(context.getState(), markType('strikethrough'));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-X': () => context.executeCommand('toggleStrikethrough'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'strikethrough',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: 'Strikethrough',\n\t\t\ttooltip: `Strikethrough (${formatShortcut('Mod-Shift-X')})`,\n\t\t\tcommand: 'toggleStrikethrough',\n\t\t\tpriority: 40,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tisActive: (state) => isMarkActive(state, markType('strikethrough')),\n\t\t});\n\t}\n}\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { isMarkOfType } from '../../model/AttrRegistry.js';\nimport { getBlockMarksAtOffset, hasMark } from '../../model/Document.js';\nimport { isCollapsed, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\t/** When true, a separator is rendered after the textColor toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: TextColorConfig = {};\n\n// --- Color Validation ---\n\nconst HEX_COLOR_PATTERN: RegExp = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nfunction isValidHexColor(value: string): boolean {\n\treturn HEX_COLOR_PATTERN.test(value);\n}\n\n/**\n * Validates, deduplicates, and normalizes the user-supplied color list.\n * Returns the default palette when no custom colors are provided.\n *\n * @throws {Error} if any value is not a valid hex color code.\n */\nfunction resolveColors(colors: readonly string[] | undefined): readonly string[] {\n\tif (!colors || colors.length === 0) return COLOR_PALETTE;\n\n\tconst invalid: string[] = colors.filter((c) => !isValidHexColor(c));\n\tif (invalid.length > 0) {\n\t\tthrow new Error(\n\t\t\t`TextColorPlugin: invalid hex color(s): ${invalid.join(', ')}. Expected format: #RGB or #RRGGBB.`,\n\t\t);\n\t}\n\n\tconst seen: Set<string> = new Set();\n\tconst unique: string[] = [];\n\tfor (const color of colors) {\n\t\tconst normalized: string = color.toLowerCase();\n\t\tif (!seen.has(normalized)) {\n\t\t\tseen.add(normalized);\n\t\t\tunique.push(normalized);\n\t\t}\n\t}\n\treturn unique;\n}\n\n// --- Color Palette (Google Docs style: 10 columns x 7 rows) ---\n\nconst COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t\tthis.colors = resolveColors(config?.colors);\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'textColor',\n\t\t\trank: 5,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tspan.style.color = color;\n\t\t\t\treturn span;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeTextColor', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.removeColor(context, state);\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: 'Text Color',\n\t\t\ttooltip: 'Text Color',\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpriority: 45,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderColorPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isTextColorActive(state),\n\t\t});\n\t}\n\n\t// --- State Queries ---\n\n\tprivate isTextColorActive(state: EditorState): boolean {\n\t\treturn this.getActiveColor(state) !== null;\n\t}\n\n\tprivate getActiveColor(state: EditorState): string | null {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tif (state.storedMarks) {\n\t\t\t\tconst mark = state.storedMarks.find((m) => m.type === 'textColor');\n\t\t\t\treturn mark && isMarkOfType(mark, 'textColor') ? (mark.attrs.color ?? null) : null;\n\t\t\t}\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return null;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\tconst mark = marks.find((m) => m.type === 'textColor');\n\t\t\treturn mark && isMarkOfType(mark, 'textColor') ? (mark.attrs.color ?? null) : null;\n\t\t}\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return null;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\tconst mark = marks.find((m) => m.type === 'textColor');\n\t\treturn mark && isMarkOfType(mark, 'textColor') ? (mark.attrs.color ?? null) : null;\n\t}\n\n\t// --- Color Application ---\n\n\tprivate applyColor(context: PluginContext, state: EditorState, color: string): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\t// Set stored marks with the new color\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tconst withoutColor = currentMarks.filter((m) => m.type !== 'textColor');\n\t\t\tconst newMarks = [...withoutColor, { type: markType('textColor'), attrs: { color } }];\n\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Range selection: remove existing textColor, then add new one\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\tconst mark = { type: markType('textColor'), attrs: { color } };\n\n\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\t// Remove existing textColor first, then add new one\n\t\t\t\tbuilder.removeMark(blockId, from, to, { type: markType('textColor') });\n\t\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeColor(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\t// Remove textColor from stored marks\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tif (!hasMark(currentMarks, markType('textColor'))) return false;\n\n\t\t\tconst newMarks = currentMarks.filter((m) => m.type !== 'textColor');\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Range selection: remove textColor from range\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.removeMark(blockId, from, to, { type: markType('textColor') });\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t// --- Popup Rendering ---\n\n\tprivate renderColorPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.classList.add('notectl-color-picker');\n\n\t\tconst state = context.getState();\n\t\tconst activeColor = this.getActiveColor(state);\n\n\t\t// \"Default\" button to remove color\n\t\tconst defaultBtn = document.createElement('button');\n\t\tdefaultBtn.type = 'button';\n\t\tdefaultBtn.className = 'notectl-color-picker__default';\n\t\tdefaultBtn.textContent = 'Default';\n\t\tdefaultBtn.addEventListener('mousedown', (e) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tcontext.executeCommand('removeTextColor');\n\t\t});\n\t\tcontainer.appendChild(defaultBtn);\n\n\t\t// Color grid\n\t\tconst grid = document.createElement('div');\n\t\tgrid.className = 'notectl-color-picker__grid';\n\n\t\tfor (const color of this.colors) {\n\t\t\tconst swatch = document.createElement('button');\n\t\t\tswatch.type = 'button';\n\t\t\tswatch.className = 'notectl-color-picker__swatch';\n\t\t\tif (activeColor && activeColor.toLowerCase() === color.toLowerCase()) {\n\t\t\t\tswatch.classList.add('notectl-color-picker__swatch--active');\n\t\t\t}\n\t\t\tswatch.style.backgroundColor = color;\n\t\t\tif (color === '#ffffff') {\n\t\t\t\tswatch.style.border = '1px solid #d0d0d0';\n\t\t\t}\n\t\t\tswatch.title = color;\n\n\t\t\tswatch.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.applyColor(context, context.getState(), color);\n\t\t\t});\n\n\t\t\tgrid.appendChild(swatch);\n\t\t}\n\n\t\tcontainer.appendChild(grid);\n\t}\n}\n","/**\n * HorizontalRulePlugin: registers a horizontal rule (divider) void block type\n * with NodeSpec, insert command, input rule, and toolbar button.\n */\n\nimport { createBlockNode } from '../../model/Document.js';\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport { createCollapsedSelection, isCollapsed } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\thorizontal_rule: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HorizontalRuleConfig {\n\t/** When true, a separator is rendered after the toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: HorizontalRuleConfig = {};\n\n// --- Plugin ---\n\nexport class HorizontalRulePlugin implements Plugin {\n\treadonly id = 'horizontal-rule';\n\treadonly name = 'Horizontal Rule';\n\treadonly priority = 40;\n\n\tprivate readonly config: HorizontalRuleConfig;\n\n\tconstructor(config?: Partial<HorizontalRuleConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerInputRule(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'horizontal_rule',\n\t\t\tgroup: 'block',\n\t\t\tisVoid: true,\n\t\t\ttoDOM(node) {\n\t\t\t\treturn createBlockElement('hr', node.id);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHorizontalRule', () => {\n\t\t\treturn this.insertHorizontalRule(context);\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: /^-{3,} $/,\n\t\t\thandler(state, _match, _start, end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\tconst blockIndex = state.doc.children.findIndex((b) => b.id === sel.anchor.blockId);\n\t\t\t\tif (blockIndex === -1) return null;\n\n\t\t\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, 0, end)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('horizontal_rule'))\n\t\t\t\t\t.insertNode([], blockIndex + 1, newParagraph)\n\t\t\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 11h16v2H4z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'horizontal-rule',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: 'Horizontal Rule',\n\t\t\ttooltip: 'Horizontal Rule',\n\t\t\tcommand: 'insertHorizontalRule',\n\t\t\tpriority: 60,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t});\n\t}\n\n\t/**\n\t * Inserts a horizontal rule after the current block,\n\t * followed by a new paragraph for continued editing.\n\t */\n\tprivate insertHorizontalRule(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tconst blockIndex = state.doc.children.findIndex((b) => b.id === sel.anchor.blockId);\n\t\tif (blockIndex === -1) return false;\n\n\t\tconst hrBlock = createBlockNode(nodeType('horizontal_rule'));\n\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.insertNode([], blockIndex + 1, hrBlock)\n\t\t\t.insertNode([], blockIndex + 2, newParagraph)\n\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n","/**\n * TextAlignmentPlugin: adds left/center/right/justify alignment as a block\n * attribute on paragraphs and headings. Patches their NodeSpecs to render\n * the `textAlign` attribute via inline `text-align` style and provides\n * toggle commands, keyboard shortcuts, and a toolbar dropdown.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Public Types ---\n\nexport type TextAlignment = 'left' | 'center' | 'right' | 'justify';\n\nexport interface TextAlignmentConfig {\n\t/** Which alignments to expose. Defaults to all four. */\n\treadonly alignments: readonly TextAlignment[];\n\t/** Block types that support alignment. Defaults to paragraph + heading. */\n\treadonly alignableTypes: readonly string[];\n\t/** When true, a separator is rendered after the toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\n// --- Constants ---\n\nconst DEFAULT_CONFIG: TextAlignmentConfig = {\n\talignments: ['left', 'center', 'right', 'justify'],\n\talignableTypes: ['paragraph', 'heading', 'title', 'subtitle'],\n};\n\nconst ALIGNMENT_LABELS: Readonly<Record<TextAlignment, string>> = {\n\tleft: 'Align Left',\n\tcenter: 'Align Center',\n\tright: 'Align Right',\n\tjustify: 'Justify',\n};\n\nconst ALIGNMENT_ICONS: Readonly<Record<TextAlignment, string>> = {\n\tleft: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z\"/></svg>',\n\tcenter:\n\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z\"/></svg>',\n\tright:\n\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z\"/></svg>',\n\tjustify:\n\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zM3 3v2h18V3H3z\"/></svg>',\n};\n\n// --- Plugin ---\n\nexport class TextAlignmentPlugin implements Plugin {\n\treadonly id = 'text-alignment';\n\treadonly name = 'Text Alignment';\n\treadonly priority = 90;\n\n\tprivate readonly config: TextAlignmentConfig;\n\tprivate alignableTypes!: ReadonlySet<string>;\n\n\tconstructor(config?: Partial<TextAlignmentConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.alignableTypes = new Set(this.config.alignableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerMiddleware(context);\n\t}\n\n\t// --- NodeSpec Patching ---\n\n\t/**\n\t * Patches existing NodeSpecs for alignable block types to support the\n\t * `textAlign` attribute and render it as an inline style.\n\t */\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.alignableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\ttextAlign: { default: 'left' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyAlignment(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tfor (const alignment of this.config.alignments) {\n\t\t\tcontext.registerCommand(`align${capitalize(alignment)}`, () => {\n\t\t\t\treturn this.setAlignment(context, alignment);\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tconst bindings: Record<string, () => boolean> = {};\n\n\t\tif (this.config.alignments.includes('left')) {\n\t\t\tbindings['Mod-Shift-L'] = () => context.executeCommand('alignLeft');\n\t\t}\n\t\tif (this.config.alignments.includes('center')) {\n\t\t\tbindings['Mod-Shift-E'] = () => context.executeCommand('alignCenter');\n\t\t}\n\t\tif (this.config.alignments.includes('right')) {\n\t\t\tbindings['Mod-Shift-R'] = () => context.executeCommand('alignRight');\n\t\t}\n\t\tif (this.config.alignments.includes('justify')) {\n\t\t\tbindings['Mod-Shift-J'] = () => context.executeCommand('alignJustify');\n\t\t}\n\n\t\tif (Object.keys(bindings).length > 0) {\n\t\t\tcontext.registerKeymap(bindings);\n\t\t}\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst dropdownItems = this.config.alignments.map((alignment) => ({\n\t\t\tlabel: ALIGNMENT_LABELS[alignment],\n\t\t\tcommand: `align${capitalize(alignment)}`,\n\t\t\ticon: ALIGNMENT_ICONS[alignment],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-alignment',\n\t\t\tgroup: 'block',\n\t\t\ticon: ALIGNMENT_ICONS.left,\n\t\t\tlabel: 'Text Alignment',\n\t\t\ttooltip: 'Text Alignment',\n\t\t\tcommand: 'alignLeft',\n\t\t\tpriority: 60,\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tisActive: (state) => this.isNonDefaultAlignment(state),\n\t\t\tisEnabled: (state) => this.isAlignable(state),\n\t\t});\n\t}\n\n\t// --- Middleware ---\n\n\t/**\n\t * Preserves the `textAlign` attribute when other plugins change the block\n\t * type (e.g. paragraph → heading) via `setBlockType`, which replaces attrs.\n\t */\n\tprivate registerMiddleware(context: PluginContext): void {\n\t\tcontext.registerMiddleware((tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!this.alignableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevAlign = step.previousAttrs?.textAlign;\n\t\t\t\tif (!prevAlign || prevAlign === 'left') return step;\n\n\t\t\t\t// Carry forward textAlign into new attrs\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, textAlign: prevAlign },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t});\n\t}\n\n\t// --- Alignment Logic ---\n\n\tprivate setAlignment(context: PluginContext, alignment: TextAlignment): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block || !this.alignableTypes.has(block.type)) return false;\n\n\t\tconst newAttrs = { ...block.attrs, textAlign: alignment };\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setNodeAttr([sel.anchor.blockId], newAttrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate isNonDefaultAlignment(state: EditorState): boolean {\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || !this.alignableTypes.has(block.type)) return false;\n\t\tconst align = block.attrs?.textAlign;\n\t\treturn align != null && align !== 'left';\n\t}\n\n\tprivate isAlignable(state: EditorState): boolean {\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\treturn block != null && this.alignableTypes.has(block.type);\n\t}\n}\n\n// --- Helpers ---\n\nfunction applyAlignment(el: HTMLElement, node: BlockNode): void {\n\tconst align = node.attrs?.textAlign;\n\tif (typeof align === 'string' && align !== 'left') {\n\t\tel.style.textAlign = align;\n\t}\n}\n\nfunction capitalize(s: string): string {\n\treturn s.charAt(0).toUpperCase() + s.slice(1);\n}\n","/**\n * FontPlugin: registers a font-family mark, a combobox-style toolbar selector\n * for font selection, and a developer-friendly API for registering custom fonts\n * (WOFF2, TTF, OTF).\n */\n\nimport { isMarkOfType } from '../../model/AttrRegistry.js';\nimport { getBlockMarksAtOffset, getTextChildren, hasMark } from '../../model/Document.js';\nimport type { BlockNode, Mark } from '../../model/Document.js';\nimport { isCollapsed, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tfont: { family: string };\n\t}\n}\n\n// --- Public Types ---\n\n/** Describes a single @font-face source. */\nexport interface FontFaceDescriptor {\n\t/** CSS `src` value, e.g. `\"url('/fonts/My.woff2') format('woff2')\"`. */\n\treadonly src: string;\n\t/** Font weight, e.g. `'400'` or `'300 700'` for variable fonts. */\n\treadonly weight?: string;\n\t/** Font style, e.g. `'normal'` or `'italic'`. */\n\treadonly style?: string;\n\t/** Font display strategy. Defaults to `'swap'`. */\n\treadonly display?: string;\n}\n\n/** Defines a font available in the editor. */\nexport interface FontDefinition {\n\t/** Display name shown in the toolbar dropdown. */\n\treadonly name: string;\n\t/** CSS `font-family` value, e.g. `\"'Fira Code', monospace\"`. */\n\treadonly family: string;\n\t/** Font category for grouping in the UI. */\n\treadonly category?: 'serif' | 'sans-serif' | 'monospace' | 'display' | 'handwriting';\n\t/**\n\t * Optional `@font-face` descriptors. When provided, the plugin\n\t * auto-injects the corresponding CSS rules into the document.\n\t */\n\treadonly fontFaces?: readonly FontFaceDescriptor[];\n}\n\n// --- Configuration ---\n\nexport interface FontConfig {\n\t/**\n\t * Fonts available in the editor. System fonts require no `fontFaces`.\n\t * Custom fonts with `fontFaces` get their `@font-face` rules auto-injected.\n\t *\n\t * Use `STARTER_FONTS` for a pre-configured set of fonts:\n\t * ```ts\n\t * new FontPlugin({ fonts: [...STARTER_FONTS] })\n\t * ```\n\t */\n\treadonly fonts: readonly FontDefinition[];\n\t/**\n\t * Name of the font that acts as the editor's default.\n\t * Selecting this font removes the mark (since the editor already uses it).\n\t * Defaults to the first font in the list.\n\t */\n\treadonly defaultFont?: string;\n\t/** When true, a separator is rendered after the font toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\n// --- Plugin ---\n\nexport class FontPlugin implements Plugin {\n\treadonly id = 'font';\n\treadonly name = 'Font';\n\treadonly priority = 22;\n\n\tprivate readonly config: FontConfig;\n\tprivate injectedStyleElement: HTMLStyleElement | null = null;\n\tprivate context: PluginContext | null = null;\n\tprivate comboLabel: HTMLSpanElement | null = null;\n\n\tconstructor(config: FontConfig) {\n\t\tthis.config = config;\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.context = context;\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.injectFontFaces();\n\t}\n\n\tdestroy(): void {\n\t\tthis.injectedStyleElement?.remove();\n\t\tthis.injectedStyleElement = null;\n\t\tthis.context = null;\n\t\tthis.comboLabel = null;\n\t}\n\n\tonStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\tthis.updateComboLabel(newState);\n\t}\n\n\t// --- Schema ---\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'font',\n\t\t\trank: 6,\n\t\t\tattrs: {\n\t\t\t\tfamily: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span: HTMLElement = document.createElement('span');\n\t\t\t\tconst family: string = mark.attrs?.family ?? '';\n\t\t\t\tif (family) {\n\t\t\t\t\tspan.style.fontFamily = family;\n\t\t\t\t}\n\t\t\t\treturn span;\n\t\t\t},\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeFont', () => {\n\t\t\tconst state: EditorState = context.getState();\n\t\t\treturn this.removeFont(context, state);\n\t\t});\n\n\t\tcontext.registerCommand('setFont', () => {\n\t\t\treturn false;\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate get defaultFont(): FontDefinition {\n\t\tif (this.config.defaultFont) {\n\t\t\tconst found: FontDefinition | undefined = this.config.fonts.find(\n\t\t\t\t(f) => f.name === this.config.defaultFont,\n\t\t\t);\n\t\t\tif (found) return found;\n\t\t}\n\t\tconst first: FontDefinition | undefined = this.config.fonts[0];\n\t\tif (!first) throw new Error('FontPlugin: fonts list is empty');\n\t\treturn first;\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\t// The icon content renders as a combobox label + dropdown arrow.\n\t\t// The actual label text is updated via onStateChange → updateComboLabel.\n\t\tconst defaultName: string = this.defaultFont.name;\n\t\tconst label: string = `<span class=\"notectl-font-select__label\" data-font-label>${defaultName}</span>`;\n\t\tconst arrow = '<span class=\"notectl-font-select__arrow\">\\u25BE</span>';\n\t\tconst icon = `${label}${arrow}`;\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'font',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: 'Font',\n\t\t\ttooltip: 'Font Family',\n\t\t\tcommand: 'removeFont',\n\t\t\tpriority: 5,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderFontPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isFontActive(state),\n\t\t});\n\t}\n\n\tprivate updateComboLabel(state: EditorState): void {\n\t\t// Lazily find the label element in the DOM\n\t\tif (!this.comboLabel) {\n\t\t\tconst container: HTMLElement | undefined = this.context?.getPluginContainer('top');\n\t\t\tif (!container) return;\n\t\t\tthis.comboLabel = container.querySelector<HTMLSpanElement>('[data-font-label]') ?? null;\n\t\t\tif (!this.comboLabel) return;\n\t\t}\n\n\t\tconst activeFamily: string | null = this.getActiveFont(state);\n\t\tconst displayName: string = this.resolveFontName(activeFamily);\n\t\tthis.comboLabel.textContent = displayName;\n\t}\n\n\tprivate resolveFontName(family: string | null): string {\n\t\tif (!family) return this.defaultFont.name;\n\t\tconst match: FontDefinition | undefined = this.config.fonts.find((f) => f.family === family);\n\t\treturn match?.name ?? (family.split(',')[0] ?? '').trim().replace(/'/g, '');\n\t}\n\n\t// --- State Queries ---\n\n\tprivate isFontActive(state: EditorState): boolean {\n\t\treturn this.getActiveFont(state) !== null;\n\t}\n\n\tgetActiveFont(state: EditorState): string | null {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tif (state.storedMarks) {\n\t\t\t\tconst mark = state.storedMarks.find((m) => m.type === 'font');\n\t\t\t\treturn mark && isMarkOfType(mark, 'font') ? (mark.attrs.family ?? null) : null;\n\t\t\t}\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return null;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\tconst mark = marks.find((m) => m.type === 'font');\n\t\t\treturn mark && isMarkOfType(mark, 'font') ? (mark.attrs.family ?? null) : null;\n\t\t}\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return null;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\tconst mark = marks.find((m) => m.type === 'font');\n\t\treturn mark && isMarkOfType(mark, 'font') ? (mark.attrs.family ?? null) : null;\n\t}\n\n\t// --- Font Application ---\n\n\tapplyFont(context: PluginContext, state: EditorState, family: string): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tconst withoutFont = currentMarks.filter((m) => m.type !== 'font');\n\t\t\tconst newMarks = [...withoutFont, { type: markType('font'), attrs: { family } }];\n\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx: number = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx: number = blockOrder.indexOf(range.to.blockId);\n\n\t\tconst mark = { type: markType('font'), attrs: { family } };\n\n\t\tfor (let i: number = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen: number = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from: number = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to: number = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tconst existing: Mark | undefined = this.findFontMarkInRange(block, from, to);\n\t\t\t\tif (existing) {\n\t\t\t\t\tbuilder.removeMark(blockId, from, to, existing);\n\t\t\t\t}\n\t\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeFont(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tif (!hasMark(currentMarks, markType('font'))) return false;\n\n\t\t\tconst newMarks = currentMarks.filter((m) => m.type !== 'font');\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx: number = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx: number = blockOrder.indexOf(range.to.blockId);\n\n\t\tfor (let i: number = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen: number = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from: number = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to: number = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tconst existing: Mark | undefined = this.findFontMarkInRange(block, from, to);\n\t\t\t\tif (existing) {\n\t\t\t\t\tbuilder.removeMark(blockId, from, to, existing);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t/** Finds the first font mark in a block's text range (for proper step inversion). */\n\tprivate findFontMarkInRange(block: BlockNode, from: number, to: number): Mark | undefined {\n\t\tconst textChildren = getTextChildren(block);\n\t\tlet pos = 0;\n\t\tfor (const node of textChildren) {\n\t\t\tconst nodeEnd: number = pos + node.text.length;\n\t\t\tif (nodeEnd > from && pos < to) {\n\t\t\t\tconst fontMark: Mark | undefined = node.marks.find((m) => m.type === 'font');\n\t\t\t\tif (fontMark) return fontMark;\n\t\t\t}\n\t\t\tpos = nodeEnd;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// --- @font-face Injection ---\n\n\tprivate injectFontFaces(): void {\n\t\tconst rules: string[] = [];\n\n\t\tfor (const font of this.config.fonts) {\n\t\t\tif (!font.fontFaces?.length) continue;\n\n\t\t\tfor (const face of font.fontFaces) {\n\t\t\t\tconst familyName: string = (font.family.split(',')[0] ?? '').trim().replace(/'/g, '');\n\t\t\t\tconst declarations: string[] = [`font-family: '${familyName}'`, `src: ${face.src}`];\n\t\t\t\tif (face.weight) {\n\t\t\t\t\tdeclarations.push(`font-weight: ${face.weight}`);\n\t\t\t\t}\n\t\t\t\tif (face.style) {\n\t\t\t\t\tdeclarations.push(`font-style: ${face.style}`);\n\t\t\t\t}\n\t\t\t\tdeclarations.push(`font-display: ${face.display ?? 'swap'}`);\n\n\t\t\t\trules.push(`@font-face {\\n\\t${declarations.join(';\\n\\t')};\\n}`);\n\t\t\t}\n\t\t}\n\n\t\tif (rules.length === 0) return;\n\n\t\tconst style: HTMLStyleElement = document.createElement('style');\n\t\tstyle.setAttribute('data-notectl-fonts', '');\n\t\tstyle.textContent = rules.join('\\n\\n');\n\t\tdocument.head.appendChild(style);\n\t\tthis.injectedStyleElement = style;\n\t}\n\n\t// --- Popup Rendering ---\n\n\tprivate dismissPopup(): void {\n\t\t// Trigger the ToolbarPlugin's outside-click handler to close the popup.\n\t\tsetTimeout(() => {\n\t\t\tdocument.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));\n\t\t}, 0);\n\t}\n\n\tprivate renderFontPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.classList.add('notectl-font-picker');\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst activeFont: string | null = this.getActiveFont(state);\n\t\tconst defaultFamily: string = this.defaultFont.family;\n\n\t\tconst list: HTMLDivElement = document.createElement('div');\n\t\tlist.className = 'notectl-font-picker__list';\n\n\t\tfor (const font of this.config.fonts) {\n\t\t\tconst isDefault: boolean = font.family === defaultFamily;\n\t\t\tconst isActive: boolean = isDefault\n\t\t\t\t? !activeFont || activeFont === font.family\n\t\t\t\t: activeFont === font.family;\n\n\t\t\tconst item: HTMLButtonElement = this.createFontItem(\n\t\t\t\tfont.name,\n\t\t\t\tfont.family,\n\t\t\t\tisActive,\n\t\t\t\t(e: MouseEvent) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tif (isDefault) {\n\t\t\t\t\t\tcontext.executeCommand('removeFont');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.applyFont(context, context.getState(), font.family);\n\t\t\t\t\t}\n\t\t\t\t\tthis.dismissPopup();\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (font.category) {\n\t\t\t\titem.setAttribute('data-category', font.category);\n\t\t\t}\n\n\t\t\tlist.appendChild(item);\n\t\t}\n\n\t\tcontainer.appendChild(list);\n\t}\n\n\tprivate createFontItem(\n\t\tname: string,\n\t\tfamily: string,\n\t\tisActive: boolean,\n\t\thandler: (e: MouseEvent) => void,\n\t): HTMLButtonElement {\n\t\tconst item: HTMLButtonElement = document.createElement('button');\n\t\titem.type = 'button';\n\t\titem.className = 'notectl-font-picker__item';\n\n\t\tif (isActive) {\n\t\t\titem.classList.add('notectl-font-picker__item--active');\n\t\t}\n\n\t\t// Checkmark indicator\n\t\tconst check: HTMLSpanElement = document.createElement('span');\n\t\tcheck.className = 'notectl-font-picker__check';\n\t\tcheck.textContent = isActive ? '\\u2713' : '';\n\t\titem.appendChild(check);\n\n\t\t// Font name label (rendered in the font itself for preview)\n\t\tconst label: HTMLSpanElement = document.createElement('span');\n\t\tlabel.className = 'notectl-font-picker__label';\n\t\tlabel.textContent = name;\n\t\tif (family) {\n\t\t\tlabel.style.fontFamily = family;\n\t\t}\n\t\titem.appendChild(label);\n\n\t\titem.addEventListener('mousedown', handler);\n\t\treturn item;\n\t}\n}\n","/**\n * FontSizePlugin: registers a fontSize mark with attrs, a combobox-style\n * toolbar selector with WCAG-accessible popup, and commands for\n * increasing / decreasing font size.\n */\n\nimport { isMarkOfType } from '../../model/AttrRegistry.js';\nimport { getBlockMarksAtOffset, hasMark } from '../../model/Document.js';\nimport { isCollapsed, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tfontSize: { size: string };\n\t}\n}\n\n// --- Constants ---\n\n/** Default preset sizes shown in the font size dropdown. */\nexport const DEFAULT_FONT_SIZES: readonly number[] = [\n\t8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 64, 72, 96,\n];\n\nconst DEFAULT_FONT_SIZE = 16;\nconst MIN_CUSTOM_SIZE = 1;\nconst MAX_CUSTOM_SIZE = 400;\n\n// --- Configuration ---\n\nexport interface FontSizeConfig {\n\t/**\n\t * Preset sizes shown in the font size dropdown.\n\t * Must contain positive integers. Values are sorted and deduplicated automatically.\n\t * Defaults to {@link DEFAULT_FONT_SIZES} when omitted or empty.\n\t */\n\treadonly sizes?: readonly number[];\n\t/**\n\t * The base font size that text has when no fontSize mark is applied.\n\t * Shown as the initial value in the toolbar combo and used as the\n\t * \"neutral\" size — selecting it removes the mark instead of applying one.\n\t * Defaults to 16.\n\t */\n\treadonly defaultSize?: number;\n\t/** When true, a separator is rendered after the fontSize toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: FontSizeConfig = {};\n\n// --- Plugin ---\n\nexport class FontSizePlugin implements Plugin {\n\treadonly id = 'fontSize';\n\treadonly name = 'Font Size';\n\treadonly priority = 21;\n\n\tprivate readonly config: FontSizeConfig;\n\tprivate readonly sizes: readonly number[];\n\tprivate readonly defaultSize: number;\n\tprivate context: PluginContext | null = null;\n\tprivate comboLabel: HTMLSpanElement | null = null;\n\n\tconstructor(config?: Partial<FontSizeConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t\tthis.sizes = resolveSizes(config?.sizes);\n\t\tthis.defaultSize = resolveDefaultSize(config?.defaultSize);\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.context = context;\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tdestroy(): void {\n\t\tthis.context = null;\n\t\tthis.comboLabel = null;\n\t}\n\n\tonStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\tthis.updateComboLabel(newState);\n\t}\n\n\t// --- Schema ---\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'fontSize',\n\t\t\trank: 4,\n\t\t\tattrs: {\n\t\t\t\tsize: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span: HTMLElement = document.createElement('span');\n\t\t\t\tconst size: string = mark.attrs?.size ?? '';\n\t\t\t\tif (size) {\n\t\t\t\t\tspan.style.fontSize = size;\n\t\t\t\t}\n\t\t\t\treturn span;\n\t\t\t},\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeFontSize', () => {\n\t\t\tconst state: EditorState = context.getState();\n\t\t\treturn this.removeFontSize(context, state);\n\t\t});\n\n\t\tcontext.registerCommand('setFontSize', () => {\n\t\t\treturn false;\n\t\t});\n\n\t\tcontext.registerCommand('increaseFontSize', () => {\n\t\t\tconst state: EditorState = context.getState();\n\t\t\treturn this.stepFontSize(context, state, 'up');\n\t\t});\n\n\t\tcontext.registerCommand('decreaseFontSize', () => {\n\t\t\tconst state: EditorState = context.getState();\n\t\t\treturn this.stepFontSize(context, state, 'down');\n\t\t});\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-+': () => {\n\t\t\t\tconst state: EditorState = context.getState();\n\t\t\t\treturn this.stepFontSize(context, state, 'up');\n\t\t\t},\n\t\t\t'Mod-Shift-_': () => {\n\t\t\t\tconst state: EditorState = context.getState();\n\t\t\t\treturn this.stepFontSize(context, state, 'down');\n\t\t\t},\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon: string = `<span class=\"notectl-font-size-select__label\" data-font-size-label>${this.defaultSize}</span><span class=\"notectl-font-size-select__arrow\">\\u25BE</span>`;\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'fontSize',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: 'Font Size',\n\t\t\ttooltip: 'Font Size',\n\t\t\tcommand: 'removeFontSize',\n\t\t\tpriority: 6,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderFontSizePopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isFontSizeActive(state),\n\t\t});\n\t}\n\n\tprivate updateComboLabel(state: EditorState): void {\n\t\tif (!this.comboLabel) {\n\t\t\tconst container: HTMLElement | undefined = this.context?.getPluginContainer('top');\n\t\t\tif (!container) return;\n\t\t\tthis.comboLabel = container.querySelector<HTMLSpanElement>('[data-font-size-label]') ?? null;\n\t\t\tif (!this.comboLabel) return;\n\t\t}\n\n\t\tconst activeSize: number = this.getActiveSizeNumeric(state);\n\t\tthis.comboLabel.textContent = String(activeSize);\n\t}\n\n\t// --- State Queries ---\n\n\tprivate isFontSizeActive(state: EditorState): boolean {\n\t\treturn this.getActiveSize(state) !== null;\n\t}\n\n\tprivate getActiveSize(state: EditorState): string | null {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tif (state.storedMarks) {\n\t\t\t\tconst mark = state.storedMarks.find((m) => m.type === 'fontSize');\n\t\t\t\treturn mark && isMarkOfType(mark, 'fontSize') ? (mark.attrs.size ?? null) : null;\n\t\t\t}\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return null;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\tconst mark = marks.find((m) => m.type === 'fontSize');\n\t\t\treturn mark && isMarkOfType(mark, 'fontSize') ? (mark.attrs.size ?? null) : null;\n\t\t}\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return null;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\tconst mark = marks.find((m) => m.type === 'fontSize');\n\t\treturn mark && isMarkOfType(mark, 'fontSize') ? (mark.attrs.size ?? null) : null;\n\t}\n\n\tprivate getActiveSizeNumeric(state: EditorState): number {\n\t\tconst raw: string | null = this.getActiveSize(state);\n\t\tif (!raw) return this.defaultSize;\n\t\tconst parsed: number = Number.parseInt(raw, 10);\n\t\treturn Number.isNaN(parsed) ? this.defaultSize : parsed;\n\t}\n\n\t// --- Font Size Application ---\n\n\tprivate applyFontSize(context: PluginContext, state: EditorState, size: string): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tconst withoutSize = currentMarks.filter((m) => m.type !== 'fontSize');\n\t\t\tconst newMarks = [...withoutSize, { type: markType('fontSize'), attrs: { size } }];\n\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx: number = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx: number = blockOrder.indexOf(range.to.blockId);\n\n\t\tconst mark = { type: markType('fontSize'), attrs: { size } };\n\n\t\tfor (let i: number = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen: number = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from: number = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to: number = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.removeMark(blockId, from, to, {\n\t\t\t\t\ttype: markType('fontSize'),\n\t\t\t\t});\n\t\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeFontSize(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tif (!hasMark(currentMarks, markType('fontSize'))) return false;\n\n\t\t\tconst newMarks = currentMarks.filter((m) => m.type !== 'fontSize');\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx: number = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx: number = blockOrder.indexOf(range.to.blockId);\n\n\t\tfor (let i: number = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen: number = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from: number = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to: number = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.removeMark(blockId, from, to, {\n\t\t\t\t\ttype: markType('fontSize'),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t// --- Increase / Decrease ---\n\n\tprivate stepFontSize(\n\t\tcontext: PluginContext,\n\t\tstate: EditorState,\n\t\tdirection: 'up' | 'down',\n\t): boolean {\n\t\tconst current: number = this.getActiveSizeNumeric(state);\n\t\tconst next: number | null = this.getNextPresetSize(current, direction);\n\t\tif (next === null) return false;\n\n\t\tif (next === this.defaultSize) {\n\t\t\treturn this.removeFontSize(context, state);\n\t\t}\n\t\treturn this.applyFontSize(context, state, `${next}px`);\n\t}\n\n\tprivate getNextPresetSize(current: number, direction: 'up' | 'down'): number | null {\n\t\tif (direction === 'up') {\n\t\t\tfor (const size of this.sizes) {\n\t\t\t\tif (size > current) return size;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tfor (let i: number = this.sizes.length - 1; i >= 0; i--) {\n\t\t\tconst size: number | undefined = this.sizes[i];\n\t\t\tif (size !== undefined && size < current) return size;\n\t\t}\n\t\treturn null;\n\t}\n\n\t// --- Popup Rendering ---\n\n\tprivate dismissPopup(): void {\n\t\tsetTimeout(() => {\n\t\t\tdocument.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));\n\t\t}, 0);\n\t}\n\n\tprivate renderFontSizePopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.classList.add('notectl-font-size-picker');\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst currentSize: number = this.getActiveSizeNumeric(state);\n\t\tlet focusedIndex = -1;\n\n\t\t// --- Custom Input ---\n\t\tconst inputWrapper: HTMLDivElement = document.createElement('div');\n\t\tinputWrapper.className = 'notectl-font-size-picker__input-wrapper';\n\n\t\tconst input: HTMLInputElement = document.createElement('input');\n\t\tinput.type = 'number';\n\t\tinput.className = 'notectl-font-size-picker__input';\n\t\tinput.min = String(MIN_CUSTOM_SIZE);\n\t\tinput.max = String(MAX_CUSTOM_SIZE);\n\t\tinput.value = String(currentSize);\n\t\tinput.setAttribute('aria-label', 'Custom font size');\n\n\t\tinputWrapper.appendChild(input);\n\t\tcontainer.appendChild(inputWrapper);\n\n\t\t// --- List ---\n\t\tconst list: HTMLDivElement = document.createElement('div');\n\t\tlist.className = 'notectl-font-size-picker__list';\n\t\tlist.setAttribute('role', 'listbox');\n\t\tlist.setAttribute('aria-label', 'Font sizes');\n\n\t\tconst items: HTMLButtonElement[] = [];\n\n\t\tfor (let idx = 0; idx < this.sizes.length; idx++) {\n\t\t\tconst size: number | undefined = this.sizes[idx];\n\t\t\tif (size === undefined) continue;\n\t\t\tconst isActive: boolean = size === currentSize;\n\t\t\tconst itemId: string = `notectl-font-size-option-${size}`;\n\n\t\t\tconst item: HTMLButtonElement = document.createElement('button');\n\t\t\titem.type = 'button';\n\t\t\titem.id = itemId;\n\t\t\titem.className = 'notectl-font-size-picker__item';\n\t\t\titem.setAttribute('role', 'option');\n\t\t\titem.setAttribute('aria-selected', String(isActive));\n\n\t\t\tif (isActive) {\n\t\t\t\titem.classList.add('notectl-font-size-picker__item--active');\n\t\t\t}\n\n\t\t\tconst check: HTMLSpanElement = document.createElement('span');\n\t\t\tcheck.className = 'notectl-font-size-picker__check';\n\t\t\tcheck.textContent = isActive ? '\\u2713' : '';\n\t\t\titem.appendChild(check);\n\n\t\t\tconst label: HTMLSpanElement = document.createElement('span');\n\t\t\tlabel.className = 'notectl-font-size-picker__label';\n\t\t\tlabel.textContent = String(size);\n\t\t\titem.appendChild(label);\n\n\t\t\titem.addEventListener('mousedown', (e: MouseEvent) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.selectSize(context, size);\n\t\t\t\tthis.dismissPopup();\n\t\t\t});\n\n\t\t\titems.push(item);\n\t\t\tlist.appendChild(item);\n\t\t}\n\n\t\tcontainer.appendChild(list);\n\n\t\t// --- Scroll active item into view ---\n\t\tconst activeIdx: number = this.sizes.indexOf(currentSize);\n\t\tif (activeIdx >= 0) {\n\t\t\tconst activeItem: HTMLButtonElement | undefined = items[activeIdx];\n\t\t\tif (activeItem) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tactiveItem.scrollIntoView({ block: 'nearest' });\n\t\t\t\t});\n\t\t\t\tlist.setAttribute('aria-activedescendant', activeItem.id);\n\t\t\t}\n\t\t}\n\n\t\t// --- Keyboard helpers ---\n\t\tconst setFocusedIndex = (idx: number): void => {\n\t\t\tif (focusedIndex >= 0 && focusedIndex < items.length) {\n\t\t\t\titems[focusedIndex]?.classList.remove('notectl-font-size-picker__item--focused');\n\t\t\t}\n\t\t\tfocusedIndex = idx;\n\t\t\tconst focused: HTMLButtonElement | undefined = items[focusedIndex];\n\t\t\tif (focusedIndex >= 0 && focusedIndex < items.length && focused) {\n\t\t\t\tfocused.classList.add('notectl-font-size-picker__item--focused');\n\t\t\t\tfocused.scrollIntoView({ block: 'nearest' });\n\t\t\t\tlist.setAttribute('aria-activedescendant', focused.id);\n\t\t\t}\n\t\t};\n\n\t\t// --- Input Events ---\n\t\tinput.addEventListener('keydown', (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Enter') {\n\t\t\t\te.preventDefault();\n\t\t\t\tconst val: number = Number.parseInt(input.value, 10);\n\t\t\t\tif (!Number.isNaN(val) && val >= MIN_CUSTOM_SIZE && val <= MAX_CUSTOM_SIZE) {\n\t\t\t\t\tthis.selectSize(context, val);\n\t\t\t\t\tthis.dismissPopup();\n\t\t\t\t}\n\t\t\t} else if (e.key === 'ArrowDown') {\n\t\t\t\te.preventDefault();\n\t\t\t\tsetFocusedIndex(0);\n\t\t\t\titems[0]?.focus();\n\t\t\t} else if (e.key === 'Escape') {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.dismissPopup();\n\t\t\t}\n\t\t});\n\n\t\t// --- List Keyboard Navigation ---\n\t\tlist.addEventListener('keydown', (e: KeyboardEvent) => {\n\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\te.preventDefault();\n\t\t\t\tif (focusedIndex < items.length - 1) {\n\t\t\t\t\tsetFocusedIndex(focusedIndex + 1);\n\t\t\t\t\titems[focusedIndex]?.focus();\n\t\t\t\t}\n\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\te.preventDefault();\n\t\t\t\tif (focusedIndex > 0) {\n\t\t\t\t\tsetFocusedIndex(focusedIndex - 1);\n\t\t\t\t\titems[focusedIndex]?.focus();\n\t\t\t\t} else {\n\t\t\t\t\tsetFocusedIndex(-1);\n\t\t\t\t\tinput.focus();\n\t\t\t\t}\n\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\te.preventDefault();\n\t\t\t\tconst selectedSize: number | undefined = this.sizes[focusedIndex];\n\t\t\t\tif (focusedIndex >= 0 && focusedIndex < this.sizes.length && selectedSize !== undefined) {\n\t\t\t\t\tthis.selectSize(context, selectedSize);\n\t\t\t\t\tthis.dismissPopup();\n\t\t\t\t}\n\t\t\t} else if (e.key === 'Escape') {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.dismissPopup();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate selectSize(context: PluginContext, size: number): void {\n\t\tif (size === this.defaultSize) {\n\t\t\tcontext.executeCommand('removeFontSize');\n\t\t} else {\n\t\t\tthis.applyFontSize(context, context.getState(), `${size}px`);\n\t\t}\n\t}\n}\n\n// --- Helpers ---\n\nfunction resolveSizes(sizes: readonly number[] | undefined): readonly number[] {\n\tif (!sizes || sizes.length === 0) return DEFAULT_FONT_SIZES;\n\tconst unique: number[] = [...new Set(sizes)].filter((n) => Number.isInteger(n) && n > 0);\n\tunique.sort((a, b) => a - b);\n\treturn unique.length > 0 ? unique : DEFAULT_FONT_SIZES;\n}\n\nfunction resolveDefaultSize(size: number | undefined): number {\n\tif (size === undefined) return DEFAULT_FONT_SIZE;\n\treturn Number.isInteger(size) && size > 0 ? size : DEFAULT_FONT_SIZE;\n}\n","/**\n * Embedded starter font data for the FontPlugin.\n * Contains FiraCode (monospace) and FiraSans (sans-serif) as WOFF2 data URIs.\n * Tree-shakeable: only imported when used.\n */\n\nimport type { FontDefinition } from './FontPlugin.js';\n\nexport const FIRA_CODE_WOFF2_DATA: string =\n\t'data:font/woff2;base64,d09GMgABAAAAAZNIABEAAAAEa0AAAZLfAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoN0G78mHIHFRgZgAIGGeAiBKAmcFREICovkBIqqawu/PAABNgIkA74yBCAFiWQHgbdzDIFWW8Dtswj+E469f8gdO2hEzai1tPocbh+igNT/xO5EOob3FItB1U3n2IQjeCFLa426gJ62+MR1G1JQW2U4tb+d/f///////////787WcSYNrsHs3cHBwgaFBWtxqhRk8amSb+fb9+FRulDEDEWCCVTVQsf2MAL85x42Yamw3QGj/Zh2s/bxbDszMSqXrOqxax0p84sx2GUNVl6ac4NM9/0CzTKvK1BNCjUtNVNNWb3TbVyKLuqWyG573Tq1KnuHw+bhexX1BaFaYMFL56E96VmZpodzHHak5gfYZrvbUFSRMKUdYT3hCHQJBlMGHgC5VGcTRaCKvlsMNB7eNF5eDRxH2ABwVAEGExU5r1ReD70Ax0uytXplpPLiS9TxDYivHYipe+jmbxigU5WKbxdHlzWmImNvMilqFx8jgnSYCqpGnWjXJmBVHaEgaBcI6RXsUM3zoTP0wzMaIP+UazhMRd38SMGLWZBN1523C6xx7ut8HrGa9RJ9U7VqA7UJ/qjul8dfjZN2yDlL1SLF9ncmoaK11/zU358jrJGKXlDr0+z83rS3+Lzc9xismjGywptVzpvmPl21SI9JUx+TfCPtN8i6p20QhvfRcxg8S7naiTeNMvv0u8ek1znLuEEfxc9rktc79gjTMblRGyjOqG6o3qgq3csdGbSmrWVjSqzGVFg7faRx3+XyW3MTUhikGGsqkkrkx7dqdP9Sz0sqgpJ/pefi9ojIg4dbIoatkfQrw5UC93cB/HGqoeJdAoBP+PxaSIblCvFZkhK90utR+ddUJfMbXE5Yiq7qfiSQVJSkuI3Ygh6zOhDrPW1ll4c/mgh69Nd/JEm/0oOoOMXdvx8EyYtK486ycZrLzPLpBdJfPr8VEdlxrvGGGrFY+nSZNPIQfHa+sy8nIvT2df4e62mqfi4HUuVVG909nT/rpS4/t80AU1C6ZzoTp3Z+EzpUGY403uVZE4eA6IcRg3wN9GVGDIr0xLb6Vc85VN+/ed52/xfa5997p0ZhmEYhioiIgIiIs0SJUqQKCk/4eWRhqUTn8/kGxJLI0SJIVhqTLMXYmz9Jab0ZowtXZkhvm4/b4+36zoTFqVdx5JyRJtEX4mlSAl9siVy5Fhad3It1plcXc7kjnvdd+W6OyV0idw7ANuUlbNnF6ioGKSF0CLVKiASioGgKEYUGDVr07lwm7Hub/uqv+/7vnouvucgXTOEUsLDb2peTLgJ+2pHef77OfLc5P2f3RIqVEAogYUDllWrisailBWmqpZtZzL//Dafveth6KJYFGbxKCPBRowzESMK7TUrjGLF8WBEseLwi4+NxaI4HLSHsYz53KoPCmijG8oRLUVadGd2vU4tvPBH9y7JPAx21uCrH/vP0327Z/5b4gAKieWB3aoAeRIKy0eJOJVIgUs6K01y9+A5hiUGacbOkkPgLJBtdf2XzyVQCxR4hIm12iUilVCY7jF6ephOtuniTTRZXXM5ceg/1rbxBCuFIUdNhBBoZJrou29Ixnz9qZVwaSLSBzmgW7YrENhp/9vbeaz/n9O+7qMMICSggAKEMzKunZ0e+vc3/uQTrQviDqKNJot3CyDAoHXt1H5uEB/Gz+eVWyhb49gzjLCArstzexYwUOtkkIePaoxyMJ8Qo2oA5jlnmLqbuDNxJvKM42psTMVUTNdUr+XGVE9Nnt/lxXF3+buLt1d49MD+HktxbbGCoSnBT+QXZ4emtrrdLc45cremlJTB+EM8/ZZVjxYHmmG0k+xOxM9MOP89OCd9IlLvD8RagZo3S4Y4oPn/X6ZZ995n/o+IzIQnTCYBsMgyLFZ5mUKXoap9pqIbDUnnpNBjkllUdTBmfLulBmOAM1tjNzsttV6NccPr9u8f8AQSiAJRI0SIEPzgV+yZVcSmfh37lvnvra/d//+1pbMR1SE8hlmosAlE/VRVKieTY4SaE156yq/4vn2Eqk3fXnsUm1tvHp9k0xSr2ES8/iY15vb/XIAUMkLCR8q6ChCIAaYbzOIN0ODwAL5qb7sjTffbP0NKu2RJ4QQKH6O0GM3+y2JWD85QmzrzItpOyZdlR6uu5TK/psg6nW6P0rDaWaseOx0mDAfw0ApFzRm8S1KWdbjzRlUZQKlIGNGpJvRj/jIvquSUk+EmopxYRPkWFeYUsj9b1FvUdNWDOPz7P4bm5d0ksvUdk0RyO3V+kwLljJ9QQBrxw7//+/3jz5WdZJdQOGKJqAglgqrrqCbhyq6OPiA5dIj3vX/uThZtVsUolkGGeGQcTJYPCIv27r9pv/0ASAKBALM3+xTdABrAzNvd7xx5NMbIBeHV5IooZQkJwjnwL9wk7QDQTdixkKgHgdrKHXtNtIf/fA/kIBalpeuilOkCyd534GbPNzyOWGpZdqEe9mvpQjOZ3X3/TFFPRIgdwILlWiY5llolwnmEU/CtoEaDFZZ7gVKekTnVusQwZvuc6TYiT0F53jxWiEXLRhuuraQ41IPzBOE19/2p89Vr2b5Ola2PnQKfpwJClJRgx61srcnUO9lBsBP+wORAAOPy7hkzkzZXwHnOcYnQj6rW9wCSEvUeQEjWXS76FIsqJYCggi3Jytb4zziTeo1129n/ug05zcyGEBR291d3Fweobhxd2oAsQJRfTQ3HkQGZxtfZMYZQ6aY4vsZWyl4RtoFg5TrP4u9N3d25lDeffqgaVsRrhW5TC7VGF8FQowAHqBe7YEhjEjBtdn9fpfr99t5MFJEFkhIgymFIeh7UDnVLz+5Br1/sAXCSZHfHG8fdC8e+I/Oce+tW3ptZWcisAlBZAAkWSIkESIpEkRQFUHZlZlUxqwDRIMXXDQ7upga/0JslW90h90gBkixT02tJlqM9dv95Wk2y/zCN+3mxlP2neT0vF3+/+Pvl367/39fUuv4vOV7ZQ1Y84Czai87iDF8JTwunvfLh9rpbsrpbUtySIS05SiQFVlJgW5InI9kDjpTKmjJRgDzA1C0F2lKSlZ1M1jCTmgkMQTLEfFri8x6OeDsA0GmPt70eGO/L8+DS6eSV2Rn2CeU69j/FKVqFRlm0xeF/qVqlAoEW1xibbxJwdNZkkdSvP54EoAkNjVRLDbX2rIssfjdEAaBmSzrrokkvyC+Ig7uN7v6nlnTG/nM335GvFXZmu2GVK0FXGdf/I1n6KhvZXr19tVypxVnkEBYAD3pTSuF5wcFHYQCgIZocyDOn2rwtQu4ELShqtuzgkNtuIhw4IiyPMDgF7nMocI8CR+FIeTTColwKlbhIHvsbJZ57/C/VtMXu2y9mOVCOuWnfwum7u648YYFZmQAUSCpeSNM7pMozpOMenTCqXGpc+VyF2Lo20W97qhqEJ5jihNB+W7bd8c/PPZmdQ3PhzUKUixBmZ2HhQyMqSqhMKpphm0M4AJC+9KCViaH/NDPT33WLug+aKJBxQbZ0NotFTq0gzOJJBWoQBnsWnD1jkzCnLFwzezwlNL5CHqmNNO2mxLLsyLjkih/jHp7eZbNb8q9Q2lDlGoW/F4VUm5nkeiR0twrj7k7xIlEKIyQ83/++3ulOn53xVYZRxalY86dbGaCa8aIg7guHkDjDQhjJ4k/DjzzZgejAATyWcD/bN+fPfhr2mZi9PYOAioaxFMzdx09b+He+X+Zc7dp9zEBTEUQwxqhGpI+fr/ptXz1fnAio6uVWb0khjUgiEkiMxIiIOCJJklzex+dst+HXmzFc7Cd7v7AsxxJErMggUxl8IhJsCGlqfR+CpjLuAw4PGcShwuOQqVPQDiW4iIJ/y/kNqX33jUAUmhD0oe3hvPNjWt8j0ZmdemV2f8tmUuxRrCAgIFVj7hR1jI611WywVTRcPkbCIHP2/7Agt6x/17e9ikAYyhoJJJBJSPuH2pwHi7aCuuYimcVmwoz6Sqw5LFp+sN7u3ja/N+HbltJdT4VA0CbgLV7RtcMlAz/1IAQBAAD4GoLrETmIXJ0RXQxFDPcQoskjBM1WIFY5jDjqLcQ7PkN84QzibO5COsoR0lkukK7yQOilNMgM5ULmqxCyWEzIWjVANqsZslUDkEMahhzVKOS4xiEntQD5QZuQW0YDCgaBBRR2hAgoogIB5YSQoRjYEMoVX4Fi4ttQbG0Lxc52UO7ZFYq7Q6HQTYcS4SQoKc6EouBbzzmaZBKabM9hP24V9nZKhOUGS4Bhu8EWYASmIUIyEMktESmtEdhwDEJEBrk0Bj0+Q5iQoSyH0VMJY6gKxlhNjLcpkdYW1gDT1sIWYCb9Ail7GVP5SpamhVlpXxxL5/JYBlfGMrwqlrEtWFncGiEOkAEbYKV58y04XGlaCNx/2wwhRgD4UG85p+L9FYTaB95JDmqfnMSzUPsyfJaHrKVn+RTULnmeB7Uq+K55f7kCFZdDsxWouDqJU9uKr02G4hvrK357BR/fXV/Ffb+/lRuh/7Fkhq8JQpxzDgJ3f7etQwJg4FH5bAOFz9/1olvaMAqA8IBpo/jBtPrkIahA5ABydZZj6kYTuZXBQ6kzl56xTMn5B3xHOXowYrxdmarmrnXOYbnrct0fUAKIIJo0sugdfaGf9It+0z969IO5+nFWJcVfWL8Bi+hvUSD9Kwas/yGQIwf3jkLYrYrIejt+ZFmW5ehkcGExwcWJkEkr01O1kG5bTo1X887tdua2DPtRpguFmMKnNE8G89SEdP34esMI0qykWcVmzvqW4aOIYqpcPXYn0NAG9HXqP5PbaMjMawXag5oQsfh+BKPx/k5tIjE3Cdkmn4xeH+F2bJKSQMiax10aD6+TtOWsMYSBTfq3SM8/BDVruFn83gJlkUs/AbHo5vsBkRxMXUcBw/dGnrzRh3hTXA1k5BB9ZkPiioFBpaJvYEqoSyzQxTmEjNLONrqLdK6LC81kiUjUC9vJdYtKmsgFJNTWTMSr+Ge6yKfvYAgv0pIV0YBA9PY8VEfXo83s6BkoR0B+DAW5QRwXGIOSn7MIFdEeFWNbGO/yaaQsd9aHNGng1N/fUByTyqC3ovHsBePEEGWhf0RDZnQsnhFTUMiPbYL0YzV+CDEr3ZDhSLsPZSHWQZ46NjC9BOdSRinvbg1YgaIPkI+KhIgSnZrakIyGUiTT2BchLUDVqES2oqiNobxfgvPBMh+MKX6IcYwql3S9PssZzk3u2FhxqEZN6hi7Qt8gsUlo8Z+sI35T0OGS/oXRHI2sDOiCgFXhrsB4CVIvIOX/jGvoPxOXpdQ7fdEvQ0gTwaMJ668N/DkhJ6xhvdj3NzHOlk53ThwuxN7Obh181xWx9Ap1tBOTun+GiphFo0aCm/whELaQ5F7m/aSrnuuHs9SSzao42bTRM2ghl45GMY8KVdlIQrXMdW5By10e8H0LLXpY4Z+bqXrLVSlZj3vGT/zKCq960x/gUUE/xtzlCKfQwgCzgcVmqn7zn/jNCgLWOOIKjTMEEk4syYh1gasUUcEdeKZHY5J33kwaaKu+v1KbvQvRkHHWftoJFxviIX8jZrJzIT9x0TmeIWORdbb5xI/MINEAFUj7UkjNatuJhD3Pqn6+8Esvws19e7FBLhR0KjY+/ul4EUpoiIBGvpFAl6vpheU1RpQc5mWb1RcCGEAf5dc0ZmWng5okpLtMXnwTbUjo2YsHlhS7Vb9j+QcHNWs2ieSmY/1tgyieKFGMEPsKIoAnCzbIRlV4ojFy28SaNTCdZzxPsUWMODcs5jpkoXDhqqv6doB3NnGxYpM+/j9Bh3WAMGBcgSwX/i0eGH92Tg9n8jMCkdYTj/9Zn/+/8vjfa8Ep45PHWGZVePi3kF39hv/fpHKFRl1Uk4YzwZXRy7FP+7dpWlwhtIhl139kedydUbVAFIXlwuYazD4WK9cXKhsGxmdmopHhlkxYdUktwJdJ6oFPOw9oqSkvw4NHzR2zfIJnSJd3ksEweiXTSxUyPtMYfujizU0GKu887GdsNZabUn51B0Z8y2LU0PtZ3+gZUYqbDyx0MNWfkNfh3rJqfxEiiXDPgiDUDd1nt7HfVt1hRowu2brMCnOtau9f6ml7rPE/b9ngHR/b6zOfOXqfkWPvdMHLWqPAG2GHxPF+tKjipxvOOD8LzliA2rLgDZwSos4GXVgq1yVVCpdxFWa4gTu4Bwc4gooIJGNUF+oP5i4TBMIlnxA4D1tDcGq2rnXV54vWU/89hxqk3lFzQYv1O+iDneykT3axqz7b3R76apppWravQ/X9/kNtRNoEpMi7GsyNaHKrZeX8uWmFm09w++JtdxxbIvfgAvRwCfplUS5u8tyl7+r2Xlz7GCPW2ClTjpe6nPEzVTynGq95aqNBNyU8xwuEIizW5wqffYjZrFnERkj2gavnT7b+YkTlzC7c5fSP2ibET6iyHM1L7jMu1gyhXncIqMXwh212bYrxU3s9S6qc5OLdhnuw5mNJ+EMqqgzxLofonfBnWpi7pB5jr/5IoWZTdmRf8ksKcppLsufqX6DMn7UseyBeVWHmqCM2VIN/Vb63TC179i+VFBX/E/idKAVaudUenzFfAHF8FilHr31V+yaE7FU3p70DvsdMZcuByPzftUYbOCcc443PDm23H41NanU1/PmtfJdrHS1uStsx5HoFo1W65CbHKPlyF79q/RyCTkP1UPcleP5V7T22oHMo+8Cc10/M7gd6otecXWdnQtG+LT3ntrMWzbrvXRNpgsPq2nQLKI9av/j4xq3psM6ZWY4ZZ467tTVFRpxrepqjxRTj7ercDQ2PmY92PCS9rxJRu23H9p7bdhbW0TL+kIr9HbT/oz1xb7mmeXvrugnHyB0Plzkzkh+1VwlnMZvNjxwv742XE1p7oC6TLS6i13RJq9o5UJ7eP9PCY0eKtmd8R83ssCfv9lHDNp5ujTOl4B22mnQ9XrL6YFqhNkYbfGP9kXy/0/1JVWQPnRc/tWrQci0N8QMVs22EEiGcrOwX3zQ6kCX2D09QaNeHEBLfYDwVK8AKHJU7gJMtEWkYIf4YI4L67ZUjbhYjVHX0Dwh1SKpGYyg+g9hqIOc10XWlvv9GUewAFmdzQ2PIPmFwvU1YxWJUeQM05XMNbblwiYK1s7mtMeImy/yKLeqE7aANEUzDt6WWe0woX9PNGRAB6vOUNsTMimCrb0f4SaYddFlxO8SS5xwZR0TdcOTXmCPM0Iq0OBKZBxilxHigdG3UOggifIBiPxL2pequ4NPt1C10zLeIoBJepshxfjIOZY3W6H9fFFBTj8oy+3S8aKZUK+UUjwIqFy3vaaXepNXba1DQKByFzA31kNPrOw08CCB8HFopCVq9p+5M0Al9t+26LPKqFq9qDbiqxataSRu2PoAyO0KiyH2UGMoiTRjNHDXgVEc3n86n98JcCXvy4IEXPkTBj2gEEIOgWCFxwuIlSJQkWYo2UrWVpp107WXoIFNHWbIVKlKsRDfd9dDTVXrprdTV+uirzDXK9fOr5gxqp0HNHdTOg5o3qF0GNX9Quw4FBX3x6FAv33FvY0pU1L5BVGrODt7tXU252XEQ8zYmjQnl3eZhYejSAQ66Dh4qgQBxIEJcSFANFlATllBHsIL6IhgL8TvPJBCsfwVrVLAkgiUVrBeCJResZcFSCqd3wumLcP1fgAcQBICCCPZCAmgswAksgUawAnoRHgtMgAHuEhywvPsiIw3YP3wTFQOcn/KTYoH3W0ZMKqAPR1uwSPFSZSlwyXXARslHbloW4Hx+JgD3Mys2HdRcys0BLb9J6fGg6zcbC4MBwIH74IEQAhBDBJOQgBQL8AJLoAhWYHUfxoIPvxZpWQUScx313UduWsPMXRzdxZfO/jtwYWlta7dYrn78+rPRPjg+u7p7/GPZ0ENBSE2Pe91vkmkeMMvDms21wCJLPOpxT1pupdXWWm+jLbbZocVue+130BHHnHDKs057wUte8Zo3vOUd7/nARz71ha9843s/+tlZ5130mz/944pIOwiDu9xwxzOf8gVf8x0/8gt/TABhF4DBrfzHQBReA6LlyVegkFYRHb1iJQxKlTEqV6FSlWq16jVq0qJNhy69+vRX0wNARM9ydaPxJgvh2Im5IwceObRnn5edHwMdpogpRpJAjuSgGXxOEQa3esZLQHpONa3Q/q9JlylbLrDkK1RshhJlBWczmjp8IRcauL1osFJx3fQzalmtob1rf6Yf/YvP9Oipa5JM2wlhRfUd5ZR21f80lrjKqYpIF5aiPqy6rgavLm/xbd75ssYCdysItRlx6kBJO1RDLBK/MIUMJcX6WlJKXWBSmVRqvPfIlc3Qp9Bt2UTEhLfJOVajZdsekY/MjvzKgvXoXmrvk5ZZRR869ueUTftDA+y1MqBwWR6bKcfitXgFTzg5OuTyCoGmRwvhwoywKdqeDha7xHHpGIaEaZPEMkH9jPx3WiDPKbaEAoWhjG4sJCqByLMKlaJ2FbIq9aGmoWV2NEXjaHXakPZNHdSm69E6UxfpMkNLx1bnqnHHmDH0G1AmFRgDTAPOAFdATqBIUDdoG+hvGZdQQ2hv6PPQv2Vrw7rDxsNehv0v7K5dWkcOkSPElhNkLB+THfkaJbSdnqDX/GX1jpiamdqaXh3VjBZHv07eQWLoGgaGdeFA+OWyH8uImJEoksVmsHvMi/nxjxsaFz9mjaXjzQSHpyV1ycMUSdgiGBCS04KUnUpSeaZDtCeWZbysI1cjXZDyck4uzzcnCNcmoRPmRD759ppaxBYzhaxQTrmk8GdI6z1r1ow3P4Yd8hrC+TIMdiwiDeQhmSNfKMln5IL8nJxIFtAXzJeSTNmGXP4KlRIhJ9wKt+/caG6R70WRbJObRAqhTILdGwJf/Yi0PP7zpQZD9akz6g1126I8dzyNo1RkXHnGe7KsyCocRNuhfbwunnbLtblNj/S68cryuuMn/XI44Z16f+J9PQjCk7jX59LnC5+yKIqKpOULffN8OWk0KfI5mCu+v4Omsli+Vfs5fld+TL87dbw+q8v1QwO90wP6GT2Lfqe9att9t/+J/2N/pn9T5w8txoJxx2CPhrE6EfM6IDWgaQrn9txeUOBJ4HuB5wIlpgUEQHggbODjPOBBs80MjVkaDfWw0R4KD8RLRzrRmS50pRvdKZe9ROhJL3rTh9mi6Y4cZcuZeHDhXTnJTe5musapfuE0Z/i1C10ybQXqvWg9rZmMeq/b5bmw5ZI31mMICH57aAY8BIgwAkOCDEVUabiO2ZHIDo4AIBj0HjjkA4GoVNneFkIj0Eg0Cv22BZ3qcEc62MaOdqzTnWlv33U8rl3u8jwYu3FOcttH2W3dpE3Z+m3Yxm3alm3dtm3fju3cru3eNQTXXjnvxwCRgaA8bjBAJcVAHAzGxXA8GIUX9XEf5lgiCo/Hw7ZpEe+1eBvveFeqr0nzA+38RLqztHc+ZMTGoEPUCTJToPt05HpENp+Z5AxLrqbTcPUQUTD+KbNwZBmLis9YXGKZWFJHNQRLi6AReKyUDmNFGRVkZbnGnVVFC4215ZsA1lXQYTZVlNlcyWZLFfToRbrSw7aazwI7azcHtDQZjD1N2djbyAXZ15zqwv7mXiqHm1e9OdoCDnO8hZkTjWFOthJzqvWb/7W3KTzbVR04nuv6h3m+O1T6l+GF7jGevDiFbRgvtwjor9zx1Slv83jtpd/w+lS6Zbw1VWwN70wr7OMjJsP+nzoVCyrMt9R6Ox1wyive84WfXNIaC3FDUgQTRjRTdVXmspatvBWqeKWpQNVq05Cm9VWr2tTeSObjC4UndSRqLe398fW2nmGpfClQv464CTJgE2dIx/h4n7rz8fw9e0EAuXp1Q5zrrIsciZXP9vSCK7UOL3kykCoM5TZUyTexpSojhR1VC0ztqUZo5kC1InNHqhNbOFG9saUz4RxMgvs/z1Va2yMt5attWi7UOrTCA1YAX5nU6NFaudkX6Z1IrATr/3OHDJl3Pvjkix9XXmj88OvaK90o/LnBMQSNb/4hPFMYy47AEsWReyJbHOOBxDGOeCRzJVFPFJ40Dp6phrLOsV2cOnPusnbrHEM8Q8holSi3nGs0tSaKyGifGGs1dbcWsWlqBINWszymqtJF5ZjftfurMsi8VGZRtO5q9GAJcoVSpdZYHpixwMo6sexdznGHETpfIPSeRL6La85q0ur0vuZqQLC4vgnFWct5voskqQf9UBuy7zV3LTP9MoUn/DZPObse8JB3Kdv/cYqOnn+GOIlvGZTaItsrOV7LlSdfgUJFir0xUOwyFCb5aNlPmWbaVI2hUWGz9BmMuqLpUrFCxoTGRrz1OZ/7Ra/70m/jpEChKh3SZCpRqmxY5940/PjdVGVyl/JoFSlWplylavVC0EUoV6FSlWpMNWrVqdegcfYr7pC3ValR64RmLQAgCAyBwuAI7O6vJNTf+UcFahDu/R7OENA8p5UF/Yo5GBPiNm8PRIVme+y1z34HHHTIYUcdc9wJpz3vBS96ycsiLOiCuOfnHz9/GYwms6WVvQOZBa+S2MYhzqHGJ4FhJD4v05nBTGYq05nJbOaKtyAbbau62u0hOKEO2Il0opw4J3VctmTz/6sUmWJUQaMUotEao7Eap1CFKVxf5NOQR9ixBAI1a2cTYPv4kEbht9VgBDD+g1gtWEEarCEKVJCGapiGK1gjdCMqLelNb0YzLWkW20o7HeURFqjnedHz2JdNQ2B9Dpp/zi561qP06N6YJ7GkNLK4ugMW68Y5WuBDBiMaUuXikwEvCOopXSZ3wAd5MjfqEIBTdSJnoP+oRghEPZPmZULUf7+AaJaZVM3PgkDz6gHeYWF+AMoHoi3sON3a2c09o1NE+LFfrSZMelNZwY5r6N0EB0wbYX4Fafx0GuT274477Qz/qKhRVasGpY37qfHfOjlUV3SVjPu+dnmxWCKVyRU1zLmc2rpkqYP8J8PeolfmPBQGT8qvwN7B0endnhHRFpe7mmu4Bbfoltzy9mm1B/e4vW6f2+8OvKMc/UF2ucVQo51xoTLYKKXPG+tTReFBMyvY9R4KRbd1R7a6m3VvPwoxKFdpoHqPe827fggHpgSHP4x8NSQrOtVeTuMvBkS9IHrJzhRVP51KjlFfcU806y8J7fUI6X084uH8qPKvwYk1Jpfy2ZLXs3j1ftGdAvlscu2nIOZfuKiv03MtAz/SlbgcoOMBL6pQBdqpVbED0gXUGz5TNJ71brFKdsLDdM+bmPpoaV34CCSBWHUce87zcnn6qEKrBMJYJQSKSUJXKG1ReoAKaY+iwePqDHCmVB3oEsPdXEyCWCBYzLTqrJvdsZKBByngGAnX6xg+I1sFslhCElxR2Y6VJDkpVaSmB1jJgPQ6M4LMaP4DB+hP6UFal8P4emOKHN31vw6ZajPBK/V98jbUKVY+N66KoYlOD+KrCbUHecLe/5SDhIT44zzk5qe7UPiojCSWxooJgtEeSY5A38mpnmfyPIiqIo/jr2SNF/YzJQaDLLsG1eU02TX11ad4CGJXqY7NsIpCb/fFp0oQNacdijGA/bTHeExEzXrWAeP4bE+VkZQYQlSq4lDobaiEtXG32X47e/oA6tFbir8TVHTKS99b9CKw6hMfaFePLOgQCsDE4Y1DpQhhsDzhIIBUuRTrEeUdpOCGWg741JmmXsqHoOz00Ao7p6cQ69RVcEtxaQT/ZhyEZOqu0iDjGbD8t4WI1SuA4YMs/xEMTEKhX+a/JAgAmJCiaqzE/ZiE7I2SLSpz3los3FI58SpEVgc1dTWZW8qH9a8BF+GFJSpUqzVZjnffuHAqkqa7LyNYXSKVzTxGZ/fOphN3Tzz6ZDhRy9jey28AKc4Wwa026vb9OOVskSqzdGX3HJjg1hSs4Mx5kCBrPajbDOJlYrzwh4OXnC78gGB1BQXyglNIGGYzHXkAQko37958ZJEmHmdUd6ndM0CdprizLbvlH3k/Iw3pd2VhzWwaXHij/vi+VYYZb6al42W/M4dR9pOJ2URIvx/4HoKSl/9aV4eQle1QQZ/2PqVvv/ftrvSJ12B8b9m+3LnmjYLczWUv91zrl90CYkj/K/teiqTA/Q6IADu36A/McOOEaOeJH1W5Mo9NYnQ0le9cjIcuRfK6tfmRSJGrVGjUWYN/HA3w/WuLUjOZpEaUbFxL9X4YrazbG9ORjxO92p20nVB0PE8BeYOZsvXdbFQ5LxfbL3d1PHtu2Owop24s+yz+YcRGjCcHhb3cYhdBafL0WjGzY1B93rigOMDj28y3yrASinz1KcyGN2HAle4HboYsysYOfqBgN/lrSwpPrbGMTQ3mQnplIMiDkHT5+rhRjbGmIiy44HQUTIDfJU0isiKFbLdCQW/RleG9/wbAkOqVhelWqwyWdqzLiJ3Sp7bvV9uRB49vPiwiUaWWd0+Xp7fxHwS9fUIhe3y7gOhoENMUV/b4qyOADCX6qzFeo2U2O+I1X7gUC4nDgKW7DyJW53NolK42BS+kA9K2bk1pMjGfmGl4PtqUNmwJX5NjdGp+qrhooPLcWDoqPwpEhcGshVblqyTUaZ98H0rBXNwUHHEuj+bl82A52ewqmpRPQoA6eYex0D6n6d6XoG6qGJxhOsXeL8jK3C+aIu/k0d57vOcVC7cmb+IAkdXhnBrYyZ/Ye/lM0Zd6929e1WvkQqozTGt4AyIQiYsYR/HE+yoyhacsDL7IfcBxTyUZDB8xEOkh3aZ/VlfGbeWllq8MjDdodA6rYcOg96tzrMDjWxCcBCLgdqzBdF3EWdhl+PUrUBchkRVxRhC7PaH6XNO3JMhky8qLa2pBORBRSm9kk9Kei9sbeVvSlVOjyIgt+4mOR4Pc6fcsvTpGZalaO0MjvchAEy5PuK91qV31vn30AA1gTzgNOF8MuvX1jNms1eKcW6FCErNZ3lNdqvQptdGv4uXGavuXxt60q7yOJ+3fehfJrwZunHbcaNxNh8DreNJxq2/B63it0909Wms23tNnpQzvEPACGBUakSa/p6YhSzOMrCpTXaBPA+GRT8Aa4q0JEh1va5UyO3muio69PSBixGZuVCRUoI5AcFXjtM1VUfhugnZ36VYpq0UGnm+ioWWZuoxV5r73lqVsSF1wVVI8ZVP4Y8XEoYpSMRDQFXsnsM9SEzFkwkb4PIpcGDh3j5W3PoHGJZixilF3JhsSKy8zJWPVO7WfPbqLgj8Msxv6HALe+DjAwxtnodeNTEcw8f3ADMiiTNUX/AnZSRH8Pab9JC5s72WEYQ2O99akhjboNToj86DLCFMzkU+zDh33hIJ9iLwfEUSQZAQfoIMcSGMfHTYiQh4SWZSp2bgSYeODKQdjcxpM6CNg1D6YIEOBYQnwFQ8diuB30/YXn2qCNGXnI6WG090gaerBoveBNmdjt5c0VZytNF7d5pCMzMRrQQpGY4Wv1VLO9S0rqgxfiob7gTtPV1fOzIfs1XNn/2B1vXLjQwZFleRCWK2QXmrc4lvn4T0hF8ZUIcNUQBTddcupKqMtvjmchnDyY1K3xdo99Ls5Ch+Lx1xbepei0/yOhv/mScFZDz8NFZpBZgiLnbj0OI/T5Th6mUrznrN6GbxSj7X5yg4fYHAZL7n6Ia0vLuOjq4/+RKRUlydws1bH/27qszG0UpbO4yfEFcVlIUmmvlgBVBwfL+a9+1Olhjy1MVSZDqhBH9s99bnPWzF/NF9Tuk5nzBvfF1KnY4Q8L6bX8oQmZPxyq1R0a6t657bMZa5zNkbI82Ioc3L4nD5E9SqhGt+8CqsgnlNFRRChdNc0NfMbT9Eubvkdy6Wma0z1r4gbjxaKFh3paWZd7/pI67as52ZmNmkxXK9/h2zo07nrNNC8xZuQC6Ps6/8qKPLmaL60f0lwR+YT6S25uSjP256DWKXyu6/SyxJeodm9HJOuhOu5Tt+UEuz3XuE8ZeSeASgdmN8I0E0Nt/zU5uk8q33/Wf2J7XviJr1aFszSnbpeEkGJQ9LStkvd3dqsTDk7ifqxFu/eHT95HfTFcH90u9qz/Xr7d4TtN9u/JW+2q998NNIVKHOLceottdURr/jE77HAgHmPHwOA+SDzmojVITwg0f+TtcrJjD9Hm7xxKw0IS9WSg6sqygZO5N1Cb9RvrBDBIXsxl7iz+jTTVCE4fZA5iIp9AU4II7Ek6HwZ3JbR+YzJ+OaQsPIJAw05aKgf56xs563uqea4Oz9Oy2Ehfkm3ltXLZnKwusmAjugN9iBNBbr8fbVxK+7Rnbz/d+PL4ytxQDJP91aO9PSWyrgOc/ZDrzgwstkVyfSHHwEMBMQnUmrqGYjdRABCn45pCHbXqPxV4PtmKFJuhPtLbXzHWO6wnyNS/obkVp34U2Fu2SJ/ciJFP3IL+i2dLgVh/HYmo6RGyk1ObnwK2Pc5uBk7tZ7iBvyG+0PNOvLJE9SX/t5G7exV1pV7DlyvoyMcuFlHY1HUTourfcstxnoVB4fRpsTE6khGymm/TSaJFA3fGE7Zl0XI1cL0EBhhFcszB6L38JOZ8tYsBZfxrJhPX7vPPrqj2P3or2tdjuJmx6OBhqPY6m9z2vG7eFcbrxOuTzKGetzvpj7ng0Ha6ZPXUF2xd9Vb9YRcGEOOV5m72tUvRbKfFVKinOlwxFjPki0juV/405yyN9I7quMxHpiPlIdCABxbaTs38Ga3I/ZLIObxjQQTarXDWUqU/SaxElRQ4nVp2FPdrcAlZej+T0eaDz+JmrNZ31E/0daPxXdce67syepb4p5JPYes9xv1b3EctOdX2njNXoJLSMZQj4/hEFrV1l7c5LGMXmcJOceQGzxuW2Oke15l9MDeaW/aEyLcl1dGL3Okl7cwE2QHllss0zvrzXpCxMivjvxqJnjk2e6pmd1fL9xr69kyIRfGlMmHdC5aTuAfCaAfoWrSruv+ppHub9bREy6oaYz8dq+z5+wJuTCGMmHUucX+9E56k0yIGPndkd/NPBo6uS1V2vsfMK8Je1TWqSO9n6FvP7V30BskQsTIH478YSZi2YMPLoZzCb8c5o3v3XRoRD9macqOT3D3GefmSwTGOrxSqizHHlepFXwpGh7uVn8Gr/TnN/HO5nv5D5iu+i7c2SgSS1v1wP0SvWVDvsyy8jLKcntK+szxR3YI69b5Gtc7biN8babjdXwmF3TuuEAHdEKGwB8do6qd3y7k1Hd8t9CJK0O7Xf/Rx9VXsvBnfPesoAoaIq670avv1hUzP/RWjfTDlqo8WBZ1FUQz0z9Bp2asIk+8hFwYQ9JDBUXLpI60UO2lKqqPWOg8Mx6dvzwkDhetXyuldIdehy0OceityPyqOww/N5z69UMdOie3sbdGXugqf6nSfRq50hGJeGujI/HaN8KFQKMKYEbza6qTMRVE4iek+yXD3S7xlppEdzCoz+0RllpVNlCkD/cVPRTzGPu2qM56d8Jj5+81R+8fT6ZrjVntNib/IlMlT6lVx2g4+HwhgMHXCBYKeqCdxJSC+5YxTN47GBhTDG48G2BzcBn960SjSWM/9/R3RSkhd7czH6gRk/u3Z6fKFhWPlas4XRKYAJ7tWddiRQBp8pX5Io2wFxsLfUbTcG5/T+g19xs2dXPomHvZaGuv7vapwZdqjFs6Dn9LH7eRdCM09TqH2wiNDewBZ0SeA1RDoNW7Fjz8zXZeb+2pNUJFY7ZLF02YGx+ndjzx3j80zG7vkbBBbswX9unKRexqMjbO/9MfliRDs2Ues8Ia25oBDv9rclPQsjiip1EebcxesCguW17SLfly+DiKa6Rj9fCUAKGn4M+Lkl5/MzUA+9EA6jkHgU+5zgZRZWT4CO2uxyIKyCVsLeWLaH8GMJqVzGQgoTJYVAVX4v7mbfKknSqOTWuZFCQCS27ovai0jh70HsAJELhmHT+c4LU6A54J0C/DjpRoivpqLYfLCB4vRunoGuPDjp/vgVEiCla0CjBgIHohMvOMBBTHF0rJh2ZNJhwRrI6KgawXTX4czRYE6KTNpuTGLN3ZcG3Nq4YdmKAVBqewtGXtJ9B2Ag0m0FjynBiI18zCYPKNTvrn8LICJrpDKCUXYC6u2O0w13ft7fClMEfZ+ybQ4DMqsMNSTRz95vCks5DH0akBA09ewAEh0Kxl0X8K/Fn6AiaeLMIkaVdwy5UtU+seuKq9Cv6ZoKWjj/vvAXkt3v4aENZRe/X+daeFAESYioBySHe3eGTxAyalSU3vJPHOkvoWuWU+mx3HceJIzzPYPu6hixh2qOLxI/0R0Njze0IMB4gC449kEwzqsgBiuJaoxMT6qR4F3T/s4VUg80i/IIS202aKkESxWnY1Oon5nuXccn85WkhMgShPzMYs2ga0tFvwLrCbHGjw0SaALkelHpHwAUeFBnjS0iMxiIy3XyPToriJ6WZiD/HyJq4l87JYASZh5qaiTQ3SDWhOFYYkjNtUB+tswqCpEZumRp6ppPIW1Ap73k2T6e0i78hDG3U6Fj2lJ2bU1/Ne7QGMsUAuS/GXRiTdwxiL/2TjytIn7YGi2fBAMMM5QZibuwuKmt/SNrQC8Nyjx27gzW6dO1it6UBL5iqN0NGyan6L8j3dBjRnoLB5P7C+3W4QI1O2tPU0XUX12S8sbFVb7V7JL13cgja2l2QCWhwlOyCzNFNcZg+F0ENkup/W+n9SA1TX/DanUcYSGmxrCEaxe48T5qFpCxQZOhuezL8Icbo+AEfUKnPzTvvqrciU/PUXB4GVUpcB2eMqRAb8DTVYJA9oPzoaD3RCUDKchub3aqZSNyrdvkvhVg5N7QDmy0o3OEfRnHRBXywxdXQnkNZnnQcIgbFCzbqoV86VyAWWKYCwC4z/wlUq4bgOb6nEJ0I6idj/hnjHXe32gkMdyuW62l7ltd2/+adb6JQPnA0KEmUMSbKUi4KVrAI1aVhftWNOhISghGM7P3Ki37jNo171AQZ0Khci7rk2X3KyoGS6wGDXtJOAYHWxpRvm1UYZ35Cy2cTTNjMBzUybK0zQUAqNpNAyCq2iuEFIRkI/RWwDGmsMg+bTsWOJl8ZLOGjXH63zWW4NVSYKBj+aWnnEoT9Wwln7cShMgGEHTMb9CyT3qkbwciDTs0pVb30PGT20i5zK2tje8gOCl+x86J4IV7WdyZN+cPuCoNJs+t8w++7UJHUlygoB/e8ZcncrT673rTAIwO1xc7ByQ7vN+GhDu806r7WDSOS2KSPo28hvWvomx8OI+WV6oCEotLfMomFoXQ/VQO1PgdpkZPXekOhNdsDQy+/Xy6KiL0DVrZ0MJYtQxhD3o9zR5s0yqjiiya2ORExh//gy+7q17dxqBiZntaLNMFLnOxUMYmxOa9qh0spfmNXyNtGSX5jbunbR9Fhvtp9bX7WyLa7x1OscuDGPCPph8T0k6WytDsoOvSuOkcI4PLOz4/6BBsAxgkoJFKQd2+wQfmhH0YZnD8+h11lEwPCK4ZU+b99m9fmheekzPHd4Z5oJEAFaR+s0t012+6fGPqeGdxmeTycANMDAPkk0qV8YYzeq7d8bBNEgHiZoDhcgKbKDdJUrpKdokF6GgQgGkQwl5RAhRsG8gObL2UR0MnOXRZTsBTvkqGklhJxLXxQFEZtYwJSzicmT9DXLPpQtv47rkkow243qjgUV2AzMqKpEdEjgmeVqLquB1LAvPApkdqPDCZrsOCrwlPaTjwNdzPEktjQQ2kYwrNR9DZR4KZsOVIMAlhcaBF2aoWf0amSi6WmJdC/Hm5vtxhZB4OaSrt4wrWu2XAzozEHDlpJ4kx+sRYK8G+vj3VgfNrK+7hwMXAuPPSK+GT0YQ9BjIUaL/VLYRUhPpkajsi6QSgSUTgCq/96M7luD4XfOQ2+LRrH8ASgIfSUCRWyOnuqdU2zADE3u7XIzVoMYFV5H4w8G+9ongLvKc11QSmBbh4EKsHxnicuITSyvbET32/tRdXgnZl+Pykj+N0DFH+E/CDy3yp+yPyx94w5Fw5Pu8T6Rb30QmjqPlYeV/QySL5J8epFN/YByNGwfJNvbyArbmcN25WjBvDq6f0iXH0A3UlHiycYoqV1EayxjPO7dy9j0fuwB5uq4YK+rpuBjVzbXxsV7XTPFiVKkh0UW8YDMroPwTOq66QYos6WtShhJJFjppbpwExfMTIF+x9DZ6aTZzkCJcwz2h2Zr0jQ8Q0+ltZlMtwaVjnNCCuL9EHvi/GG0l5vc1DZDk3S1QfdMe32Qvu3iJ3If+0Z3uaNoNm4bcbpnyPW0H2GIZZIK1mv5p7H0syMPG3lYxsM7e4B8KF2NcWHSLL27O0Kxw9yQIjPgSD+de35oda8h2TNuzubGrkrqLi5wOLsGlflcFWiqKdQE8uFq4PPS3fx4VlV0ePFpxdrbHcTi04q1p/dHY/UysFFP0nMRqt1G4HTi0qlTJ2W1DPbgkiRbdOnnIHSTBqGbYl2q3rdCye4MV1TDR3ep7VXTajgPLzj10s/Qo+rfHp7qpd7qo77qp/4aoIF6LxNjMEIQmI470a2E+pV0P4to3MYONBcugZs+7gdu1/JvpKBJ1G0GkUSmUGl0BpPFNtP3/kVxuDxDvpFAKBIr/DbkX9hEKpObKEzNzC0sByrIVefPbxjFcAJAEsVcQiDY4zDgqOM8AnO7c1bNNvyR4QvUo8H94NNefup8YrbCptDUH7gdduqb2gnH+Uvk9EiGOoXx3n+hfgx8rDS/OodFtz7oTQfd4lA8vU9edntc9kb56EX0CLSauYEOgFYpn9z3QETf0PFr0j8BXb+slqcCNtEQvZ4bdaRO+tD4OI3zr2bMpdG31v59XtavCrretg+dofuNNEOVWIorYRbVW4woR47ZNZexEsd9oBSp2XUuKo2jaq5Y0n7nclt6qnKrl0INGKjYiOunCHPgGVv8tQfv7rhznaipuitWTJmhziiu9GHNbwUbbUnXxnPje2aj7gr1QbNV3yOqVTPJ2Zx9KQSV+Ca1nhSr3HTV12mLTSTeT6apt7x700XznlQBybxs1LlMc+969+ZGgZ6nd82c17OipmFv2tGdi6zPdM6LFm2D/EXPmT/UkdWsyaDOUzGl/K+BNtGJTna2c53vQhf7oR/7qZ/7pV+71G9IBxcf6GNXA23W3izqkSYoKc1Ns65ZxbVrd6Ia7L44wiMv7nlmEd6EVUsVjwX0UhIAFj92WbZRFDTe57AvyK/31vz1N5B+CgD63Z+ZghOiI5Ep+38A14Mw/xaw6vsFaFsrB0hnASgAAyAToEBMKQy4zjTwWTVGZPw5hwBc3CEaXV2lAl48lBBLIaQjGnS77OlCa1iw5mDnW2R1+tJ8UPQvXc6qhxXehx+klTpttTfT/0/TpuuYFMaEBS98waBhYOFw4EUlHUhYdMz8VChWqamiuY6616dI9dropI9iVaQS1anRCO9M3PXQE8eN9/61a88/P3WBK7zgMosuDU4nvQwzzSY3+U6YJL+8SEmBflGw+uVa1qb+K6qKKxa+HRE6LiWdQkoop5o6Gmihg276GWGCL6zwjxDKSs/qkVWaVUYoJwwjjCTUEv4rE5d9r8yasBzWZSLEOX5ZQfTiWHzv1TPvow4irJi1v1itFrFJIEMJ2hMRU7faHp+Jegf8V9/CfibGxA00OKs5ulWueXLZCYtWbtir9etKKmzCh/AT4oD/dUj+ENUrIH3Ekldw+EHG40wE1XSh4lCx3GRegDWW2ty97KytzmI8o3ahjgfqHytSX8c736Wed3xkgiA8kFrkMm/xE+d64CwlUKsa/HfRn9dQsxi9pHQcAs4AF4f6LgAvA68D7wIfAn8C/gpyOBaKAcWrVaA8rGvI69DfZD4SQ8Aev7TAv8gX77xqeY9DER2k0gfgRsCl8FD9b/YvbgBY5n2MJPsTD/YHruPnFNOSdQsm4hjrJ0z/7hX6soERH37zcxrg9dcA7uoqNxdqlyu1HldZl7O1yWvJzGrIL7xyRfrUfokRP6J1yH/l5yRECY063ri30TX50Ki41xziRhyrC/Eah2n84uoCqf70YJWjI99ljFHca4ZvypuPGEi4MWEFhmKKfb/B4QG+vZB2PB7hIR7oGBeeiZJQ/+hBg37Myofu2qtedUoXt3MxWO/S7I/gs68AeOfb4vZOZHZu8mfNqBEbtvOcFFinHWD2nDpgji3bPD1nEuFl3jjz51t0ugCmLHM58v46HejGBqFybityhvxl7brihCbf9M7uZccQXMwarMtSAeDWb+wm8G5ym1y/8Ct/qYrmh7LwNGwwsBodYRMml2/1VNkz1u7emh3YdztM6as3/t7eegUAj7Nsw8p7Ij3lsId3OebX9S69pF6yLq+B9wjvVW+LHbHnUqO9T2+Oc1j6d3UulWD3A63x2aWKdMYqjF6gPopV0XEtLv6az3foIEdn3fXUS5lrDPBvt7pNjeFq3avOJJPNqNnEZ25U9dq+uRo0aPuPydYTi6e94tWe+QEK+vXaWRe1/tCEMnub4T+lPh5lZcW93/unK12vug13FyvP0uyOil4o0T1YRSdGIRrt7h3tyqpxa6LIsuzljKI0SctwIFD4YOFFFGK1kyxVW0W66KpAvGvdqNL1/uWGLoub/ddd/mOsKar9YoE55llivsWWetJma22w0WH7HHDQSm/50Lve95kPuhw+8adLfvdHGHwZLHCxkMFcHiwSg8eFPCXOckFPSLBKotXSbZFinTSbtLdVG+t1tFOmHbK1yLJLrmd0sls3xxU7Kt9+JY4ptFeeI3o45SrPek5vz7vai0q9oI+X9PWycq+p8KZ+3vC6/t52k49d5z3/5yO3+NztvnGn79zhWwP9YIifDfaTQX40ynkjnTPCr8a74m5/G+M3/++ycf5yj3/cH+KCgK8wwI+H4gCPxAUCxQk4QRLGzDGUVUbzxx2Y/bvXUnEv1fbG/tL5fL6YaTNrZs9XM2M+m09n5nw50612GFvdMAkYjXkolMM4XvDDwz9+I2tZW0vHa7mVVtvfAeQOdggdAxNRGhIKqlS0Tgsl6Uz/JxZOJqNjBB0n7ARRJ4k7JVgWuWyKzot9SzktrouNi5fT5SaTeL9gkMptjwglUhlfIEfBKWzX5Qpz5wAwBApDUmkMOpPF43LECmW1+TDiEa/4JMiRC1du3HkBCRUuDFiEaBBRYOIlcOIskY0UiwOHgBQjFoo3D0CRLdJst7PtodVe51qirYyOcudV+E8lXVUuqHYRk54al0Q6bI0sgpDF+edkfW4+kIcH6atjoB5ZA0ONjDS5rNkVLVhacbTj6sDTia+LQDehHiK9xPqk65dhQKYhUm/JvOsmuWHZRiiMUhqjMk5tQk4bk3JN0ZiWZ0a+WQXmFJqntaDIIp0P9D4q9kmJzwy+KPVVmSVG35RbVuG7SgG5+LMqq6qtqfFDrZ/q/FLfbw390di6pv5qbkNLm1r7p60t7W3raEdnu7ra092+ng70xnIWwKkN2yBJpCyBkqXQ8ihYlk0eJA4YCYHHJj966533fvaLX2nmL58EQpFYIpX1f8dOnWHEGBNe7R8YHHr77v3hC2LiEAlJqTh9G5xAlCvMLTzaMoGIpIzMrOyc3Lx8L6FTQy111NNAY06zzCrrbLLNLnt0BpPF5nB5rgICCRUmHFiEEnLII5d8smDlXlpySvqe8XhPm96V0KBSRSVNOSlvyJipXzSlS+mlj36Y9DAAO40Mfe+SLmMRCoP7z3UWEK7w4MqNw0xd0VTuUWhkvsusuQkSvOEmunrY4UfcE2du686lazeqv79Nb6Tv3U063VfaL+mAy2GOuhqc9mkf3ssZLGXDahhVqFKnXq1ylaonX5YGjXp16dYzMSxrLSFo4lSmHrQm/HeAXWNaZLbHmM3+YYsmyKHtkNj+vrvgJNw2YURgU5+S48xlCHbMZUzexFnIJCQlodoX591ho411SgRI3ZkPr2/d62KvhraTLXPpky54Zghw8MiISFzwE2CGh88RL578zxkHe4pJljPTzGOMOfaCdnbHdmPKjY833PrWO8JSlzbKyFNtaKxhR9/AOOOOv56NrX/EpUxrdiNt0PsMrGVZVrjk4ZOUknUYPwRLsTO+pBExks9h05fqVckVRfK2rHRB8g0WLZp3ZaYtMp/i8ozqdXapikm+e7GLt5x96koqTBMnop9yKKeqCorOO1750VMGj1pe3NIShcgiJJYvcbjQ2ycfncbuXC/fffPVDz/9894Hn2N1pm8sTvSJy6WjS3XV15AwQfwyyk5Wesnphg3V/ylCp2eXrebM22bBdjvstGrFsiV77bHbPqfMuanPc48de2LTkQVb5i25ZdmKNatu27Zj154H9j10z/3kk00ugs7EwyWRpEHr7tpANaRDpwEmZjIhA+nHDwAl5wAA0DsBopfLht4AkI7eDNAeHQeQgUYAdEAfAMjEngHoiFMJkLXtQ/ZYXOSsTugHALnoFIDOOFkA8tCRAF3Q5wDy0cEAXUebLwrWVZhfAHqhowB6o/8BKMXpAuBqnFwAfXDyAPRF6wDKwh7bceMalAM4eHYRuETkgYQsqFRhUUSUBhEVKpoEdAyYmMixcLFx8ONKj0cen5qAkJ6IGMRJ1ZixBh76CcCgQxcCDD70U4Ahh1MCYOihrwIMG3fnBiS5TtkUhlOaTHVnVTSbHLtuLstp7CvPqfKdrcAFhbSuVuROuvv82RV7cUv4KYNfKkWoiyaapNVkjjUFKgCmQh8ApqEfAUzHdgUwA/0YoB6nCMDqn1b5oPcCrMX+BLAOewFgPfZngA3YiwAbsT0AbMJ2ArAZdzvAFmwugK1wAsA29B+A7TjFAHagpwF2YjsD2IW7H6AF2wXA0+MUXOxez6D5APbg7gLYi1MGsA+bA2A/OgngwHYfDqJdAByCEwEOo5cBjqC9ARxFewI4hpYCOJ50oxM3TnDyZa0QtUHVjr0O6Dqx1YWjbnz1kKzXYX36iTdAuUGKhryl1DtCvXehYYaNuNQog8aYNI68JgZW2GDSlaY4Nc3ejFkOzfFp3rUWrLUorg+i+iimT570WWxfJPRVYkue9U1ey7J8/78Od5X61lT74aeafknrt+H+mGrdWH9NtPHhu8nk+jcU4HTa+NMn/fUJ799c8s+9vPf7iqGz0erLFXnTs3DABcgDC4EyMPHAXKDG8CGPZS3icMRwuR7n4RHi5fUUH584UaIs5+cXvLI0GngCGAAJwBiwChgEicBYsBoYAunAOLAFGAYpwHiwDpgA0oCJYBMwCbQHJoOtwJRBm0OwHpgKOgLbgp3ANJAJbAd2ANNBNrA9aAFmgCxgB7ALmAlygR3BM8As0AmYDXYDc0A3YCdwHJgLioGdwVFgHsgHdgH7gfmgBNgVHAMWDAoPwV5gEcgDFoMjwBLQA9gNnIK9ZBFDLMaLejf+jQ9IABNgEhMhBUyCaUwO56LBFKYEFANmEBtSxYFZxAcuASwgMaAksIxkSAOmwhJSYBHTIAdIhVWkQSkgHXaRAQWATNhAFpQAsmEHOZsnFw6RB2WAfDhDAVQACuECRZunGM4xfag6whVmQi2gBG5RGlAZuMEsqAaUwzVmQzOgAp6pDKgKPFENjYA58Ii50A+ogX/mQQ9gPvywANoBC+Gd2qHvCH/UQTegHr5ZDL2AJfBLQ0BsS61ZZcPA1mjjKj8YBKwYRraVbFbVMLatZrdqhtFtLZj9azERawF4GfgBXgGPAltBFTACPgVJAkNBksEZkBQwGqQNuADSA5wE2WzUzgaekX/VPaVfgwZ9unQp061bhV69yk2aVGnKlGLTplVlxrdymXVWXc39VrrACzXPISCkQULLAoNlwMB4BgvrKXbsMnHg8BInTul48MghQNBrBDLyqDmlwHnnhbjggtBulm5whEvuEuOUiuNc8nBPZ8Lz9eB4uECb6jcvV/P1kZ8ApuvhcdcLgUcpJXQWlmPhhX5UWsLnrr1FvBhT2R/Rf0slly9R6uotA6X8aRmha3u6Q7cevcb1Pcxg2wCzBlkZskKlVebdZtka6+6waJ3NuvuDmGPj2cTb1rMzctOue3zvfby+9v6d7V/kA1zX/iCmNvIht3UwiOmNPOS+jgYxs5HHPNajQcxu5GOePvrCf52O+LJze4Pt2jwKC4D/febu11vctf29s4I/3mWPnf1LKGsdBzBAo+A/CKgQABL5AUChbADoUdaTfIFfbMnB5kD6rBYlymZ+fnNEi9YkIOBRMWIsFxRnkrB4DRIka5QiRbNc6y1YtxBAw0BAxoQKNSpMuHFgYNMiRJgSKdKkKFHmQETbIWagu3YjGDgHCPFcJEjgJRGeDwIiEBKScGRkYVJRgKVJE42KCoKGJgodHQwDUzwWNiccHIm4uGzw8EDx8cUREIETSxcjQwaUTJm8SUh4kJICkpF5tqqKC9cf9cGwgQDqF8iGgogpmI2E0IBQNhZGg8IZLoKGRLKJKBoWzaZiaEQsI8TRqHhGSqCrEtlMEo1JZnMp7ZfGh1FS6Zo0tkAkAhKLIjMLCpcr4TNKuUIZZSpnHhWUrZL5UCkHjc+qouuq2RKdJtSwlVq6oY6t1dOkBrbRSFOa2FYzTWthO600o43ttdOsDnbQSXO62AmD5nWzsx5a0MtofbSon10wackAuxqkW4bYzTAtG2F3o7TiKnsYo1Xj7Oka3XadvUzQmhvsbZLWTbGvabprZva7ZtccbbjJGPO0ZYEDLNK2JQ50i3Ysc5AV2rXKwW7TPWsc4g7dt86h7rK/DdqzyWG26IFtDrdD+3Y5wj166D5H2qMDDzjKPh16yNEO6Mghxziajg+O9Wj3POY4ttlfhed+DbkX6Ddhqt9C6oB+F8r6PeQ+oD+EOf0Rcj/Qn8L8/gyZAPRMqNVfIBOBng11+ytkEtBzYYmeh0wGeiEs14uQKUAvhaX7G2Qq0N/hDKB/INEA+mdor39BpgH9G54B+g8yHejl0HaviOi1FTwLNILUAwv4K7BEHgBW4DlgDdIArMLzwFrkQWAdeAFYF5kJrAdeBNaLzALWBy8BG4U0AuuHvwEbjTwEbAD+DmwMMhvYIPwD2FjkYWBD8E9g45AmYMPwL2DjkUeATYB/A5uINAObBP8BNhmZA2wKvAxsG2QusKnwCrBtkXnApsFWYNsh84FNhxHAtkcWAJuBALAdkIXAZsJTwHZE/gVsFnwV2GxSZTA5chiddLJErlwKbmfIUmDzEAtguyCPApuPOAC2K7IMhBvmaxBehvkGpL0GEyHtDTQAaW/BfZD2DgJIew8mQNoHKABpH8EwSPsLpkPav6H3trOmMWNuu4W1euQV09dnSPK/QiN5zoN4TIo8AgXqXrlERzNdxv6AMzPI4rUNnBxeNyZ48HCOFy8CfPgA8+NHkL9Qq8LEEhUn/p97E0iEkyRZuRRYDKnSjEmX4aZMWbbkwkmFn9JFPFCmWjW6Jqeaddkzo2y4znSS+1wuE6U0QSmTtFZnjAZrns33vBM512+OatBgktbGW6Y/bRL3rc0yNbRFxnZbMU8Au9twEmB3O04E7O7AyYDdXbHUe1W3bul6pndzSd8MbP7OoN9E/e0eekqMt96K825G1oXGjSswYUKJSVNg02agMqcTzbx5sRYsiLc4n9adPvuixldfdViypNc3yw75boWQVat4rc2Pncd++ikxf3yu4VvH04z5668JmzaN+uefRVu2cdux50j2fdP6HPgNY/dgBluMGg4cTPDj10eAkG7ChD10yCFDRBy2TZSoDeJw/pEgYZPUHNk6naOKNwQETjmhrc/pIS37dOk6xYCBBG7cKPDk40R8tcn48SPMnz+sgHm4fEygT/nvIxN5EAHsYXxd7ovCU4REi4YRM7HLeIq0flCixJpatX6rU+dnGp36BexF1F/hwmUpAk5pAPYKHX8De4Vbmhwe0fUyHJyVHHVKAbD32PEq2Hu85SL6OA96UXpc+DLkx49OiIquhoSkKmUKZ1GuHFaFCmkqVcpARZOjSpVs1aqloqNLV6NGpm49CgwaUZQjRWM4dszfs3m+cJ4XXihx4hVSXjutUnGLdaj8FQbDtximxXEbgvAjkvQVk2nCYnE226WZmeBw/Lm5uYssHPH/O/cn86/zHr6mKN8IBN6laUii4n+xtPR/k6l8SaXyQ2t7P3bt2qvcOOL/dLeVf8KdO71Xr97ywQfHeXPE/+4+frJcPjni/3Wfj/gf3ZdP2vu+4imf+uabx/nuiP/e/aiEDYM/f8owMEACBJAWJIi6YMHU5MvnrkABL4WKyCiGYwePQAwRkQcSEm/16kVr1cpNmza+2rXz0aFDcDod9I8ZB/t+7SSMGWmzibLbjXA4GADCuY5CYOiElj4M2A9ax0FAMIeE9F9QTscB9qNb0cBgUeF12hiwX+TUbcB+qTY3RxzB5Zhj4oPXugUBwf9kyLAkS5Y1IqKbwoWTFiGCmShRtPNcW5cXXjovTRo96TJckCmToCzZ+L3yipkcr12TKxefPHl45cvHkwKnWMD+wrYpRYpcVaxYQbzJn455jYu/fubv/V3yMBD7d474U1U3xnjLWl+7cuWZi4u1a675lQOfJE/KsmpFUa7XW2AwmG80qlBVlSaT662sXGc2G2BtbQ2lwnFDMhmWXA6rUKArlQZUahyNBl+r1aPTGdPr9RMEIklKoShomqZmGKRYJx8EvKP38I+TPACOfkZQUwiFskQiOAsLcktLeCsrEmtrKTY2pGIxTLaOfsCuhpJIREmlEgMd/QhUx4JhEQgiIdTRS7DaCMfpZTKpyR29QlGXUioVqVRIqR29RVPX0GrpdDoQvV4lQYCRpDKKQot29A6mrsaytAaDSKNRhckkzmxmsLdHzcHRaxzrVM0AAkIlWrSY/76NWl8sniZXnDhsUFDxgTkWbwCA8G5kgoCghoRUAgWlULx4GgkScCRKREySY/ETADC5G1mgoeVIkaIKBkYBLKxoODjl8PB4CAjyERHRkZAokZHBpUpVjIIiT5o0XFRUaWhoROjoEBgYxJiYkGGpxVfY2D7gDHc3bgxPLf6Bj+93AgK/ERL6GJFutEBMbEPS1eJvMmTwhL7z5u0bHz6+8uXnB3/+/sEI8F6gQJ8FTfBiWBOi8F9CJ2wxLAl34D8gwkcUw0WkSCBRogBEi5MtXjw3CRK4SpTIRZIkXpIlC5AihR8sLE+pUhlKkwYpXToTGTLoypTJW5YsgbJlM5IjByq5CveSB68NAcEIIqJhJCRDyMgGUVAMKFGCqVSpfmXKjCpXaRYVVR+aJlc1T+9iuPVN/8KPMDEdGzDgSYYVI8WYMdImTJA1adJFs2bJWLAAamluLXxgxYpNq1Yd5bYPzvnW8TRb7rpr3oZtS3btWnPPfaseeGjbgWN7HnnsnifzbDHynntOzok3RPJB4UU+zpfFiDud7z/4Tgn8RqBobqRI4XOJjrP0GBABByfGlClx/vxBBAokIVgISREiE2egBxkw7iBNnMVHqWaxZKqdhW+2HDHjl/2Oncgf1onkLyxLfjiOxh2eAIOxx9Mpkp8xAE6dcfrjGU7jasz/T22jzkjwDu8xwQd8bNP1PWFH/2zmwf+IYxjX7XwH38u+n0ww0NglPwT+An9H/x1DnEHu5v95N4vqd3hZUKlA68EMUIYD6oKfokjZoADAAf7fUV69jApwVxjDxNXsmzwDVIXqmwDU9M6iZsekXBFtHQIH9eI8qHs8GfqW0AKFcHydh4BPAI9cJUS7j8DzLuTdL4frLTgvvkvx0TMMC09W0C+nw1dKa4BnwI7LjNLV8nYeJUBJ3bCXwVqAbAXU3rDlZ322QEjyFUJ54clYLmwa22/ePOsR2tUoWoQW/LqXjZbxNnjQNm80wju7K/0f3tDkxTaHEqaBWB7cuWvJsRiNoapXxcHQCaAjVluYtKKW8HcCj7/yRhZvVaeCPHCa6DY5+e0Er+LTounu2mcgN6O49ypehBI4QosN12agpIjYiAr9LaAuxZ/yhVDGB6yCZtG7Ikc570Xq4qBsaLMD3HfA5ZTRLq24ovKVzsKjHzpY0UcRbJE2CMiNlnskSSAmW5lHDVQRqhbaiWswA4O9srCERWldT6esvq5qEMg9yZxZKiBFNahPJ8/BEKnqQEw150lxS/Zn8RR1R1TjsfNHKpyIY9EyW+Cd61ilE+1njGkeDQDhbAZlE6Nm/UhlmQB0G2DMuqDviYc57a0IiFNvnJ1HHuw8MVunJFDgy9H4UGRkCa3KzminQa1+ncjQZmApOafs4Oad3rHP1CraDHhjwA1HPlQWD2ZFQ1l/bbCyJgwNGGHHCCeFkbtZLGAYjpxWrGVGy4AOUrn1Cf+hOObRRU8TWDvcKU18odoq8DP4Pu4CmAiclELE6LEanNhnKDbQsQcDWcSyJHbPXOI/pYwBa7gXIKrbsds9nZuU7pVUbhoJkMU5HexlQNlCuYjjMcwmb4H9ANAqEyo2sUl1HLhvjX9rkw5/qvlJ3tOgcMggkFq5BB6bDhiRCGGo/jFfwgSw4hJEYJVLQkt5Bn2JMpw5BJWlCu7uwqJCLQ2coQMZD8oP6Xo/8n0jfXYltUDTTSR6oC9I0WCP1771QebBIgFm1kjPStK3sgysIpxVhbeaCFYX0RoiWVNkQ2aGYCNsgky7Z85eMCh9dJktb3epX9CL3S+Peiv396co6MMubJDT3RWzNdkejEqhUTplUCZlUTblUC7l0aozE4BWvJaER3ukiQq2VWHXPM3y5LjFCIW89/np+YzEIGrIpDUOCxzdm8dKJTkZs1ktub1Pbrce4mmqia7cJ5HQTVTTNH4mBX3neipDHyxx0F4Icj6SUdcE7C0AwMdrvJBS0XI+IzlohRreJ4CdNrv9E5gXK8fDKsiKoKRVe/IUqRwmxsmoENC7zP7t+PdRtc0Gclcq9J5c2XwvpEdn+NEzALDoLaPcPkgykebBvqrD2et4qohWYgEjzEtkWBVRD3KUpiXfCiwnwxt3w3W4UftsHM7Ehts5lBR16iLXwzkl+6z0IY8NTc9RpW8ZNYZ2mOAMOqzRb2LpK4GJeETkOiyoPkRZD1vmgS08oqexw4E1X1/AEJWaBYwlCMHjB2hmV3YeThvayctSWOjBpkS5FmGCVxbivcsAKC5fAzQIFiys0CgI07IZ3OmhM7TCWuXmknhyq4Wj0pyO7V8wzICJns4tJSt3L6y3qHm+kv5PTqy4OfMWIU5pNGjiSyd0R+pEHK2ISZFEs4Xhmx98oo6W3lZrmvo3vANm3lh+n52ee1QC8K/zjPdkZmkPDSIyOQSA9U0nan0iYD4wsWGd5/p9ZHiBdf0RCe2MFtrszv+NaDwY5IEY9uQVXlDaV8paeCSnXWA2qxH7zDHHsuaUSyLEp+cO0+X9jN6dH0kZ+XRbLvZfIoGSNYqJyF+V7ekx4uT6KsBWTIbq2GdNuXRqOXMyk7q26F2EoFLDICZBLVu28SrNSYO4BPXsVr8k5OJSA0DCCDRCidsIuTUBJI1AMyzn7SlYkU6kJGhlyzVelTVpkJagHVvp8qQCPZ3aX2PCPAwUsiFYyEZgAcYKMFG4ME2EMl42y3TAdWqOfLpQuCQoJMtoATysCPU1ATYThGaIW0XjTtHZHmSDh2gDRwKcCO68bGXwohi8KgZvisF7BPAgwJPgXrCVxbdi8aNY/CoWfxHAnwAgf6LS8mv8t37fzrYs5Fauttgnx1ppETv13WzA6qPeQE39WxS5TCoSEQOku2fv7jGfAM8ocPdPYOsPkLsOSP2MbWdSSGRH5jfFgCNs6rt1NkpQ/xZBMeJngQ5VWUbctPDGr3w0MKLOvLUmtsNWli8AEGcjMXsL7hHm6E5/dFNBQZKRLSJ/GyKN+b/j0Cop2rF3+Zo4nYtHsPH9HlxMrA0f9xAGJvWgwBRk6gHinoHHA9p5bjjlzCsyTW+llkwNd3pWIhF1LWiF8oR6zrG4koZGJhWuEIY367s3boiXzxcW4gq5YcHp8oHSUJMOCcMgstjwqWSbAhj22ZO1Wz7kJ2GMeeeeFpykgeY2GB0JHSdvqSWYLJAfDu8z8PJfbs+t2hcbcMdTJTPZkiSLGSxo4xbJSxMuq8IfiZvwnMN/5CMLRmW3BZiF+J2GS2GjpqU3LdPI3Zv+Kzc3Sr9OVNrmrOrkPMozkYB+Rt5d6vrAE85ViY4kciP8wEfrTRULf9OE+Ihsok2+6hqZ1Mu89z0wspBHBKN32WVS98131znVxVOY2LYXTjJ1+l47mmgW+QgSl3nkRLQfWP9GyGIcr+gIgU0h7Ey3WApwnSdjuxzBu0thCbKbAfRVAL2balcV//r7vmHGqIJQJbpR5SofKmOI7eVn2ELsWwZQsrrgkoNOoLcKJacHM7GbxMsE749BbvR5CY1kXSx7BtJVkdY52ati0ChFl/IBt9c/wT/4rCsYYpFMfFheaNXWf6pBK0tEdpmUcAtBMr9sJz9VlaOO5kU+4iSBzQRqPaqobMzt4sCatZEPwTAj+6oWuyvqyHS0fo0jUBXZjU0piXWDWSEQW5apHVOoqaARgFe3Py85kRzCkJRZrT0eSW/EQGUEIVyKW6CqZCMyThdy6uGNDIyWlK5514/QRuqRzqFTwzusb01aSGuiTM6BEBD7ZfZ5dVSVuiKMdKTR1Psv645QBl3hC/qflBFIOBl0pEKaXLxa6UznB7wb8AROC6XdVVL50dElO8oQERNRIDIGpDNVj/q0VA5O7c9YX9GQhzjUAS9GS64fU/LBnemRfko+hLZwvca1lNB6xTUgLhPp3dy1q21/tPaos0r3r1kHR36VMAlVVnc0BPgmfM394NjGRFKerGXyOGWrNlFON8V6W5KdXSXEZQwyhJOeLh7Q5hTjOp28Eluu59BS5eIOuK7x2vKTN6dtvs8WqjsL+Wo9vBlVPs6rgiZEhiEQIADYiNh2SSOdgyFIKSCuS3eN+crev5k8YiTN7k3z5nq0vU5mXB86l+dAt3nqjyfjz2pEXMpOWx+LAaJ4zPmaVkD+qcOQQIGZkAAISAIWLTCA0863STM/8vtMuFhbDe2uD0Ebs9xHueSZXk5AF2O99VM3+hLSbAC3kxXhtsoDCP72AMJU4RZ8iUDpTEBzINPbU22qocncDtsNSNgBPquk5QMuo6cjX9Y5pCXPMl2w8DFfCJe8x7m97nNdGWYH5ZRuyQdlxAFY4fmiQcCYWxAAoRtjYmcIlszuu8Tt5IRwXw5g28Z0xKd52Y0cx6sLKcW+i+zqCHDpPu8A0jx4W2Im0ik9A5zlQBRORhy6T432W+8Y8Lm9ot/+yZc2hGkoreS3UlcKAMQABv4sLIq4S5cIZCfsAgDwoWStlNRaTjuU0G9QeH04CHG4FFFDICM7w3Aapku4WEL5YAzos1HxjJKOI4h00gN53OzryYco8dnIhKUA2og/WXv0r68yIJiTXp1cRYHLTBJghI8qr+LNXnmhssjiCxAurP66munwTxlRnsf3H3+qVA7XOLHG+Wtysvp0oksUMHi6nauZz/VZa9BYxt2MSeArBK2UvjgEk4wQLhP/rEerXtWH2/mACx7mc1NVsT/IPGU5AX8+tNoFLkRda8wzWbUVC2TB5yfJA4IN1MgMQuZMPcmumbTByW+KT4OOE/X54PrNqb0DNnVpMd0vEMDCQN4OZubPvDgxMnYLUBNSiMt/lwA87FdObUpr61EvYAwLPjh2hzQb/JEEIVhlS4R9Y0aukJkI5kgQq3yt3+KbotYab+yHQB0tgUCSXgPmdpcBoIbUkvpgMjpECgikROIOyYQUWjp0RjK0ScQ7OcLU0AFCp/X303VJPI0oPIGkFlqcbdmBt8xAIx93Jq2FvcHOAa/C6DSH6MA6He+ndkhOQebUB6/5opQ/0xvPsyz23hcTivnk/n9k6eOoMoIoKXOWxdMXgkUcr2Xwg5A8f6XumNi9P1zherHFXC1m5/cNfyhgw0LJ8Nc1ty5fQrNlGbAIAGaL+DUdBSKpLxLjJEOmAg/1zpGCOmNVQ8MxP/LzTDTXaSNn3YSpKS1zldCCDJZ0yXuSp8UyZ0fJOnmfDcDyX2/dfQeGl34Sqv/mc1FH8UdsgFSL3TJyLkJBEWbGBkpwBMkeyVL7Rxsw1yybikLUR+xf1IKquZJt4rg4UqzhBCrV4RJuR6O1KDQRFQwoYTYo4//O327x2hdGJAyMNVjoihK9xvIJX4NAgioo6o7QAfKlZrjtxQHsX9VCI9P2GR2foGaKjdWRTX1EYd91pbFc4M6aSi9znN+HBWyrdZpr87ue+lDP/N3pxxFERe65z8FwGvLXUYYO8CsCG1AbCDf9I96imC8CcKTmy0Xe2VABfu9im3oam5Z1XrjJrx+4xc5fW75ty1i1QtLAJaABvQrGp4tpqicMmrLtHoMlyqCIltTDIiS3AGg5fIPGMGurAldGXl6JN7PhOJziHobs+BgbMeu5EtGwtupNkzMfpOA1RVqt4EgBHDkbUwl9DegnlRgTTTSWm9bkGCtK1Ks7QgdXqbzkYIgRl6pMl0RCFzPag64y5Tgn/oGrLGxi4rWmM5pMcW+Cs7MQo3l23b6xVcGJqKHG1cJh92ZNUyLZcrxYlKp+wgI+T/baNalWQaSaFLGYBZhKV4SPHOhgfXzTpQRGJh2EftVchTwtNlkzek2xckA+ox8mLuCquYNtkX1hW352InwfD+uky5xqLcHGvwa7AlOkpeTUWIw+kIH/wjZq1becgP6EdUzxAGWni5tP+jcY9LEIEDN7aqGEFm7CUiWl7NSfc5QELj8aTSvMGueby1pJcsaxj2Z0gX4dS2su6+Oi/YIMb5C2qtSlgUIy8+DX0Ism+p6sQCkvNaT+t+lISALdcrZsbGLBVustQpvCOSiMFkLKFmNfAijfyUqTFQ8VXCwXWKVYQsoe3yO4zpt0EEmdNOboJVLuxtiePyQxi2aKBX7qBid4Oub5Y6kYKz4J/nihszIvMU7NKqFDVorbkqTxVquQ+1BM2Fh3o8gstZr+GZAHnqNF//RToewRCLka8h5SgfOjZ6FhU6R5a5KTHI97tZwc2FKEH1ztPO6Fa+3H3I65Q1IPEt4aNWqJwn0oxX0mlJa5UbRCitCawkqNhelpAUSkWU9FGgHnaezXHT1cSds5Wrz9vRmKi+5pXElwfhnocNzzjZ4vQFA0bWZ4NniKt2rte4DVWXuT5c+FPosQYbqKxQ4EeeJBqa0Krc1RGgq0hGGU4xjNLl2m3jspiMNiuhYfi6THFxxRo0WDKY44X9pUaVwuThITUCmANxtZDlLJraAoXPNPBfnLZAGk6MwudiPFa9SNeQfIc0M5xOEXsiUlpsLJ9xUahLDO6BqHfVzj0wvW3w43GNrRIB2P/NCkVfv6l3FitBg8jZoz3DizpAn4osiTWO4I4v2m5gCXksAXGWsIt0oYaye65jB6gbwGktTjzo+qg1aNgf24uUVihP/+GZ1He+0n1PWdY/MsX7Z3ehvMNSEJUTiQXt0um8hoZHfO072VmoyRX5/DBHRVYhO5tigOAvagoMBZIYuwqiSC8VVIwm36SRbwAkLedeb9rFsmpj7+uhGJwAxZZUtRKIyYM2xjZ4e2KaKQOtTexh0MEUg6UIsbXIzjaRTOPLxSiAmh9rxooXXOt8Izem7dwZgybNUHZxjDKgpS8tziVKipFVbSmzoYdmqVeZ+zVujl74ThXwbeAgFirYKmtXCv2wVeSFyaEka6729HbCCypKRoNqjQ0Ve4qDpUm2jzzAssOMlAobLkVTGldaLbNRNz9QL5uHKlMMIrKyhODo6UzQNcwfZyrY6kz8xN1JuiL9xYEESKHxUdbWd6ViJ+xCh3iVX28aTLauBdEc3sTiLML6TFjfQ9y1bJH5VAyHAwEsZz8pJ/EOW6ag2mfqMpuxFUzy8wUhOcSe1UWXZleky4N+EFI73eW6vmVfjO4RJvi5pu94eBqwLJTsvsFHlFAJga1ILAY2Re6EmXYls/VgvReGxdBly1NxbDIqufdViS0oHKPiTCNmdad3BXu9/tlL5om6hDI1HDEW1f1WYt9dfL/aSmMLBW9nLYwfCspdh1cde7XHNdzUxVjJPuTGAKOXYK8eN3DU9UwBxq3mxt70IFcwjks1QZCU8kxtKpJBcpb4zXPjRQYCGiH1hSHgf/hAHJa0hFpCRwKsnfVAJU8QtXm1Zjxojq7xklm6+tik1F2ZhS+G6oE8nWMHQqm6EmYjd3fz15cioUxhsSnLwEIPBtnLQf0NRHW88JlU0nlU0k0RAP4WgDTf4xGeZBpmJKPSmxeSOVzRuUGCi1l9ZAOd6zn3IqP4eNxVibt4WNhi/sQV3McsPjdqH2FcxAHCMaz6LA1ivkjbNB0F9s1fMtuN09C0CjbMQ79br+SDdL405dJ9Z0Wn3INL+QFKBZOAvMWYohhwyHsbZvt4kPcFJJum82erfXjQHpJa5SMEdZgLuVwXydiuJ5e4VTcW3yp+gsbj2tfZSJBdWAqfq1MHBc+DM6MC9knXuD2PSd5y15dyrqxEnFnZHwUJi4FkmqRk8VWTkoJzfRxhwvERW7FKXLKlyhcTk+B4NdVfRQCDu+tNPO3XggWGXwUcQGxOOXSMnF3j0lNC58ICoPnVVeyoxTI5GgaID+cYGLH0/kZyP7dzFVOh+X+8gPjgf4z4JA7N+cRxb+CwiuFoYbBr/rFTPmF+fAertD1rM7bZw1IRN8JSAegcHAFnMAPYfHTyV5bk9VaRTg67AibHfa281Slxf3qXeeMmdTO8VOaYY5QFDCSumpm5jZLC1xiVU1w+yh50xX6G4O58htOuhvOlZov7w8V2sxG2pmQC9U8iItHUoy+yU2VZZg8C1IYkiexI9tHKqAKHfhEcEI9IVXW5o6wNxE3QvjrQqokjAyq+y+UuhdpHaNXM4qFtyhR/Ji4l8BJQP8KPXIQLp/YLPmaawYm7xOBCR7kPbwpFYyGHxSs4cANHcoyU60bIrlv1BIL+9ZolBqUKCs4DFtTIDOTKdJDf5xuxZl29iUs7QR0wxCmyT3XaUnc4zBgnW+AMmeo4LFPNv7Cw5E9VZXqERnQGMVK0A57wmypTzn3wzhY0bF30tjG3dw3nanFiiZ+SQdUFxzVemu1jwsw4NKcw75oSJ7VvSealyetE/zwunoneC6WFJ6P187qDgT2Ln8UeXtQP7bX6GSLmOZ478tiFzCyz7FIqFU300myjbd8hB7Ei9AfwCkJnZcu8QHfqaM4uA1JqkJvD30Z/C6CIRcyFrD284qdigFxWuiKIu+g8uTSuiEKn3rCZhcYTt3IcUkkGMW8dAixkBlMwq0bCugMRcJ6S/ObGRVXGARmnsBiemzabipIAq3GpdolaqKzwVKSkTUD2OXaao0nJltoeRMlKNNusbPWgDJBGhM2ghS/xdsyDdcyg+Ap0W4hwzaxw2PPMv5kEC6tCXAjf10cuxYbfHEJRvkB1DkRoEafsuMdgkCwpgHECjP/nalAQ7aGpJLraY3EFDj2FAlWU4cW1AWJWLB849FFSOZMPkOw2WJyojEulrxA011ulB86Q2GBemxAh0Ff3NPluM1dQ61U8niW1dlnIX6OmXOWDoI2syXB0yNHazRlcYY0TqQPEzKKNUx4rMggXTh0ut8yuMBxRgsTYC4NerXooDYaz3LGJ4KoS4TFcb6NsRArLUQ76J62jH9yyDGCXMOh7qMo3FlU9phyzcwNvNptCdRmotrHpl241ekk5YQgcUBGYMRQ7f72lND3Hnv0YROIO0lkTtpFh9rrJxzzS9eci0d5ylR7iMlS2/sp3MBOFARR4W9YyX0y7QGDoNGwnnM0cjFshFXFPP7jBvIQFVouHhWipKdhkNcuiXHsStOA3f2uvSZdLsnlgV6RRwc6R086P6EmB6zKcBicMMRVLLDaFA62iPE6iXCdFWLv04eZcpLzbuG0hI1umVosys+h2acqhstyqbYzAQ+ByBjp0zETE3pfnuQ0XJe3gXFl43G5YyuYsZYXTxOPlYG0DsiAiLLcf8Bgnh6MhxZpVI3cbpp5uNqxyXjFwSFHGgJLoXknZ/6TKud3/1JvesQMmkrpzQwzyWSkvjEBELeaZ1S3OG7kCKUiqxxvqRGQDc57BPgLYpOId868NNEV33Gk/UEF1vzeefGtTmtlNA11n8KBZNeXVUUIGH8Gx2Yff5sT9SgoWarF6iShg44gMZNNKUituaX6fQkpPBcoOTFhOeTBBS0VsLqM7pRpMXfaIMYF5hfy1SUxKiuGKj4IFhDyfQ1q1EyrP5xertCSrsPaFO2auauqE8O8etk5KbGvFbXGtSzJJ3RxDgxIU61LsV2alRuVeazvIgleBD59ruTuY6Jc1K2RsMv43OtatmKI17+T4NBhZra8l9jvWCFjERm2o37orZMU4rRK0QeVLoa9Z4Ra4lJOdssmT4xmGhyeRagMZs+n/qptOVX8kea4XlJO4iY2bHA3WMjTM+GyWIYBH7Gv84Ku2VlnytS4QBlYjX9v35U3JJe3dgVW3FP4cR3SPm78LnUR4Wwrdeb5he1l/xs4TafddG2CHAXnLzCWbumrVHz60A+RSYXJ5FikVqKZPmVoTzV9T/b5fNcFiTAjAHDrHL/FxLrDCA8L8sXJOsf+WrmfZ0+8VUizBz45Vt0leNg15VgzdHCo7hrEvYVCVb4JPte2O18e+sZGNWjjfbIsO2uJkhhXkGjpaugyaNSQcsHmsybMxQtWJPqWNYtfo/+wpmbTO3eJJ01VW4RMmZWNOrwVeiggjKfyZlOIYCgwSzrg99xx9up/BKCDEj2ycukX7JssFdY7l5k5PyLokktL1rU68h1O9Bd7oqyx7icgCXBfqmcbJzUvXqB60edMkOYspUFtVDAFiqdtJX2qx3DrGVXHbHOfEUjvPvEaDT1v9Uf9cl5zabtDGfhKXkvjRa05OEy9ed/xC48x0UBU4gP35RqCe8p0bqfNkUgOA5FH/5TfyH197w+UPe8kxdSFtw23yHkJPd9JREA3oQvf5FGziFXbRPqIO+tiSU4UFQlt8bpG9z1EiVHBs8k7Xo1c9yKgbrSfXwYE5uHA8VrtGIMn6F398d2PijoFi2FNuTbvDeW2bk0wrG0fiA5SmUINCHMHRUgyAnNMFcuCeR/1Rp2t2cRz+feTy4IDa8dltpjEau7qY1MX98tsZtQXrR8KdKCd/lvccZxy93JlMySvn7oHsvYNFTLOR6pTcO2HCt52yBcFmU/WOQcHvmaDSnpzGGfAtz3N7PPrKUOfM4utjT+/Iezi28mHFGoSIXKHB3qSQXjGh4w84bE6CnNgIp0jsUCqL6G+leSM7qcEr1ucDemysGC1uS3vODJSdzwySsqX+z/b8xm3k/nPXo0t1oNsrabH1YmJ3YwgY0OF3CZy8R6y2LQVmihPtRN+xSPWUuCw/2sjXYqttEFKVk1AWltnmCX65ZlFZcFikyNJF9bwIjtSJZwhAEvGvp7F+WxuEE49ZmCpkf5OA8wm8yRXw4O6TFlPsI5r0X3db5c3zA2pRkB2Vcan1aKerClTad2U9FNXQrxMpky/4mUqdD/nAW8KM/Hyi2enH3hLWgqv46sOCBaeaSSKZKel4eg+WCELzloIwgZ8vPpA5/1H3b6/3X9AxI201FCnowMSkvJWopagZ8W074yRYNZXfPIhQx5zE20aZ98lWa0TcTAsWEBJgxt4PLyTSTljd7eG1Fb+S6AUGLsMvIECWpCI+R6twZNTSkUlrJW/wPv9lfbkLSaXZgvfYx20rESBoqZ28oev7BPpX2uvC+zEHdKGVFGN0XzU5/lBlmKdmtyh2t6MJGym4X24BrSWU6j5o3Xz4jtgmbyOVNu9sYKdmu3aTsyL+Gma2zGMrd7psmqN5+mXTA1n0dMdVuBs7GNHnaGT83i4xlJZY8gTPvwsj2d0+ZCmwRn9iwnJ0ty7YZgades+cIrUdg5M5/tCAOFnAP34jswzuK3L86DNWvPs1c+pDnFN6ALgLelQNCGbyB1AyeWwNiK48XPurcL5CtcAxUGPODCjMBwbyv0k1B7YsEdQtOiTB9JoEQaunzVh59XEviXXWBHftp4EJPax1EAoVikXdaavr3TT2stGbaeI3mlr+y2xa95UMTXw72WbIohkojjqO9d5x4UQ/VyogfwfEwXmW3fjT9tPAy969up4Xje7VVR/6/TUj2vrUHkaWtLsJ9/fb+Wy+pQLEe9BKH3mm7p6M3bEit94yAKjg1BZHkE8eIl4Xu+1B/m2DoUFQiPHYIHR5vLM0U1OTwHH46u8yGJqQFMWd91G7aZpa1d35tT29Z4ZhKwa0cFZHF0iPpWFPSlQ3v64u1Us3Mpua+/UkkMq97o24NW5zNtcvJ6nuHdtVY2ViRox+xBlEyk1l+3qpkFprnmsntoyJNKvQF6URIvINLAQkPp2eCztnO4nYc6U9FMYazW9D6CwZgUj/to9Zs5Raa8a4oFDs0WDQOybIk+WF4ELZotC2gOJrXMr9tlKJ0YEl9yd9DkUmd2ubcP/u0kD2nzWv2k1roHIecDLmV3BU+0BVykR3Nd8l5f2KF6kkB67cDLoYePioo66JHtuFFGWizmH4PnV0KIQRbYB0fns0mWK1a6fLowEhbAVTy7L+rYrWhjcQdsQdBhpAw3cgqUqnAcxXfpk1qJMQJffUJHgVn64TXwvRpyMvE40OFgy3oanwgzcwdwa4FHpvV7ROzlFWpJDakBr407BgpKtdL2QPNaJur4ouswlGap2rnxg+I4ryzOXu2/od/nVjuufX0IOc+9YMiudo6i2lh81anlhvt9EzSJzaHQXlWd0swhWKAt/7Opae2tXDQpG7tuz44a2Bqk/V3P7AmoSYjZMihTI/hYVHNja+M8DPzyyz1gwfSxMGA+VMdU1O310O15eI7CgSrEx0GJF4ZnKdUk+QM+LetnluZubiMVE/P58opcBqNANFV4pVVSA/pIack0rFQLSUOZY/Zkdk9gOlGz2rrrMgZ0a+Nf/DcCV2Txz9kpQT32t2Rk8vrEffY3zlHMZbcJq5/+VnuLsq937HK9c/bzjixb6ehsunzKMTsSYzc4+OP78cgP4ShtOgzcs6M9O9QmpCzWI0kIU7iuhy+Ud9gJdOKjf1yQ+rtQuEYrzoVlLh3/EFE3XMDxlrdISubP1zKe7KSlSqaMbWzS+YkdZzeSEu+6iX5xCyxYlf6reJ655GORv9qe/wOsfGX4R6Gf6v/8SdBHty+zwNA/3TAIvDd8tRX/9ADnLiKrr/JpvjJ2/fBXCV4kHsGqE3enbGcfBMOfCh3xR81jQh/J8Gbwqrv5TuY1GDE6T9iPebkqFS7x61YGilpheGxBangqotIZwKw8CS2i2S2gmOYoAEOxa3aJmxMZNccw3mSwLNvo6aBrzMVp8PQVwzOUFNGhxF2deZED8h4iKwvXDyULaVYJV2UsZPjERu/s9+b34nLutz/9yuwX69XT/ml6Iftps+Bp3DPcLxruCW6SsqEhBAj8TLjn4kW417Dpw2N+Z9Tb88Fc+HSD49959WaaJcPqW+ohdkO7qtct5O0QEfhmIzftDJGrwO7l4DuSISgUqJes3foKTyd792yihWykA+uX+Cw0hQXWDVB96ZKYkhXztLxnqzx7Gn1hIk5+cP1zTwUIn9WEVSLspF2lV3Zi/zpHpRySwNlaemf5qcNxYft9XJbXKcUtR0so3ouvf0Hzl3wtDjqU53Ke77719AGQ7oyrAfaZ8yHrvtVDqn9j6Q4KDvTCGYcpAiLnexBmhfqdVe+n6qWIdfe1P8uwsx7g8YTZ7hQlsGRK+w/aCu8xLbwfq7pmucR6a7z2FvagXJjX2nPU6yFkFKXgm1f7LffXAQ4xKhA8TI6D36pOfcDQ0+LuR+k7GdXfOVXS4CEZ6OCAXz4GxwCg8jMkq9rmZU2kqoIRfsCUJnjnNzpiIjkRC5zjbbie26dFmO41GFiQ21h3HrtyV1Yg/VUeVl13Be9DLkc2MnbYHeUpIRlySHw+UIAkifa2QNOUoCx/OPqogAt/dJgvSLs8sAN76VFR1pHA+ZCA5KqYCjfLI50i6uT/kE4prP1N8lP/mwl1+6nwJQYuAT/G2db3SDd5WF49sjSv4+CGvTdh4SXIayV9s5nZHej+gujFMy+4cfiZDcmrWAr+cfEVjqq87CDp0bzaDWcXcjpp+WUKy8tzUsDa4/xHb7IavDwj9/aGX71Beelhz7qJ4ICVoX4DEx2rkSXg/lBTANez+Gij+WS01499kWvnVn93eaS36aD2oPtstNUovTQfhFv2aCBNwCcqTCJ1owe2zBmznctZ6Clo1rfa8ejlNbNFKNvByA4Hbjz0o/HlR9UTz/bPTZ0cVxPGgKO2zgamId9wbRaLKnSZ3S6YJLBeqHgfJHnwp8blIwGLh9ePYbJ1fY7gmXTz2GxVnWb/YNaFBs7V1T30WoyB6u5sShQuEMZKXqDtBQxpjJ8NOEGcJULffj+IPNguxnPkAWrHKc5ghNgQEIcnKHAHHV3K0zNJkX6BpQqVGAyF2SPSCskaMrjsU0hVL0Uvc+k7vTvCXTYy4Z/8a88hzz1JZh4ZFlcpY2nuFQxD/4J23eCtyIABXc83Du1pIRjySxfWVHx2I7g4gCL0F87hBQ4fULa8FYXixFyKc1uKJ9hHJCBsi86I33UjullqIOIveVR0IZWaV6yx0/j3pO4EYM2zPM+z1NhVdNfuMZcHYibeTi5uTvYES7UYTIVaxySn4j28Zqc393nRFwa3VxdXRJwvJ/t9ef72h00jf3Kcjt/NDotXoSj+t9tllBWniSU17B/uZXHJYGWXLyQZrOHXIPYGOKNCvT22DgE9EFek+l3tU33vqpzoSdlRquyi1ZgdHvLYIRoZYWFQTZ9Bfi7DzLQ3t2MiCqVcTEYJX2aYwSxxz3JaYFRlzYoUrXRdWIOhW+ZzkCTlKTUsshXluKYwIhGCHRCOAwf2pzNhuGXQwI4wsjANrU/VsVt0a4wXJcLcCMZGO6fH+KkGTlAuZ3KkJfSpoAoLTem62e+fCYcZ1OCiS4Kzhw0LnWXQyA+HZDXWUh7t6rphLvgATw0IBOqGLdbVnHL26rQGJjhzTRYsYPIpzkVdgbpKYVlQvcgWazad5JEfFuBBngmqFhAVGnxTQZGssSAEdmeoLcIJMM6W65DgqTbfvV3zlV8s8aTMLybMkVhJfn2r4BXn4CgiqaX3BH+sjioueSkW/LciEvqc36uCx99mRyGMneWZF2GWNoBg9iedu/yVzg/dZ6YTJ6U2yzo9mzOtAHsL1qWyo35Xjy0xWG85I+hcHvUj/xk9+0hk85Gt2oWlvxTNNJtkkVBbvJ58Uwgdgtdc4Z7u2USYys7K6z0GFNsO/4XCL9X35jXwATqQJoStok/xs0iypypqiiLZHlFDAffyT3EpR1LmXSonZOmWyfM9ZSpdUcIy7wTIoeGZOUG/wyw/xtXOzHlT756RuDjMZ+fr4FrzAZzHomjspKrCBd3p/lyTSH/T8jIMRA/v/h6Jh7mSD0r59A4OmIpf6Z08Wiyn+D3rZQTfDbMvhY/IcO1Km03wVfHkMdiUHxBhC7hjRLLvulCQJmKnv83GWKQfm4QLxXZDtPxrFd97CTpR+G3O14ArpR23SxLzTdWQxXvxJ1HingKYpa2YkCQ2KbRY5TtJM8a6ZnE86eFKwGOnwnY39Zo4nWtJXyAuyzr7xI7BIoPvpXdM4Zd0q5QAcImhUjlr/v8bIFq6q3XPPBfvHtOONVopO5bUcW3Nf5B2VgDlYzRDqrdoIBxzpOVRsiOIomtVFgzJJuR+4FmrRdxfBQcz9mg2cWK+wqbwctijugaW/OeEG01/Bw7ygkvM2GnFncKSOxUsu28haQESLSo7TIWGW9Mp3Kq51vdYDM81k5CyTS20mv+gKXnFwCwIBPWF+0VWprW5t+WyNwpVRi/lfT5nfrClAHlx/fysTT12UEV2JAk77LDB3dNJhCHl1FDJH7OzBak20j1l9nKSvxHcLmzsuEf15D6unGyvY80OD7XTzuMJt8L8A2rRUGCKGlaHiTCXkyDBYH4+02taa2uXR5Wl8EbRokRQW3U54MHkzqYIvh9sdRXtLAsjcR3usLOu+xYEizj2dMDj4m/hTvKfbZ4jzbqNVbb7rKJ3OFqQmhDry+FabvdjdL5yEQk28Qolw46n08PjHMpirTK+1nKWaoMi+DqH7K4d2EPBB0dwh4UV0H375IqUSYvmGUUyngq+Hyu0vzBLDBLBUxwNcMZDkh/bVC3nLh6rZMr88zHpDJR8Lr/JTnbkkVBUQTLcLIp5+KrM5hLQ2U6a/U2p9mNuPyyl4eFU+I/JImM2ZjRD9x1AYVnhQhQMmtqJ6Uw5f5mX49wXvH3KwU57N724lyh8COHFCbVmv850mVfFDdR219SU++VFCoVwYbWpXOnMFbYbUJya1qMtN305ghnsEhiP4eMZ+c5xedrbkKyLHc+9/nt8fukbh+XsFdPIaseBH7NWDczsuBKwvC5DYiXJ0nyhsMdbjNRDvWE8cb4K/5hVHW5kIOo6PmRbzLoWqHSE5ou0Qkdoh27QclKNaBL123s2N4FQZWvEFnCgFbiyz/tclJz2DtFLFmU5fWjbohi62RnfV8kndnSD2mKsPAsDg9Sn/BHM7fqisM37uXo29DfbM+FwlbVDY2MjLh6mly2X52n/U5ydc/wCD4/d8akfXs+3Vtjln/Jsz87nvnEfVLB55MYafBLPH8JnWcqxB3c/ormCJ2nrF4UrRzXs3sxlNCi+3PTQrCpeCItVXLH5TDHOD65RphUspaqUMEo9WB6y7JUpTr5zbjDyLjKHRd2ibjkkPlEl3Z9MtIGwNYoZVo6DhFOsrzxIGtD71bU+PtVlQ9SDYhyOkaVJONZSybFhan+QnB36pOvom7wiBcFX5AbRQqLpzZqr2jTEclrCyn/+c/wlNh8F6b4ZbQ2ipx++2TTy08lwyOaNF/L7/QSSzvsKtJyhIAjjhktOO/m2dHN1y+QazyYaaltLbc2gpgh3qc5Iq6I6MkZomj7VdNJ0NZipVkjmVPDFPq1ghaDdv5kEwKKKTvhIkHfekZilc4V5AlO7RVt2zUJumbpuWS5tua5MWB8Yae6BZ2tvQtFVnElkldDjf40W46QmDt/EmbYZeFKxPFVJ5mORSv9WxewBiJq/g6guaxoBMUq8CqckFlANjaCEzDDovsb9QBZqr1fyZce7cAwX6ht22N9WtYndppnuEia90E11rXyf2+6R58AGhmpfnOcSaTBBobEBi6JU0zZlnXy5Jgzf+QpepjFna+pU678V0vHyzlQufqGU2MULwtDfOPe78eKQDlhdqb3wdknkRXmpghIP6YBuuYP79JC7hpilkLs5ycu5RZbTic5H5NiF5mQtvefw7OAzakm1chVYXLlhlWaPVtMRqVCg/f64ks0oFIH7LdCqJXV8u+BO2+2ml7SrB4nSOLS3y9ynZeLHQtyihivax6gLsWvLUo0C0zJTGuYAUmyZoB6/Aq5xyZgkYFPzjXftenJ8Oi6W5z4aDMc8neDezOHk/yBQ1IEAjLUigXa9sIchMajArcCBbWI0Ea+sMMpo8cknUNOh99iUDxrWUqgAh5TQFa1TCA1GVEfjBK/QeujuHoxTVWEs4Im92awXOAt6LtC4L9ZAd/g/0W29uKKtCr1iwT0CXcuZVhDjDkwDJrRB65xWzIILZp7SEOSYC+cralvTYDYK0qY1kBeTCIPzF7Vu5BdSkV1zOq/QfFvjC77gS6Fku3dHquDpQ9vx3ZaO6z0U4ZSaxpDgjg6ScCQqkK6F2xPiGQoEm+neiRjtT3ETOoURpU77VzO4x2VuLEJhxcR//Jf++Vxd59MuLJr/ENduu+feQJm+Qv/ZsxqHSSRmegiJTqhC/cjsTxXH5u+AiFZSmGlPUVJJs6fk6vdLpJZ6dGuoAw3cYY8J1Biokvx8/p8sg3j+qbYUWYmFVBFjdxN8uEYHsQDBolKgXsnYjAV8R6m0DmOKgkuhr6gA/VYuqXKBVZyUaNaKd7bCSq8oEyABbIg9JHHs9FDjn6hDBWi3T2JgwNzREgPABP/BlskqvHtIqlydZmIEcOYPrprsJWhgJCaXkk6QoFJqJoYnw6gKLZBXUYkbH3cBgSf8R17uX6ZB3sIECx6+mEDiH2AC9KG/0vkHhghoh9UIE+aOlhggzlhMcRO0XLoBNujQCxpFCRThMrKO2SgAQyK2ueBY8BzGQjAsSpkwI+cEBBUn8Kq2HgVSykWiE0kXyMRJsMgfOVUQpwEXOREwbDhhsCLZbhco8AjnjMGOmHaqGcXsRF5DOAIuMy2we9aZ/hsy/+UFlsEHfhUKIBKLsPy9baNxuiwdX2yFYjoP/VnvngR2WfrV3FpqyYfDMx2m6xAeqG6/A48ON2wzQnwTkVCsALl99B7sni83+W9ww/bE/WEX0/XL52WvvF+86fvC23b/t+SGhD27W5RpQJvp9rcbwwfkaS/R7iJXoePuBgNigvFtWZxrRE8S7vpe7nDXje2xntM+9WyaXtxorFT1OD77wTliLmv0uExsMcijeLCIyb5PUm6ThexjGPCf8qF0/v9goBgLWq5t6AbpV9zj9X9luENtY07cna4H7PNxrcf1gfBifPaYbksRXsgP5/O6ER304eO0r09iHl/Yh/91Vs24hXsAqf1W1DwHjVZvwQO2XKe/VvWsa3fxYKnu+23aUh35c/Hidbm56/tbl3fkYjKMuUWQz4ZfDJ+jxoqFlrPoONV/eE45eUaoLi8XHs37x+WlsVPN9DuElI4/lDbXA/TdNV51pS2LXl+qfDTSvlsOVI+cf6Maj9eG4yJ5zFOTWTZibZ2z9cllLJpzhKIOfxy90/buybvYnCzn11tnwCJHq60OmbOXThzP2MKOT3eftF1l3JanW3ju/Sd93i6tAKIR58w6gccwbsHch+w2+20IKBQQFdh8vUnyPXRKLslhIgOVUUh6dZBYuT63lRGRxgajcI1pkNppktn0uh2c2phpgvVT/Tm9unJk8IusTsgNzdkYp0PgyGYzzpg2bWkrfIJ6kV7xdjNnSXYSv/ndG7NoAhZYEoK7MppfEnJTwPJ5yHE7n2KK14druJ8QLcvNjMi0YjMXoad6PZhOq6iN3dRKycEykfsawlpDg/Dm9AJufAdRK2S2ILUCNF+9BQ8Jm58Xn8Zki7sXcGoGI4pZnQL4EvhS5sVT9FewoXxOSLxQI111HZWEjNwyFkxZeLJZvH1y4/NRj4R5z8BNr4QM8r0OXs2KYSBFlRagvcwZRyo3EfPNufdkuJ2YqsWgJ77qFHwvsUdflNK7VpLbAkbEIrdwdnDLdiyZSvNZroto4FpslOmxO6opSq1MoKeq2hUVTQnVuE3Thv27m82+ArChtczajNx9wVmyQ9YXVi+ndmaAaeZyWT1flzN5cJCQZuJNErFSQCLAqo8mqRkLZet2ZdMqBjxf4iKsT3DHkOo0B2gJGeCdt5MxcwlwR+6ZGcAezUDTF+fxj7xG1wn5lUKk3DFPmsZPXpN1gO0FCxJPVrrPAq7UGCQ+AixJmZdclYnQdBrYhKUq7LXygiWQmBiR8ku+lBGsBVyiBzEM+AlMMrJaRgg3a8BorgUpFlXVHXVKRvIvFD880nIC91EeAzZOiCUPlPBfSdo4p0oM9GlgmTssXquXSaaPzk7JOw4PPmMpCyA3ufNhVmy56H/pD+HXTcdDu/sYJOpBSwQjTQ8+FGqbOEZW1lim7ftJoBhM+oKTIWt7tP6p7fW4hid7upSWpqdNZuHmZ7IBOlgYfNFwXKYQZ3IEr7ysLsNEpRMgbtAs6/zHqDxBTy62oYGVrYOLeR2i+NIek4sGyFML9DEnxki7XlGrnb1StlDKKtF97T9vdFXm+3lteN1Iv48Pru8qfdIX/C+vsJrDFXguAOh7uezgEd21TvgvfvArYUbkBkskMxFiR/V/W/ucW3gcLHbTZZO8IAsDyk3SiEqU9liQhNFPcP7pvXS6BBHrF1go3eUDxByxPw2MyX+59fgYWuE7ki1d9jST/yZIvh98K6lHrH7l1vPD8Edr8yt9hL5DLxoe9DgA8isGADHO6bsDSHacFpU4tdJAwdpb85TpSjt+/n9+Lrvm2vRRemMBAnDPQdcS4fDu51PdrhDf3OjIRWzbfgQbm6XDIPrV7PUn8wyfRwZj/my8X1oyTMwU69+vuA9s5219aXjystmAu1nVzOngXqzDQeq+bmQSAI2Rq3ipfa0syuba+Kj1/Yx8czBqS+pc2gAk1Zj6UNIcR9enztRa7j3tMxtRbHBKkt9baba/DrtA3d74V3rwitoVAEBj+MA96uKC20/EyeLBiwAgRtmFopjg9ulogGpFatVWdsetqG3ZhkXJLagsnleuaIo+jSlcB41Gp2HnNgn2bZR5x91C4jN7LCnFACCmn2RpfpWRTzuX0zL7ixnDRXnzq0U7njCfcGGicYz1Ibs+GorpirOO6xKcHueKhZRV8B7e4RnN7o3pTN+F0mXTS2UCr5JRD0oG/9PC5+SNhDCjgqgd4V37ndtvd2bSikWoQahhad14C4Aeq57TpKRVHi5vWTQl5c0e5Kx7TDMvJDmPS4JA3Of1JLLucMmuPXDyN1ZF5i+vHjiPq5jy5eufUxbA62x+bLegVgxfQT/zbGW/MEs3tIJ0kb3RVpgOf3Ctl3A5D0CEJdBH7bg72facVmYBQMwbiZ1ZHu5atn3/5UXtZZeHw0FqI63ATgtJMCkOwXpCM4dbdM3i9m7GpzwfZTAeDcYn373V2Odj8kPxmP13wFUyTGYVFAyuk+g2UyAlCS3CEk+mHFXJ2fxJ45eTHpeKjTiRsk2Ts3yfwisnPK7Kd5X3LzIC03rv1gSeCfXyalcaDd8f9wjfuNxfJWnlVWpMI7h2CZJPLpvifmDvVaHAWIf0fjYwd+tpA5nyQHcueNyJu0NJL7XSjEtbl5JdukEzLmHjzQtbj7Tg5z64bV76/wYAMf6fxe9c34/g1pgRPhdtTvkPQdGNwee1MW+WfgpuHTcX33rnPX6epQ8AMcX6x4FPfE0Ix5aK2RWSllnc3ofZ5ElBv3dXpUbVGCpMozFNWBmnHjLjEu9uJmC/H+tiPB6Kx6zeEay5yGTWyAqCGyW6mTVSSgjod3Vz0xTp6oAbWMYR5h4AEBPwFQZrpwvpidOXAC8sbUuNwDvWGEv3Pw+ZGTn1EnDVJSTcYUYtz4Tw0AlxUGlTamlQm/xSUIFZm6OfvuTZ1LflwKeqdBTMjkR3/awiJykFPUJuBEb4HfAumgqTdWnq+WSXnyBXt9w//3xuOKdg9bRPPdXoOaiVbGvPH59paikq3yHscieF9FICZpR9m3rw1J2u3VuP9//Hyb61tf41Ju3suUHpH/XhQMK06a0EThx2snhS3eQTZWtX7O07yV29qyn5t0htfd0NFXXFOJRu6Jb2OieC3LxXfBezDy9gR12tSuV2UPlL0DMe0CnPMidUvsdKawsX+swu2w6CC90KYdeWX1TlV+OfLE7b/+qWa2F64dG9h1IDAuDBcxCww6moZd3yPojt0E1BWkZPVCG8f9CqN1xOGyNhZGHo0QLnGZX0udoAVvfuWsJST3evRTa2YGZWoh9RxSYuvYCPHVNIxlsGI92IqNSdaeqp/UOVbX/7f9WZFzdLy2Bd5x19IrJlwTshtucWx+uHkxndDAhxE/1NCVZ1EWV1mQfd1wb+qH75Au+ww0JeQnr4etuEE816LnlmCUKOzm0UKLvnhirbHzC3PQVaqVwIF3tivKOycX6dMnBDudSH6cdqkkg608XDtjd813ZcXvymFt1faJCrWGo8Plsak7HPNnFJBEzVtR7lpPfsxtl/zkn3/VIbgx8PbbKJqgQAF3MF+Z47NPfc3q7/4d6SO21d4p9aNVfBbI+jOxYSEk4jJJNPihM/5qQl/jUX37hSlcYuape0tQ+sbWwPTOqAQCAQ7NN0riAAvfjkLJHkPEoXdiwTXD5np2G+1MTmD0RU/cxVGHNns/6vR50yHGM/4EOSu8KCZreLJAQR7GSb3JwG1TaIlUHCqrqVym0dkozkz6P0suzrCZWPG6nJT2bTi9UT5Hisd23bN37EidmRszLRapp20xw5pTqVPlaxOjmR2bNtF8ZpdF6jobihl3qWeLr9VXYujeHjjVbhjgXBqvMFn6GuVYKfJnxJFbRb7GPlnenshmgzCEObGn/cRDF+jxD3OTsj7s+hGPKtZ+CPYuqAnLHkyXlQP/4MI6YHTv4oTEwq9VdG5tBCiMFRn8/pIuzOtezi5BMa9NypC463+J7JvWbyO1QFsORHLh2++9qZwGLXpMOBe8GOTc7k7eR/Qne3bit7dtsocC49sAaEyzDIY4y7f/PGyg1tcytQ3AsJuSHHE3kLVHk9e8Ki4xejFcnpzh9NVrevAZXtmXYVUNuo6mMdOUZGQQl1SXI+UjN33Ke6ZV4oJXT2Wk55hya/sqMhtrTB8McLNhHXXYtk9j6uZLynreIvY9tPKJAm5cP5zMNf8wBwXkZFW6PYyQ97VBa2FrdWdJ1r1+eEtnLp4vCxUFMCCo4gQGMR+CPv6YpFwkVmzolF4VEvIS9e8iLCXNqEumcjCXAETTKEC7cRATNj8v1gOfH2CYGkqpHvG3IAU2bWxreJzBSJF90QGcrLU73HpUusRiFM7pEm+Ftvk5am3imXbMuI5dWJfghtXS35NRbmhJyDoB5ZICKL+wC7nwcALp6K3/7wAb/pU6DRzUN5xHrI0wNB4yOg1q2T5xAGRFlOe3Gu318TMEQLy4oTpAHdMi/4nNJbyHt08pL8zVwTSive+TGRH1U0fSISsyocNn8NdBfGR/skgE3jJp/psV4tnIAUgtL68jjMJA3Kw3F3Pi3rMqSUp/ycw0lB5kS3vo/QoCj3JptkJroAzmMd+moU+3Xh+Fu184ZSSPaiMvG9RoOYmkmSJW0BUsZdrt2w8ozNOSx0Ppw/LWVaZXo0xN6OCHUUOo3gn06KqC3hFrg12SazLalpseCEwMpNtgDOwY6fKv7KtP+zN7ry+Lnyjyz7L32MSjyeuLK9iV823viVrS3csiplzLCX1r9Hyzr/45Ci/6eIeMzaPy/9GSXn/L8jpuTfwkr1EPCE5W0CrN/gzc/d5ZpvHLE333eP4XHLKBQMxqzvGnPCGT7eYduF3Hh+uItN8Ym6eJ52SBOaBUyvLSorHWpDfc7JMvuSxMBW1+iCMoNFjYY9rQGcq1t7TqcDsulHvt+yv3KdNQiKu6zruLgoBq+HdXfiLBtipLt/qYgh9IdVfI5RUeJ4K047TAuRrW6h7poj+5OoTU23tusj3F33jbEjB+k3AxPN9CCMaXARCZX1E+E4u4TS+ClyXs9hJE3QuwNn3fan1DSvL+WxvcUcTalf3BqzwBj70gBSzu28drH2PFmJH5p5/ZRSFaStnntg53M24Od74hP38m6oJVZ2ienRQWb5qCLvAq8Zc5E+o+VpzXDOMTw2mqLf3q8VUp1DS45WSYvO81F7j1nzKrN1dZ1XjOL7LjnhE2TaW81GWlCh/brZppw0glREJOCjYQ5pRpIxndWsMqindjgqWTVBsYhigsQrItiQm09nKUqppTSmmhkPsSMkEOG/qkClbTnwVJ2xYeIyQ3lnZ78CfkPbeSzUaufBIXLSH8F/PuSCWaPADe7FosyMgkSF97xa4TbPH+QdPCTo89izId2N6JRjyCniAnkdxs/IEI5ng/EbGbhSXspZ+wO8zLHh1sp/tniDr/spbl5kATIMBhcKbBdK777nLECDEMCXnGyQRc7Aq9YFSrdAX5TO9+LnFNRnC5XRv3Wv4zZxLc5vCjTXJeelEDxfd1lZ2Qjd8r6kTjvRlijHGkpqsTcb5c4G2SfwtEGgrUGutsTKtfdMjmwTzwXzs3xFbaTvAHJduOMmhVKMZaKtV9rQhUaX9Y8CpVWV+/y1s1AKekdb5EScWYEZEkX1Vqt/tYovChECigC1iBDHRspopXQOAmFARFWfHd3o+kWSYZLZvDDUV9ROjqHF8CPL3IN1UUiIlmilxUWAXQxefodBnCDts1Fo/IOMkA4eueBm7hLDzx9Lw2ur911rA5MlGKQ9d4UHt9hNKwVHNOZSWDkkhFnDo55TUfEbHWWgkEv3hy1UwZ9U3vg9Q4hLP/WLsNL5KB6RBwLJKe9pEcqEYORgKCD2DtArhnbePWi8nVlW0Ja5L8hcn8x36xn9wiuqu3Mxf1W/Xtwi3WOF2n/XmoIYitaiQlq5gyC/chaguQKBnzDtaE5W4A+s6ZH9Bf0H66EfyQSAYBtecpziegONywXMK3HJRK+B2rgaoX6J6Lk1zoiJezsN2A0Z9cNtDjd12kK3ZvCuWji0W63MayVLgWHY5owi225zvwGdYgA12J2+/6D7qEOcAlDc9qSB4LfmRbVraH6EkEGtNC9PpM1QJmVbWO8Jvm2y4OxS4Nzk7jc2i+F6Ah5GqSfl/upfp1jUGZFVIH9ZWu0ZwEiKckw0Py7tyAU65uZFFYUQHzHaqflkVW4uaMF9B4TQo8fApmNbGbb1Fel2chIvhywF17mRPaKShIHjop97PLtrmGn0dBo7SZuo+L0qRaDaB9iyf2P//Wp+4MWrsdU1BwoV54vzgy6MxVbVaxtGmlvy6DHautHZ5pwRx4Wb1eeq9Q2uYhz6EO17fkrM7Tfib3x02iwFADGJsxc0l/wGo1yqDGOH0xEEV7njSMLlfgAQI3mQwoX0yMLKxoni0CzNaMQaiwqDOWe3JB72H64UrfzvDFXH50TFlXfNUeeHF8OiArZnZ/ZVF01wcVRqAdOHRajP6AUydQ/DuO/Ok5X7gCn0KZqdid8OjQSuyEuKP4SRhjdCbvClSRnQgTxxKFFb+9TRd73It7IiCqNX4i+5RliT/a+TGad7E7iuUbNK0jip8gBx/j7udK9ojZzeM64hI4Q13/Esnsnj0yvrU+nWLhxVlyWm/Kras2/itpp/BIsleTIW8Si1aHapKo80nt75EVyxZdsGQWeztLsKa0t2kWlJ8hwV7yWasAAAYvoOpVuMcFKxNpKES8fHD5eHGwXYuXwlQ6ZkoZdBCYxim5gkDxe4AEEiZyJc4cUeNjG9xUFuoHTruj9aO4BDABvTeqysiOmkmWg8JmHLPOLYt7ive8Py8CG5+aHlVxOjR0Sm1Vl1diAKeGk8ar2NAR7ZoP1O9JatJDzzCudqOzIBeE6RTm2Re3H/Uoov23zQp99RlBhqn6fukgsSEH0Ur0bPt6W4KcpA4N26pL/43usoaP7VeM2V1lPxDvRHA6bwQecHX9Ka03RU7Tzv38SVDh6uwJOTDh7qyl/eZ/NXzmljNhCj8/NiRolxY1qReFB3zFRCdMWqQnmgyiW667vPTc7N4o2MvrIqmsGhZr5hTtsNro0XTrzNb4/PV759CiZfNRUBP4XydQAW8kMVhTsw/7/dFl8+bsbf/OA2UQsAYirbTmxeeZtjXBoq8ni1JsQlvucUQPbvjamBRyz7K5oANEYLgMYMAoAY0yaT00BPFb5DVv8CFPP/6Jb48nEL7uZH14nmlc/0ePxHqw83+2Oc6yvyuDUmxGWVYPn/m+v9s+//rc1ObE2qBtmNHzvWyMZRlsX6XBAmUOt9mKvizHuJQkkHP3F1LKahYrYnDx7Jl4M+gcvr4YbEw3cc+49PQCZ6AEBMDwgit9oldUnKDZChjK0yTvSkoCKFsC2HkcwUUR4xbkjdIXc1o+wmz4CNSbnxqvv318L0JSMUnwzdmzXvwUXu1lTDk5ctBjzN/wXOY78cdcvUROi+Riz40xm5ChJmHJu17/R3HqxvhdSObWqiPWmCectPTcffDcJA5zGOfSbnA7tx0n1712+9Yz4uCaypkJSRsxv3bJr2Iy/RsA/aw2TCJe3VsrYO84i1S/R8BgCIYbDabRR2GcxTrMSa0C9jYwo/zfPSSGIN+MvYmPJPi7wS5Js+4TAZhZsIVjnceDb7NOge64PIrabaPDKZUoT7DpNIurno309ML/UmVCM5Lo1HFYREkNyCMplBhvSgSnwVxjv2XYED5R5E/H0NpflnDpvKaTK5Ic9X6a8oylcyh4qz7F+1ayoh7p832w6OTXl9EdRWrb7pJEZCrSVVV3qWsVxFfPCOepDXUXoHlMf4tVwMDAaVypO60X8DlgdbKzsRubNZj7/5yXOyrLvbbxCKrivdvDtzYFDPipUmakFGPeZy4IJTqvYCgJgBVp+z6jmdbT9j2Ahaf4TpmeTemSG6wcvsrVjn4Rv4QbCRhuWUhWtyZ9OJFUQpYY5QsoJ3H7xF/6CppE8yu2W2CwD07+3fY8WcGf1xILiIWawjUkhmEqWO6BjyMMHqhYb1d6fliB8eqSW2PzLfnrZmRRdrd2iL5wv1H9fXvujB0/4tkQLzy+9JXz1/fa/sOm1Ljc7U7tZKxgrnlqJfR0d9GFvtgUOR5yx5tvfc7e+ReX9lYFLFamB1zXzllsId9rXcffTiipq0kTu5HU+cTMFlY4+1j1iej1/L1i2fCCmxoXEHqUTJW5GIQUjzfS+BPwTkF36AkS0nRGmYo86j9LMjY5B4rVoaQXD+1dzKQniRmMh6om+M60/c1YllcTpLdjZ7JDipqV0R8khPdFdTgztcEBTJ4XvktLoUo6yDIMMcbS85wJO1XGhZ75H2xUQ6XG4eJT3YIgbVZcXVGtA4azlKxRD8VS4tq/hmdxHQewBCtiBfAOPgD9S1ze/djO6E+iZGEptJTElaAW2GOfOs4NmZ1of4Ywu4O3tbl007O0lDK5/oWYjuVtPje3A7ezuqfuZi8420onte+lAyUVJmdNIR0pVzpdybiqClY0sn8XIjk7PBmNax3pK5mg56Jq/KMS0BYjzGc9ORSsNl8ChbKQxWw9o+QKeU4Lrws5VhePKSrv81IyZjK56VklFSozKnb8lVfxrt9fmc56a3nT3nzTisUHKmTT6yyfnZKlwhW64BnSEvK+Y/9tYv/M/Or8RtgdvuFlquxNlQi2ma/BlVuoNjtEKqMMooitaKEoLU74VycBXGI06vQcvIykiLMYNP+gtVt438JbpxOlZryDccTrBVX0lfIKt1zffSfyz0LtpTU17PqqfqqOdxjCravmJivgYwGRk/GjCC+ZUClA+I6ZvDG0EHe1mJhgUmbtU82l95D18Y24au/I72kYVttEHZJLHunnD45nvJlzhBCWMUBjYYNjy3j/gQMuWvuX+3OLOvSicRmPvLfghg4MqC6W0oMC+TMKC82Jy+zuA+djyFOUcVJGLnqWiAgC0uVnVQD10vggeqc2y5lmn+5+g5R164CpyclQbPjJg8KgxgSfSo50452llW2XUWI2vjJkAh/c7vZPPvvCgBa/6m54gJqPHS8x6Sw1rFcfe+B2Pr9AZaoW0RBAwvhmGklrv1vQoKqf9tfEpqf2fNAB4JbFrTuVQtPH2JVWeHKT/eVuV9zReduvmqDu6LKPupjTSTgN6nJX0SAUf6IST+SYDMcYfEbJSRWruUzDrdyn2gRE3r/s66ATISmBF+HejHtgpWivOMNDF5E6fdIwFkBPWczEa7g+Hjh5wqe7krS76w2d43cB92klUyAvEOf64LNmEJcSI1A3fRpelfTkuPVxnEH/obXp11+937uOsDH0sdO2/nJx2YEG3Gjk0U5lNiTIbJ41N1RXnUlJY/8uuv+ZrCyiaHZLrvYDL3FjeUnzmMwlsdDtvflKmRb9w/grneJ38DfXbaNszO9iMc/eM5rGPp29myGVjPON8m7NPlouX/AmT0nKQWAxujNf0lzQX+u9yo6/zBmqyws606/w22NVE8S0u/8leeLYdL1s8//XDI00mCiu4XRo9ruy8vdWH8CjNU08Kb0yMW7Os4Ovp1fNOWqbCQEE7Eg7fRLNdj7fbEA9NRR0WvaZGSPalT0ukOMkLED+WtyKpMWwcqMEZKIaO9j9qW2tfcmLi0jzj+H4YbK6jD1coUeJRKxMfBuKTYXbWmG1KNFvXYMhHHM962ROU0zOHh3VP2aCLLdJAgDrUoZwS3a+aQqyZxOr9TWAA2OyBuIp1N3RhXZfmucLOgFonPPL1K7rYq5+Ihw2xYmGymcW5hgDYl85ZvS4ZVa8RMEgeXEsPOhoVOEUhkx0XgFtuWFtdm90cz1MjpJot61egugepi91aekZ6sJRJ3bYZvSDbaabk+zbQ37ZuM+gF9S/EgWzxb8UFe/qtX2wu0iifPoSXtQJXULRbqmBx5G8T+NbjiCXE8o7t+kNYWc5TKJaplIgkguHLmJLrmRGWBZGDYiW9ly5WrTzeytOVb73oSxsAGBQDtpVjDQaI4NFq8QEzebe51ji6BnPjnw9+C3gXtgB/vvEgKetFoH3PJ1cDyidbCkiaF6Hm2+zzw4fUkP99RZ5/vpPzMlGlDReNp66+oefxKGoFahaA0Fpt6ycb8nA7p8PITDTf+HS2VCpYU39Up1Tnpp/iF97xU+Fvt7S9oMOOLKUX5Vl85jYY/ye37/uG5ddGHlxmHk/ua98lXjEclHS++7g1rurpWQDdgk6fMTw9Pyuqbz3pQ00nPZuggYERJyAQy9huN6Rw6aduezUmZt2eHrTvOpkR+h8ClI4ow4ZjW8clnubKuVOoc8x/CTPbJ4/1THNkcd/plHPUy+ZbS5V0Z/FbPbOv+BPEuBmL+bGPQdkRIm4Pt5nlXfKuxaN/ArLOQV2dC+Jy3OZHxvYlbtZOhfgexsfAbf+kYau3PHJmk2XkAu0z9g2MCpyGfOMulfsca5KSZ05CNlqYx0txOJ71YC5cMaoRAJyFQ223unkXO1TYHeLBez4uFUItQN00/ZQ0q5X+l18SLhFXAIdToQQyyw8x/mhOp2a+yYXGwAwLth0AJUkm/cjpyWYCnHwvsGPCdlQKggRKTlhcdqvEEnSnGBsxbs2W1X3RMNzQvCx1YNrIG0wxgtm8pL3WLXaWK645c7eKt/392x79dTWuuvZxZZrU5A4/eNlujbeNVGJER4weenKaspVGMaPLc2GzmhIo3K0HqwkLQ0HMnlEIncWmFr82FNzEV7ZeM03o3OZ4dEcC0JDlv+Kr8IKyKIBHUEJ0/4J8UFzmn05n0Ck/MS9RLBuQQTJYWNQ4Nrj72vpxZS/sASRzaekmMQyGQcX+yaHLuSFC3SutX2I78HUihUNFSChwzI8ppWGyrygOkVc1UF7DFk2cBFOsRZ2BOYHcAYiMzRTRZkxxJAJToQttRX7TSw57yTh1y3j5ou7cLAmWIQ8mXZCeCbaax5aLzCrlGzjeUNXjfuX37tvOL1vFJz3hv3OJwX9yxXR0WeB8n6V1/G/Xz5ey8E3kVQhKvkWlk7YpGRTGVjIQnCK3hODq2NktUrsvwJFtk6FNzqUXVw/esOyf23SgJzHwKbNUIa+oPF++y3dE0SvL1ZbwLtZlmQ4mv81qDMN6G2CzFiI24hQQv8s6DjwVvF0JBNxEJLP2ZzL172zs4/zak7W3GpkdJYom112qwtyGMnm317inMT3St215vN96oGpv2vjUpJ4oI8TAJh4bFvnwiiJRP2h4VFXSKu1GqWxH+Ece2gGtROANEs41A4ZwbHYyTBU5WF9ZFlDNkQxOqHXf4eH1jXd14d32XAWFMr08zIPLGleuVDIgERBox6AsmpZm2l+eRpaUW96sF/1TfjoOHl7ZFf3v12uTPRxE+SkbR+2pBllQMIsqntj3l++tXWt982jSwjOh5KsSCdPK7R+anLCI/BPnXfNegYR5dVBn7QcGSfvr42HjGKTkEAmFMX+2DZ49NtFY2M8jh4nQJbWsKx54S6gYBKejzpfrL18sZVEXkRxzkPaSxnLv8BZbgbZ+/5u+e2NOoqrB8CQNiMD9mDdJ8VyVzAelL+7Z9xp07U1BbMn3IRr3ZN/HbtaXHEW1ZjXqtPsZxAeJKvvm+dXz2tK/vJeQapBUit2V/0ba2R9ZZXq9M9EP7UqufsbY1EzJnHiC7Q+p+5yuvl90qdagLoShkVYMKRFSQL9/7yrP2qzdOhhdnqnd4BC168EfGJL90DCg57kCSSnTASY4a4Q7tTdllheSarI7yUhUm6hyELLb8gjqUntd/wjjnjBCb0DZIJ5mN3A6S6YdaF3omOotLjVwUOAmqXELaJDLzSZAGRevKvfPgrsdFT7knyhl5do2RSAg9PzX5lKHLzNPiJNtpU8yDzsE+f5f5luPy92RUU8DJFIsktrZeNtLaxYBz2p+iX3wFL1vzrHsi4bHMQlLCGQPzGBfYjZGLLO2GnzMZuanjdfSnbGT6Tiekc6qY637xr77IKOqVzRmLR7EllMezG06XEzV/N9W5XGk4ap7LhzDoFx5Xnxd/mvYswSjIVueLUe5Cu+1OrRz3ZOt9HAdP6ZVK5O6OcJU9CJF31XA2QCCW2fZ+IqUr3iHxgUuw5euTmAPWlgZ85uRD0y5od39x/z7qfPNkk0NtUJo8s3wwO95FEDKVx4O7d2sU28DrQpqgeLkWGAU0tnyPQx2piAK8FtMZlZIZftBD9TPd0PLIcw6eJ4F3eiB1yqOQC6e4kXp6zlhfTdrUaJ+YIMSnoy/RHxzmO//zR8rWugAV0pYwyhhrr7EsHp1IH/22RlKGHlpyQ1P5IXr/75GZTpkfnM7uoce3b1Rtdm5SOzdI6G9Rs/HmvvPLebuRmee9b0eWXUZPm1csr9SvWg5cbm5aebkKRi+naTBQQQSVa/PW3f7tFe6fVdhbUsCYTuVC4WHHLv4WK2WGNI0prp/xYPXF5s+GDm6dJ9eE5reetKq2jeJKuHBAQtEhNS0E+Vj4FDd+7mn+2UpOaZ00WxaEdw7Qjv1X6qLHV/6va9Q0hWPb2gy+5WQZ/ohgxBa2thp8zc00+h4endXnnjnq15gd0GVt8ww3zBnYYCkz2cfdzmve3frBEXF59572igM74fLeju5yrN07t4tvO15r3T/p62eF/OquTuvCDfZG7630AaLOv4362YT2WLV7cUyVNWc/704ub0N6GJ6vfF/pQroGzV5mIg/Z/KT73fpPy9f6y1o1WmtebxlvGLFTrY0bXYLPlYqV/hQpdU9pctXt5mf3zGh0Twf/VKe15vP2xhvYxdBMbRvdXS+92608GUPl9DI/4SwLVVGTLpHXGgeBKulCysdwERGpxf2jGX4jLfRie8Hg/KOFflE2QpHYPuN5es6hvFfMissVlvG6n2cCdSVYe9TeL/H/eU7/9ESSzYxeWkIFh+USm2O+urFdPU8WlNJ1h41YsAntjc6yps3NRSk1t+LRYHQ2MoOIjWjQtGOFUQYz09D8xBR4JtaHIYqkN9nKBqXCKaeqnOlECcq/hqF6FC1DVGlazM1zz2ReeTc0Gwn7LbKELA5tLc8jj4FJaZZKG7p6RWF/ygUSM52h3nsurvKQ33fZNq5LOLHnhWDbsQ23Va/korLKdud2lx/K/6yiGavAhEM1vwtzzhW85y153EPVMHegmDW3MduoeVRdORmQ5uYIVOhea6/dgVLmMxttnuGONZMCmRmc9QaJtwF2PvfctLblpCi3f3svLW27rDxLwsluUkM5VRGnI3Jfttws0vQvFHxsuxl5HbMRbDaFndtiG8npSqbmgovZmul5E9k3b3l5j8JY8n3lyTGYbyKhriKmwNwcZxuC0/3RjIoTN8EfxSQBjInIzgWu/p/sLpb3IIwF3IX5qwoLBJ6aLDqhqrk6XxzMMikIxibSNyewGyoUktKbm8ZmM8181K/SxHB35Z0ac3z4BBD54oFEBZ7iaZTsLqnRnO/MmJ+JfuWqqpqqTXzvdj/R3W6imrrCbgISGFOPpyDndxu33zPLGJl59rmUb301ARRxKEnTaqZZIlwjssPWsqNZx5GpI/e7Vu+zBbGucFvc/HGUoxvr3euP2GBjOrKFsPY7Rf6fc6Hvx/bW3gh8FhWXvcM9Ht2Os28GI5D0YlL8sslG2OnCUjr7lKIA4HkMA2EZTN/3NaA3uODm/0cf/VvuKkg7ey+ya+SOJ12ck04gDKGjuyZrqCWtqZN7dC3sLsI/fluvj7TD7Qvc46HdmZWtO/Rifw0oicqAAYO3FYth+8mueG1VerWLN7I5cjrWpKWqKWi/c1gb0f+sofqs/58K2CBQ//Kn2n+1LUr9MtiQjD+HDt9Xd3XL62+z/Jid4fB3UmwoRZoYJcAQKgjCFaBiLAhh26vM16fY7YwHpiGP897QouSiDlFwNiq3gnFdZgN92RohYURLbMAMSiI/+6oNufj3RNNd8aY7Krd1vgDVKNtzJ38pslKYp6gXNX3O395caGmIKeszhKgOxLorE5N1PAiIHdXFe6Nf0gtVI6tgYQ2ixsxG6c1HZeLKe3Uh31xqxdlD5b2OruHoStL+NXckxvM0d71kAx/QTE+eBLEmREGo3NPUzDd1UTJaI5HZp1deFGbnG8I/0SbYCyGwDTGbJiI7EWUHaLcH0jMrN9uXVYWOVELaGe3WY/vKl/GmNmo6dBSWuhWfFp+V/wwbyWJ0s0RLvc9oU8Up8qiw1XNF+b/Nw84Yp9z/JiTIKP5yGGS+3atsbrzLltXNcu5C4gyyfEZSPpGwbcBqXaLiojxrit3+ipeTEXCYQKQ1fpCn16JfYzIcQFvCmPmUxO9dxzp2rCuHtCxeQQ3qjJdXuVYo0dYdwxmKniIYCUwlOWpR3cHYwOSRKoWaigfEoUOL2nlImuzqePkyoBXmStJuOywb6XuOu02iYbgXN4Rr+fFKXHN4ff7ufLuo8kj4DjcevqFjTy4T7IWhfjswOuEfaKRrsv/TP07c4d1Njuobj/DJXEZWsvJXpiAAvZjCm62IKeLGtxn6syOILtPuZGi0IyNupfrI4tgw9w7TPVTWlaNUDuxzLPMtxSzuXAR1bBwBTjxcyKLlhGOjqPLwnU6Fsxc+iEwHnq9WfNrvmb9gNUAHurmaI858sR/oiSpV5h3+a52zyQf37I0n568YaleOT7L1upLz7CJRhaA9hbra5trhyzKRfue42yQboGPVERHkYhPXycbZFUHAPYKxHrEhRvfqLzsQYm/mddRBiPO9e2W3F9I7e2W2b8qaRfbx7kwiM3N79Vqhjrdp47ce9Fb3/WZ+DG2tpVUHpmUITv2in1ZCLz+ZyDOnD6akgd8bnZezsLs1i1BQ/N1Dw2FGyKyeGv6mCmnNrX/v1pK717ren5QKARFsto/Zoo41sv85n7G7vsuSUTVTbeICvKoekuQV4brKST5MqWBgtm9maNZ20UdOHmh1jby89CoR1CwKrROD6oz+/Ge36Sm2XHBMPDqccFcfky7nqoErNi5UOnbYOZ8kkrM0Nszo902Ql3jVw03NwyXi0G4xKLjtLi8v25nPXCHIVU9XrybfbTTSUoc6uM7yAHdXPibh0IBh61BMopWqqZIs99mA8cU9MmLYVVC/RU/HJnPgDpgmw2TSoGCBWslu8x2FNPZRbVmtokqy3FslP+CuNSsSdKpfrAiTgIHLPaYcp2MCBLNbWjRaw7bWblXFNWKvPJ8rJ1f8kfgjRiVXzK8doMB3MVP/cP9m2wK/hB+Y1oLWdxz/2Rff/7DvcaRBErNnGgqP1qsnuji5AiX9uzir6+8cN/VFAHJzee49Cr6ayz64Rw3vZ561Y9J2bCIW0P4MwnMrZ74J5psAm180t/9XOFvEm2HQ0Er+kI1p2XRo4pT/+qVAJPspgScT8Xt0Rl5mUiPve4XO/2b1Zyj6uok7kZiYwLpyNHPM5aJATXrgZcd15UEkoRvXfSPOtMHFdnfaJ+LIFFE4n++ZjrfzacH2eq95CT9EJ2VE/ktLzIsw60+0erztzCL8VHP1V8TBULFKwaY7mdnPKksQhyayGuJ6Eds7sAUDY6I6ARwv+iYTscLd7u0T5IqSpcjlpc3EuYiloKqbvhfmfZcDqwDzY3FQ3wWG9aEFaW3Myk29Eb0OVv4PyKuPRJxfm5T5kK/zV97Qp5S9onrrZdsawyfKuvdGqlPXPylfACu0TEmGOC+du9DmcAq1eudErzA5UxaUXlmtX0XT8lxfQ7lOkr9yoSI7RtjYv0fArxGL1FkVECBZhN2oocn8yYMIl1eZod/n6cwqrqS0Gh7cLh4cwXyudKxmbIE4Itg6MfYUAmb17x9BSb6EFbeVSE1chtWGxED5CeSYhB4rGz9PW9dzOi8Wr72WI169ws2/1e2f4tjS4ijDg/WN6LORsblo6b7AQbEWm705+JyQ0ofRB3iFk0Uadne7HdvanL2MmCpKHdQ315y8HGLY1hL6sksYgH7csXug2uqtUh8w7jCXtF7vYEY714fnmKt7qjp1ue9RCR/VeqBi4HdKATarEsXFQpf81v0lxgd0+QKL7dK3V3oMEMzGdXFWoUfZ5c/vR4wnI1E8BR5aFkIUqlNx0e9CoYKgNp1hovvl6uLY15slVNoWIfYnUhr/WH+Be1A+kl/OFmdXbsdA6b0Y47dVfdWLBELV1Bg2fhAXAo15/GQUl8wRiQbzWkr2oy2g6UXU+N9NxxrXrI2mvPL28lrHQjdthUCirz5lmKR8rOGA4uXiw2dl7CtambzUSn7+iST43UWR+HvXZCQrf+XfTintoGlD1AFmI1sJQz++q8mcYBRE6OU00G5MGNenQ+16lGRbK7GUQ8nvZW9PpHUSq0KkIAEZuR42f+1a1iWouIRRxUlUCJLqiAjaew6+2fU1JBaI558UcYHz+71MacDrUNHlqUra8vUQwft7enCuXKskE3AsQEkwULKZBZ+rwCHfCiqmF4L0/MClQc49P0Q9atLB6b+wF9R70aJ3Z2Opop6gFgVzmg7VhuOk6Kd6BFcbrOPJrn6DE2k/p4eeHdu7Q71WRDwwfjxfgreEWddCK3TwLqoVXoqvuA5tQcu3fZdWsZgS3bFr25Trum40U0b0gRTZPU7jW/bkpNvQVtQQFKEIOyrE2pgHFT3lkouk7cec03VKZCsJEdPKtvVdIUpVvaboD4Hqjx4NFFIFJZ9RvkBrCUsBms1wMpp+8656c6JRGpWnosKo0KKgouCT9r35jM16Mboum1cIubgUgyPkMPLKRy7ao4jnIOSuXPtIXEZSR7xPZnXlYJ1pR/kjp8uvoLl9TB8LBycQD/rjOoSdavFXdQppIKL8U67gIvsez1poSeyzOyDXgsl8/PatRgPlQljcbCw6iVf0l0eYiG8SCvc0BMWVtnHqIYEhvRY0BVM7PNaIpBiFgToBNVyeB1GH1EbtxPKX27pz3x1lgsKSwovXsmNYKf/4rSPVF2sBLzvtla/gwj+/zkr+Yz6s+cImcaW4CLey3epwejt5FR28xE3h+XYXU+xkGBo4w7lfNT2u9yKqb3tjaXo6JcfWSdirCOk+cs4TgU7ydS8QAzyrJ75+EGOcudHb/5CxFldYKCd3kMTLs7FulmIj0ppo6K56Xr7rHu+2UnttchpdaY8Etv8+qjH3Co3cjuy4DHC9qr3WAOZdDz7pKjBLkNjU3vyFIZB3d/m+6ck0RxeN4+jxgocGjUJOC14ek1VfXh3Vr0MMz10o+AzvU5/36MwozLFQGoQ0pdqlY8ALWK3XJlFTr0jBBZb6hT3we8HiBsG6Wu45t/RF1cR2clZZ8yh/k5SJ0jckMMV/8mUNN92+2mCfKKytqsgeM5/51HBGSi5gKDg+6BjX0K08j60mGcmJcLn7pOe/GUJguv6sR3rylSY/uyH8pGx8lLuWNk1xiGHkZ5bdZSxg/aYFEYnrEWl+rfxONvbY7jMAoGUWBAFoXUcA6URqBtL1Nth6Emsh7ux2gcdBCbdBr9bgnznQZAC6wXsfFCQOdcHaCuduQVmhaPkYYCGI1797cvtezVKZRwXolWOeMGlGI2z0Pj7hr8KCtN/nApFWINXmWjJVLz8CKegWrB4Vn5A+9iL+wgEbzWfwxHnXzuCVbiq33itWWrUCXTzKaA338zObsJWc/OGRRjNyiTQsV0CA3k8IYbuzPYZMDCr8RPHBm/NM+SSfJlVtSwu934lcdmdNrB90ieR1dTe27wgTx72ZzEyPDIrQZV7+4LIaaTZPKyypDxJVOuDNYSZRk9Ch7jYNCt4bS2BZS4WFJ9USUYYU5JlwEc1u7P9MwEn6sAtvm1jq1hGXe+CFaZ7b97LrgvYTLhdSg6IGagTzVx/VqU7IRSdleXM7YU18S6RH9mCcW0JWiV/mQIsMeyZXBQcZG3ZGzDnqvN4jRzDeFTC3rKmmwK4gmorPC359Sd+MyFmGKidlBm+kKSq/JWVRANP2I6vpiNLkDOnwaJTQi+ovHeBxj06kKO8t4Evbbna7oJ+vekCGV64HCRqoXcXZv3M17iyaHF4pNv57YfAZy7b6qVuOqK79ACUweAjDlSRp/AnObu5jDOmo3rhDUZJZxBFXtKLV/iChJ1N7Nyv9ZZML3nmPn6qI/LzSSdlA+9ohtlATOyArfipd981bW0IAD+3ObPAciBx/fs8zja3JFBy4y3N46ElL9MvZzNr1/TxPqwazL+WDuAs4spYbBvpzV3JBoDyunCXE2i+huExrK+5ktkDLhlqgOPpp0esq7gpKtcEuUVhbWZFp7mX9HKpwIOu+5nz2abrurCM/8UpTgstNibQSACRt0wZ1OmHVGZGE5du40yIMa2xdpQFzYPa2At4yPvYRuA16dZjbuVmGvSs/KIY94F+J6dhUAXF3fCDnaPWA7jvRZ1mPS33cMu17RbuqBkCg+5wbUwf8j0KgJ0JHxt1zBL24OPIUJ1JYHqF37Abn2kpC74o5FuS7OL52LvIg2Hnb4GdoNGRekQtox94FsvkCz7ZzBYJCgH2wO1tbhpmocUsz+x7Pxlc6m2n5V9WYfzRtxXUuCDa1yiYd7HlJ31yQlKmn+ueXYmZY6+/j3er/jqv9U1J9PyPXXO+j0lUvDUu7+sYlyFdjf3dP9WiTF7Gdjrb6lVF/SandN7fDRdncAW4Tg40GXvwXoIEHmmvkFCQ1+je8tpabBkabu6ir/lb1Z7q6ak5s1BNVdfrP2CB//iejrfutmOvPL8XMsVZBKNWoe7qa+vCRWgr3hU6N/rxmr7L6fhHb5ehUeQVtYD8imKMQgalx0SE4T5m3Op7LkU/N78NHuI47hx2zLkohGrX4Rr3l9sq3Uj9LVHyHXjBs8lgGeW0EADEv3RcCcHasFpUYX6lNe4qyIeqKO+FzF9JOVFTfTzZl1/BOqCqbCqo/+vzls7K+dfb59iV/OeGXDbX9pFliP742TmZrMcPskb5pVSKW+FBfzUw+BgB6Se/5kkcQyWNHiUVpKohgQrXLWWORI//ZzDfNLdjO84eIm7hqaHm7uKxDvXe7QyIJeqgJP/fKzYQB/Ls53z+590VqBwUIVIYh1skWWrNYplGwfoL4ktgfNPSwye9xfOz7D4VASiYRUnPjc/tQwnadaWFk4N1SPO7iXSgqCYgKum5sDj3U37pUKB/mfcPsq02e4ih4u2RMWq/vM8ODD/sl7XuqPRIFWdApgOxc1oEWYZ89ixUIX8Y9M3ycUHD/t9KnxTkmW80fL+ZfcGagRWPoE5m8CzBHtLCs3sR7GbPUQRAjOAclzlgYx/6rnFSUvoptPByUvbtQht3Xv/TmU/czgmAJjHBz4htLeJ1WHdrQ0JKkbiBiaCVituKCPzSQhm087qOekPIorRXCVDsHYMllkSnPaDxxL7rP8IMbQ6bLSCBswfP6Z6vyK1vjKw0uzY74MihVwykeMRakt6ARKZlqIee8FQHx4f+2leJh+y0AO4NKT/yerivCT0O7XIs1DZ5jPFqkhh/FeaIZdx+vExOubST0Vp9xY9JzFJW1e9qr25tjsXU6BDFZ4r4fN4gI/+TFbA2rMtHL4vXTe5WBv3Xkc0JV3rJUc3KAnvRwIdG4cKnDHXLtWSrzx/H0OsVYfpxg/Uv6g4qC/Gst3UX5FlcF6tWlqdeKyep5EGO0p6rKVIxu1WmayNGVLN8ONg3cDSncq60b3p0ZXwDVDpTIaG2Vgv4wpPJ4auX4QKF9anobyttXBpfppbn1FWWlDRWBqzw+Pvnz5IIQHqihJD+5r7W0jF6mIKud/P2xOuvmNf/lOaGCWS25nBMwwOPwA1DrGYvJ9NySpVzVOWIl9vJKyMDlxkJKiqRblsRZ+zmsm8Cv0ciq3AphbAVfblA5L5Ms482r17OiIpBWtHjkkAg+sGiOgVYVKjcmE7Wp7nH52Qan4JBI+4ZThq/OGQNsTh98RsracLUe+eOIyllNybL4J23XH9Mr8OgBfvrZ9gzwQmD5f/T1qXBN5pbINhfAjk+Zbxamn9MydeggiBPQYYlzlsaJ/6lzijIL6Y3HvNRTKkJgbUnfr9fWstTOfWqEvpQf+0hZRLmbMFbRVlogNpFThYVitupyRGwQNb1pyUc8IiwdmIp2b+Lrym5KKjp4I9JU+Y0rNT03C03qSXHvG6ZlN4+ktec5t1gVjxhLJHUFBmEDCpkizOHSj9DIyFso/aWCZYUGgHxAmSd+ufuK8NPwZZc4VPJOiHvLxWrvPHfs0t2jW0WJlzfju5um3Oh0tSoJ0432a5looTdVZRalpLu74urMb371oQdDGvyRN+gwCa0KPEmxfwNyqgaKEyQ1cL2pREprrRT2h79w2oqVL66V/vSpIsubZAPEt2fM1cy3RamvFbyfMHItcaVQdTq72XhmJXzgAKWIipV0MRJE604CTpUWE7p0oIXpA98VZ62/0dhwq/FZGyiAXFCGoM3rfKUbH1zCjHPt7S6Et6NFaKRFKhxhQUEiUBQEHJWaJGA9j1AqYjqlkrV7r0pOchJye3ffgz7JchHUkGk6YaTdS6VmIsSR9EziULuHWoX/szlhaNjLwJFR0rgqbS5bR6Nw1BdoRzNhREXA9vjGwMvxh1PgWQNZ1WiVQzlYM5W1WISlR0bN62n4gc8H0Sq69+QSk8Nyeyo6s9jwFFOGLZoXbZKaPqMzs6dgx17U19GgBLtUKFgTFUGS2Dsjk/DASPdKZE5wqC2HgBpS+y9fOBinM+lUWXaLfnE/Zpzi7qH3xhjjkGUPE+dKalgDMVMedDZF12/IrfWmOP4aLf+RO9mqDuuXpm7SfDWc9/s/nQDR/o0L1WGRaejCcIKInMrIaUTZT83MlbqnDg146lAGr6gHfP6+bCeigEtMxUSjTKBfj+TwkU9fPqZi47KDkBovEWz0frRnelpKxq4C83BHlBDFo9McThsj0WmTssrmYczW1MC0kHQHVnGgpwmIQsaGRBsqJ4fJHIzBOO48SxR7M0a96HrNDigGZwMJymG5OpWr6IA5Ds1V5F77NQTERrxiMzx4a+nZZlx4LMwmEgUK8WK831yT83AvAL0jLOS/E4OVWYQueW5pROh/nRMaUUT7EHrA2Nh/IKtGRBiXsa2rmbY/WLU3J4Lz60Ad4lsdJM4/TuvIYsPRYpunCoEG9y1cQrDGGC4fkCnGqtGibG7B+HHQxXeIjETUIOebiijAflWatvaLvmPl6QnrjTVKnM/HVHZMgF1UFHH2AGsadlfqQQwo3o4CDYehwC+MLh8S5V6FVAcjbY7Gxsn6b3krcQZFL5XcEQ3fcy6VObxdgzLqV4FDj6UY80hCuSlVWTOdtasI90rf1qUEs4ZcQrL7AH5itrlHRTV2T9UvGCN/hRo3vcB/NWYpV5Ui7vco+0E2zsoD1ldoyzb/jxP9YsyLuU7aFl07pjWlMnMwpl/RV5Lq+LW7x7IO40dFERuKc6n83Z5Rjg0QHbAw3FWfnp5nrTky9Q079nQica54vLZ97ozVKNEUfS5jrVBUDg+KLmWBmp7TpJxOMav3+DALkAScyP8VDKUD1uwSY9rwbPQ82lOclpKxs2BguB0mUqnzVzUPpWYse+pmfj0VCpZP9azOTAqNRCTKMQeTJZtScQAMHopBMmgoCW2AVYnPxCorW2o0RRv6f4T0IqZaD2LUeH5fp22uk6+AbncFKLhEBUZufBv4Xku+yvYQKAEk7E/mrI9zIYCKN+/bnljtVwkAHnhZ9yIsyFOmMB3rKwoLdiloYHdVMP+scAQA9FlMXgvMijW85GyoZIhI6kQug5kUrf4v9ZIfKr8icCbN776NL9o6N5HNoCZBjPzlcQ5jJMV8xRhFSiag7SG3Su2U68Q2tMz4KLCF4U2KcVtg7q3V9YRQaX0MrhiXqy7vQ1hD9hfWz6ovANzGFKj/kvEVwDWvNJ0CJPcxjv++ucNUQVxY7HbZlYnW/KuKTv2RTsERaUMAV77GmgHY5QWmTzayCHp/tC3o9XAHsZ1p+mh31LFUxmAC6r9tLK/xFIWKSlOqKGlKNY2qUDvHcg0moQmurzILzXm/38LVhcKkVY7JJKf9xqoloaSbmUUuz+fm0VM1XOIOppxUpxFraGQxTtCWoSIPEZJpRqFAfVsKCWlMoNGRKBojgXMo5G1RJdBdTMfUplHpFGEqMVOCC3GgSGeLR2WdGIgAlyEBeXMl+BhHIHEab3gZiQCqXqyKQMrBEjKlJHsSZeBcnMn0O2Ti64oD9JsJV/rtTOxTALScrjIb++LVDdgmIttJiiVKqCsOcG0lkBWzTonPkBBJCAxl0ESwF97gmhTf8Q/2ImI5MiwhQ4qk+3je7Gw2ABX/mwiGuJkVTxoHdEjTzpaMyrqxUcLIlAtT9CgqPSGRRkfF0xiJCVRGHwrFoMfHg+z4eAbDhGh5RIJNwjvCVb7GeWJkDX7CwqWgbGjREK+1zpHK/QU2Vj3gXlfaR2dl19UaAChVXUv2k/bonSstOI97P5oNut5cMknSohowIe9/N+l1vrllVoChY1ZbcNu9rpmdMIA5yxkAmGyyAHO/a2IAi1z6AY8KGzArkfdNTjcAzd8z6gEmm98AY1kzAzC7AlAMVPyIYtBRSAYDFU9lIFFUev3jNVsHz65pGmQDS71ItX5fCK8ZgehNfriqiLll/anI4xOzmCxoHpuagWaToHLKdFG1GqGGSs4g3Cp7cuzzUbXlRM2aNjYzE8Mhw6SkRveIiuGzDVLpFhJU9zq70fH8+RJdXdLidabQpX6kvMq83fxhHaNeWWElP8Zrf+54lHXgMXcxlyg3pRVTm6a6LauoXBJJu5lZqcY8bj6TrOGRkqyEh3I7OzSoas/FnUm1+wfAWnbaDla1xk026j+fa5G/pCuY4QQHAkg8DXtbhez7ZQVs8aZEc8cvHVZdZj1wyWpuOCem4++OM9t/Ws75XS3IbhEe5LL/9OrcykXLeG4cs0817k1aBm9aDWHmySOz2wLK9qM3pZDjf/UGCDN2dv4cHH/Uu1RLDyLP/Baxp0eYkS+bOaT5BvaJjEg48tYpv0pvnx3fcJRdQi6qrK2ZUuaDJWaGj9nWZEVpu8xg1+zQkvA6UOqd1qw7Cy9qtav0D1/bUKvmAhJtK7WtZ+GJW/5MOPL3WkYNb6l1WwPFgpQ2O9kRxqJXCfLq4mtpnx6bARyQoA/TbJRdGUcxa8ptBKoNUCWV/e0QHJViQXKEVbBisHWZ9WRbydJXwPgMCYEcy3zJhAwZybSVxf0tdKMVTiLFk8XSNVhARaaEjJdI1Bn3DnI0dR6M09+03oGP5/Z/BwR8LrHm5jL6j2ROcUcPsy8wuVPGCs71KkqVtHsUImLVVRf5xURfEDvm9AERZLmlYX+UceCNQdG7IMY43bAU7JdrWsU87kc8BsK970wBoV7bONEIDTQGB1uG5NR/anjW8AhxXxQDWHKbBag5LqF+WSLzVEPjt8G07Uc3PKH7vfcxladxHRzWTGGqNY4Ibr8BmFJ40lJHXXMD+sGX/9p1tsl5y24+pP4G8Sn2QzPbcQt/G2zTh7f+2GJiYfn50czsK5jsmsXPj9KrTq/qN1ItLD7Jw8/LDwB5l4DKS/tf9kCLYccaggbVjbawepFZHedn+JfWD2zxBbYYUQxaPJJBH4CmABlPo9W9WLN18MyapsGosFJjPFodj6J6qLSBJ5wAgsUqMRZlouF5aWVKIS5XMHqhLa24TZFDt9wdW+bMAPOJ76zpwJ+pupx0yyCRDrOQAVxSLgB746RuhwAWobwAACxAMcm3DSau6bsPLA0a1ljThMylCjPXPJyK1viPENoQ3Ax4EkMyDFuprEIwXBLThZAjtKcdFkp0XlHZrmDOVVWpZOA2ESsrK+fQwQeDEl929M0QvUv49boSb141F2NdMTeLeC66gnhfqX8Y97KsMO8yN3IbvaH6PqTC0u9xTcqQmOHTGPUa85qqKNLXIa+xZof4NcWePprqvDE83BKurhThvB6Vma91v0o3L1PCGjARP6MF/lRjvt31SmbeD4PREiyc8iLgD+V0nPcjlfmYbU01TxPbbIddSGodVXDxB/yUbz7T+YpunkMEruSfjcX5tXpHOucNZA347eiBXvE8PK1AQGwAbNtbvI/Frv/MEvuqHD5K5RzIApGN8ZeqDfsZJREc5yLc+8+G5PhYqrwhzBJqO/LlFoMen935w0y/ULXZGE8C8SivfqtYD5d73cG8IYObU1M6RRl+WD5dLxjG4UMlnRrx+clsFPTDvOQyv5iRP5n8TBBz1Wy1uffri6v6NwGP9SVYyyuzYfebK2ZptWX8bEYEtWeYD5svzAD2LsyGarRlW6bAm/vfQ2FhkFXc/wLv5z9y05w80/7v97/g9U/bOP88/7pok9z8/gOvDjzmm7A3rm93E2tbWqK2dTVqs1LWZThsXV/D2OjdRtAM65sdp9dlyrDaJv0UTNC6ocouCjAQnd2UtqFKUL85OvHMP68JvlLGpVYBy1qLKgMQmFoKeyy8EGYOMvv570iHMAjCh5uXhI8lKdQUZFpTEq8H5GhTr6eMGhyYSddyRVYVN/UBs02vXCv5L18iGLgrbMxdcEzxsckDLrDBD0MDz+DpRiKFWGzfg0OrNuLDpK0xrWvp6DDJRnxozea8B8ppuI0sWmOtqss/3HqovtBaVa0hJalrppR5Y4mS8DG7ZmVJhWOpc061bY1DZ4aeUp+0uKKncXlbdUNYS5b3bI0PQwFcEr1Wex0X2nId4OwfiYTYtsg/Epci9n78FHlYjQZAc02JY91aPEhaG9Pa2lYTDZKsxTt3rx1xFHbDv4NQw9mX2qjF3ThDz/64pn6w60DK8O827VmXL7f7/c6eMnwg6KoOnc5NRou5aJ/7RXOiRpaW6Pe5mpYimvsnWcFu8gALch7RtoqaXCEBg3R0mU/B8OdxeR4pmhW1sLWCvSSWIs8rfGVCNvGH0GIe+pj32ZDFcjUytKC9RMRjRH7h3SxZmUkQF4oz7UgRAMf3yxWOGjKpkn0piBgPlrtHiZFOVUpnD7vd5t0Tgs6ylFl2S7gTFQgPzaIpc99EgqRYKrSE6nYr0OI6Tjx7uKynLJrSFOGiWYKJW7iVHPffeFti4xHfjbd0NiHgh+MSVomN8Ovme/kQ4CNKgdc7ZKVbpkO4MJXGGF3n0vRL2iT6YJu2IDrRSAgQkSNqS/K3N28fbJhfyLICE/wkyeJEsoYV5cL4dQQbrceDn/4bhuYUoShyHYlI7c/VBBdmOMTh1zc2wjZbe7f0+khwCUr6qAJZS6Nm+l/Zv5LPiV1IubYHcS2b3nX8U7hv3Gk3q04vPdhbQBUQ9Kqw8Pdfv//uWb9t/N0gBP0LTu4ff5OAc4hME5PbIYrxzP8uF8ofWssfcs791Ss/RsTrMDGbhaH+abl1WlX4fpAz0M1Ltjr0h7ej9IE7w9H7j6RsppebqxPoripQXVfun0a18n8fHPjcP/hUYPDVdUFP7qwbQQG/zUH/lmU77NqdQLTD2yVMdvndh3K7+BwfWqDHspvd+LT3jKfre0+XWodd9B56wJSz1zFXz3rvkwcd3G56BPrQOB38VcxHVZPWhPi+GgirzFoz1p/gM1wN2JFTNdfTqMiKFs5W7legq3oRWlkokkzcXDPi+RpRA0MukWYuYWWxbILWp5/bz6mA96MhDE5eCWxG6M5wBge4Z3Q67tlB6g1GdZaj4pzlOGdSwOSKcspPlGnPlZVrz59ILi9DTndec7pz4ZXEuudJJWdQmAsY7BIGcs5LA3f95+5Ez1QI+FzSmS6ytLCuqEhlMivMp55KVZUo8QBCd2d6poIvwA3pRM+bRyb7iqkMzgL5WIETXa0Q8LmUM11gaWFfXkNmMrEp5YKwZol7znifOy1tKPLsNITb8cj3Gbf9g4Y6W2xy+pWNzYHNEweb7ouAnhO2fgQBzvQ/3RWf3rqD9FHcU1f1r6jLQlSjqGponQyoRIhNXEGvuGJiIdFh26zDqS3/W/ria09y2NydJub39juLMjha3xwaeL1XSKiXD5uE66zOS/XGhkaFg9SJYkGXiSUW97P4XeLx1SSOEXmRoqOcV5wubtyv4E86DdiM6Gm8dqVob3qWRp8+yGzyt0MxG0Y/PMrfzuIG0yNcVnoGskxY1c2joEmSxcaJ67O8orLkVVpJqSG9i0YtaE8vNUi0PDAryitLhxezs2Y5IoKA0FaYVaXNgBeBXfPbXzq/CGgGlKkqzYW5ZZpIeaTcqPEENiPaAtsi2iIswCfcm7fs9iHKTzufVe5197ZyCi41TtzJbJ1Nve39a9W/x2k1cxXo9ERUumfWOssorCg/gVXYXJZ4vRl4/eDwxTpfbiSzAKj7SyYFutXKdVef/xeLozs0ndk/kOuKZEUtBg+lR1278sLpAcShDBIrBcw5ZjHJDfqxVDwbzxErM8ILkNS8XL0oGZNblEKMbF4NuKfhb0kybD5nzDyWMzF7fkTCos0/d6tEnDG4Pb10+UtuQ1ZSHzk1oaGaqdrN05B95sW8BmyudkvcGw4NkhteRM+D49EVGFL1er11ohtel2WziENygPNhTAjg1HwPcHK+Z/43WwFP8gpXtLriA9/nL4BCh4zaqQRsNKt4e3kkj6+hY6IK8xDKwC3w3pYytqQeGyrC5JHaHowzihYSMbFs3Y7aCB6/hIqF1OTBFAFbEKYWI1tWhw3LTcnHZ6gbdxKh8B9j0sEJCNxgckesjJWJRGAH0Ejg/N1dnxYCPBcX0fv33MLFPxYC37hOrEhhOtEl/bm/TPrOcKZ+SJO8+0L683FSew89B0QiyYro3mHMgsqe5pxaHoITEoDNGjCguL2HTh/OFC8M8JXAlrvdzzpwr3rIbS9ftpG7f2zDv+ymtL/6sYMkKdlfpDlWUqw5sl9bUrJPm3ukuCT32L6ivtrP+dpU+vSud83VD1APi6GLgsTFlIQ/lTmFpCH5mh84K52v+a1ROlpkUJqKKRZ+Kj+HGyXeE3c3Z22+oLuTE8uPRfuUPuINpGZ2KVUcGMfjgEDSrVZIOkGOXUYozFSoCqUEUr5UoYBkUAk/72Fuh3TRayuuX6+qo3dFd7qmjIwQRb9cXeX1bytrG+XjnC7q4/P6hLI4xoEDDOizJCn0or44mbCPx+8jgkEMgOs1zBfhPvapH1jgR40x5y7L1KCLi8DeyARWLb0pQbqhR2ER35WlxgOkzZX6fIpHSdDBIPqF4SUrJWdvYcw+t+4d4x3Xhopysfyb2xZvbn84mtnZr1u6jHy41fKLR83RgrdW03PQDHsXPLKzQf+kHdDkyMEOJ4KHKChOL6dpSxM3oWg2TmXmlA27BTs5nFK7gOcr97+uq73tUmObZZ02EpfTeU4dl54dX/xm/Obiq7K2q+51/6ahBOWPGx6gn8vn/iJ4f3dcXYiarzQX/9bXqHFRXyQ3G37rbdS8WKz7xgNg5Y/s5sYsLS3SN3ZumGUfrANY+RM7w7SljXWH9b2AA4viJPDc1nnwlqTk8C3zWyPmbPZVdb/tJnorNH8/d14pmPib8knoNwvkASE6/5PnhgWXK9/nJ+b5ttu/PPSp6DwTLluP9u+eQyDPv8vKWqVai5W9E9xM5Zw8e06VwRnrVglt13fW2F2OSr7fQG774YdWUtMDY+c3NnVwbydgCzL2T1v9VZNsWZDewtv76tCVT5Qh8r57jyJW/x0UKpUPw17efujnDeKc+8i2y9XySTR5YWR++3OpXC9vRTwIY5ycR4tfCtKsHhi4j9Lq8ul9kjr9ubOVVQ7n22b4azucTEgFdF8pcRpXuwmztnpP/IkDXSzWyKym0iakLcRoYyGu3ULA2RVjiVUqdocZA2y5N3Wu7MYNg/PUpMHFqBzLWKditsvklMEZ7m+nzjB1WyqdpkPEBXP4VLmdwIFNSC2YA4r3lDubr0mqpaYAzikeyB1HW8rf63ET2jWJ5IBOBXEkppj+a6NeYEemZweAYrFOiT1ECaDBqZhD65Xr11I8O5iBmeC7nAj3mrX4uFvYtY1uPo6/hx3CrrmlCujnVuNuBbuDBTwk/DvJrY6FswCkenYxsoIEMCQde/BbVdyGllBjTXDLhqrb69erMAfh9LHMiECGZ9el6zqL0xh8WsGWEHF/pXMnoN/beQYoLthCSNswa9ECDWBLTVU57kuFOKo7D/TKXuJHhOCpK4Vqd0Nlr1PQk3Zycgocmqw5YrC9QCWI2tkpmjY2TFdbg3wLG81EWHjRxWKD7YGaAyMsYIEHWdzSfk0tXNfKTlEThBfkLK6jMwU2g3zm8BHgYRiGA5/yNSelIby4ldhVID9GErcawpdKgfy7rqAjuJLSzPXM4ByxSU5AJcLq2j2H3A3uFfztX7ZLAlvrhVwOxBbCEd6uqbgHY8HubWxivY1SRxFQ4u1uZ9YWFo5xHjeQwMapB6zkEgA/2NjZ2LV02FjZ2LS0gHYcYRXGuEdkLrQtNJT8xGIPj9uAK0DRmElZm69pQ8KAzdfiDxri19NHN98Odow6GlWMUo5Jv91Pn0iHsV/+0cY8AxsfgEvBt0NUhzJHyDE6DDrmDI+aXJyn4RhcJsf1B1MQQ683SkwsT4itlpI7NOSWxLav2y8fcJ+7H9U5uDf8XuSBzqaeJpDVI5b5FNIFkcsAOxF71mXJb7IoVzhVCEmJnIsiE0pKCCQygjGTSWlXcuOzxulcJDJLAhBBLwcIU0B1Q2MjgkZFIKI5qDTZQXtuKg1ia4Slv3z2suEAo0fQRb6AY8EPkqW2PIlSR40jr8vkdg5+5nXbO4AoZBU3Pquo2bKf3Up18pZcAHVPdjf3NPdN9lG5paOnwzWn2yAqUZH9EjaVv/7c+Es6cb40rP/c8+63yV+ve15+IL40ylfNANAyW2U2geYTyXdgpgszACiazQRpGWZvswNmNNm0NAgS2wgNr2dZwE9uZILp+4QGKf+T5dq5LiT23E6d2HP4+ljTKNuskQRWY2W4LNdRhAedrftLl6YVvdt9pVRpfOK7j+zMGMwkP/rOJ75K45+VcSpt8PhzwNL3Jph5dANzPO9YmYL+/l7RujS3b1Rv4cUg8Md4S8eM1tFo15FBigF3FwAWxcMo+HF+OEb/VIh/t6pXnLwoK0bFr6AWwYU5ELP8HVzKn4FteVt9z7PyTjP4DanCLPMIEoZROI0Rk0xk6wO+sDElhxH4D1Vswf8PKzmApqJN4NbP3Wuf0SSnn6FXJEV5eYPVrLVDxAAawG6If5G0iNm4+DO4RXtizPcvxSPx85jTzy2t1oa1JfEWk7ZkLsY4PmbVn17SORMKuWfZgrVAL4efD2PrGPRWM5ar5qW36PJqjF+FY2gz0G6HBxxvDzNWojnepYRHnNIKuviTmG7i+6FKeB2xcR5O2EybD+q0XDc4ZzFJmvHIa85+DMTnSpDQtEQGoyBJIEAwcI8BGn52EBWHvvoMhu6gSRKYqi5/UthTTBweJg2hCgpSGNy0FGiq/U7pYuQUxvTHlHijHOAx9CQ2Q5lIhnUfIWlJDEZOIg32iw1hxQGfm7eA0r+5HgxBFugfndiXlgHpgsIUOoIp6N78QjiDmAZ3dzWenlaAEkTpICzsJTaXPKMvBJjeAXbM8puPqKGimvhVSwYMW0wWuQb7h5VpumHHc+0VFuaEdRsSWJ2sYex86vK4sAY4OQtnI1EBofWxf9rqrvZvsJsCnAbsLW5lJQxue6tcWVG+bcMhGLirayuKtRq1J9kmE/ukVsuBA69Om07CY2BizQfbKudr9muUjhufmiB7j2HtOttDz0okspycwEhLgFXWMDbTfSx5346qHauNq7uqdu2Lgjm21tyq8Yc5rau9U3v7V8nG9CdN8Gjgu+E3gYOBH5LXA8PB8IVMClgUg2m4Y4PyDynCOfIu8u3Zbv6gGFS8S0aRCYdwe+aGyM3yt8giSkLx+iSz4q0C9BCmISJoWONwLWGKc5458G0g7wYZhgReuhHDiGRwrS5PQDbMOW8gwFQ3jFJBA6HOr8y3zQbL1ZpRv9m9LiyCRap/QY3que/2tUdwY3CD5N91wTPD0QWkXE/dqIPUnzwsE1qtK3OXP28LC3XOM5sBeQYaYPqKuKTIq267OcIsmae4FE/D/pdQDRNX24GV3Eu55m8B/zVsQsDr5rBL3MoQUpB2HTDDcg08GE/DV5hJ0oYq3/7Bz/xxhxMcY4J5GlX6F3LhQbBvfNcmEgeAQZQhberyjY+0Wn971k04KJRQsF35fIVJa3OJ66CrL6PGxPIE9f1Q89RtcnDSjW6RFndGJEeractTHLpldu4HrPGKWfN1mYcvcfNSEc0a3lJIGjbf7Eks8TSvjHC1rrZHkm1vVvtSDi6Oja02O8OHVfn6fVuMf0v4KWsIAUe5WWYnowT2KARM6PY97actf24l1HcMagbDAoBNORN0fruwcvP2FkaJHMRI3OuW0wUOrORejOP+tljBunaWJb6hMVedStduK2oxH2hkySTZgzkCdvcEV1siydGxon0YROFTPaa4gZtRqOgvVadoeqX66Y6aws0cdOpXtbMxMgLgBrR/hoXAfWNVQUGuTK+OXS35Ye/zWUNNIAW0VupXjZwJ5Dk1WZjQfxgKTh3o333qqI3ol99YvFOr3ZBa983YJkz0qGfKs40vPcedLmGY3V9edXQ+2/jKc9I5w+V8zE5BnufW+DLKVsB2UAvuZyb9vzC6cAy2BTwjGse1C2txSf17+8IbxXcJ63HJPXsRuqN0qVmY0QZXobMvQJR8u8Lca55Cql9Pc8mn0vER38PmBgfA4ppTXSdeP5Xhy9rXTReRdW1zOnzwYdo258I9eDmEBpjgDYtX2xWvO9n/HOV4/kPd0dRFH8XPyGUOk5smrp1qHj15ewUCnPDuXffaksP6VrpU7sIbU8uCWkMvKvNvKXLF6Kq0bGPERFSOxfGo6yLAXJMrSYbKn68j6jKVoyu7HqOym6EREr/FDvNTQkqaR08pfpwG4EWssekNPcL6WiS9/ou579cxwQNp8a+a7Y78UrUttSJYbUUBDr7ifSv/T/GuSHC1R1l42KL0G79VeyT7WoE5e71m8Wq38n0Hqz96be969QCIaS27ZH3gYCAN7Hw0kDZMu5h6jwmPazIi2xm8dmELYGw83z3M9bTVwVUk1E5ppg1KJgj1aa06qgfuGaEF3aGdE7wGBLu3853AVfOqPdSAxwTbNQeaT5np9YC5I0fVVQ1BTCp7nnvVnBhbzYx0t4xn7/GL+2DbhAX6hvvoswUmuaZCvhPAKitVuc/TNj4P0X6M7NOT7cVsjDw+L4j87B3Twy3CxuQHxjcNXL1xe2iyIbEAiI1jldVVRH8hDIcddz/t9aLf5addlXWOELiNy9nlkejqYHKfAr+8nJ+/e69jaG0qLbzGae/u/ILVJSW2uy8HiwQ8LTkBa9IowOrfSipcumobR1vbGkdqa+tH2lrrRzURiNkoo+3h9AdqTUnBoNMlZcAedf7WShl/287iWofgNt8eyxtuOKxC++tmtHwj+NFzxsCssq+oY2y7XNmj9p8//HEl7DpPZIT/Y+aosO505Fo7Kwv2xW/63HJtrmNHbVvr8tZMxLg+Uygx+yOXXOlstNHYRC7CsWDVqdHzxpzBSHwkr0Kh809q2jXjfeydT8njI6PepSb3Y5v3mCV96At7eExgyc1/NgR9qhMr7V97eK93yZbIX+3/kwbOFMMgmlnqSCEUqp1NC95zmzwSm1+xNEIcjc037hbXmQ8V4QYaYYnbvxz/iKj9uXRkdKR55EXin+LXH27Fn/1VMNE7mlWa9cvu94tlU7IhOK+1Ko9ba0ZI5pKPQXq+62swrO9xLN3gLhzj9DxxbSgwYI0wv6adpTPrx2aWx0I7026qIGkRfGPBASYuQ8/3LUZQHv3xe9qDqS+cyG56xLxzb3Y7w4NA36REA9Y/mANo0rftkBFJrvKm3b+W+ezyKfXxXfb1KPXY5VH2pr7/BK3cklaOxjvW3NHJ+6lU7oBtezAvBXiUJfnAchJFQcTI0/4xjyqKE0F4lhpOZuYh2EhwzOPy4iQgga1GEivJGZXFSa+eqUYEyvaYrc06H9hwHQpEZ2p4LIrwEOG9DqTVx+G7XqA+a3MM+k2ReQhkUnr5l1mZo5PfFJoHVQGw6gtl5rLz/RCw119C3fOu3WmPeP3ZS9n7eH1pT1x75l17KE/4fcp9yiV+f4QPdNj28HbhzcNLsRoSNPzEEjNbvUekZ73nKPmQ6gvH5x+oPI+emDN/c2xW7bl/2/D5fsiqL/I4532ZFJf5m8278M9jRga8rLYcMY28HakYsWRLOiVGV1t+5VpZDa2JRqnB8/X2xPImoz3xa6nGUUK6Jg65hkf+56bK3DwlViGbkKl5AifMfyF7ThgNP9WlVTHgrkinc76izepoZfV6Bm9tilHUKUxWazPWTNu35ruGzW5wq/CFGwCPomuwo4kq8zwCr7ag2YelYFOxAE82JPZzDjnf/R28Gih0jOAmsikAr2YLwCpvYKovFix6DfDcturBaZt1h2AFbVUAz8kQSDzrX8upUjnlOjENLRvH/3sLP7nDCAWOS4B1j0kAtTVre/GZAPfoOGDjQlVh20EY0PoV8H77DGCFEfeFWAsBnoMfTBYADyjEyir5tsFsbf41pgnDNosOxCUHwKoty0xlb8vMZZb9vrDQysP7vdSeHYCPJjH0m3RzQ8c6x9b0ZkekZW41biS/secl30w2XxGSky5W1C3zT8o+ocwy/H9Ms5TINS4kUVWwdiEp30fMXBnLUW633Jj86hmtJB/3Wdp6H9+CPIcd1dlH9DXlV64Za5b1vT0+Ofp1TWHLFY+a/ovXejekED4k4JLu/slZYJBaK9LTrFbKunldIk5f2lEo/7lBrKZMfJN0tcKpCcm71oImiedANXdvzs2BriiI+zRg3i+EVi5I/Hbn8dqQUIJyJg4UGndc9enIH9zaIEQnwZjev8fwqD2HIo+5BystCehAkENRVVZMWNBSezug4aSMNV0b25lDxt1IV2k2iOT7QIfjaJ6/JUi/NzmO/cUTQ2RTGqyJ3qs3j7biPmwwRyY8It4O6H5WtLTt0O0KaG66Pfgrt+ng0D9raE00EP+7sgbMHVUusuFGQzPieMcAEuxwLG2/mUWpxuE4rahmWSlLXxer42uu1cWRc3usa8Dsi+5pejz4W9d0Ir/29etoTbRwNfMTYVwikqF/fn9oh6Hlyyuv92KgSYZ+O1V+PjPdd/Ex903/HD7ZpEwlpnmuBsYxfCwyBCrP3Da7t3gdRZ62QABjB4erG8nbMux7eDbYQFBbYtWKjBVQRXlxyIVnIoTL6Bf7pmN/fFcMU0VFO8SgnxSIBklhMta1+KUSnPdVW2JwNkNkqpv/RMWPeF+UvsbHyW88KWAC3sCpNXrWw0gyHx99MSoJu30xN//jGnEv9xcRyPyDgc01KAYNGc+golDIxSNv4fbzfU/64iiaoyMSmMEz4hGMwf0nUR2bmEUxyTf/Mn9eUZXCBr5sT/hKfNNZ/nyfembs0H97Hq/veJPk4DIX4/hYx2SfW2FPdM2selF7enpU/jm9yO44SD6JWz0JxbfVr6vfFMMFDr4YVIjnkfEd9c71/+F7TkJXvys6lQAPQsEBPQHILch9XGCf4FnzC3OQD3Q3I9ZhLwEZSDZCh+VmYsUJQumwmbqOkDo83qTUczVQl6Mb4vBaq8lISTIf3DnundoHBCP6KnQHNz3UsNyFoajBNboWTeKKtihxuTEnv9DchGyILewZMVxoYl9jQkMQmVOqIzm19a1Z05fAYiXWeBG0KC2H6bPWUTKnL1LLZab0rQFQBa7RPzE+R8kxv0Rp77GeL+ZdGKZd4Omhfxr9Fi3L/MjQWbSce0VVJ5sfQsrUp4XQTdw1n4IKt2klR/Q26gWt4nBxqfKUAPqBBTbipa/bD5emwVySs4I05Xb2kr8VsLmm9mpFxdVahVnB53R2cXg8BMPwbbo2AcmhgK1Y+9AcFy7QIMdlYKovgTwv790DsFDPuwCcqtGvYtuctNwLxgzLTVtO31nTe+bsfIV6wD/Ywj/YfyBOcO98f4z3NvgJl9um8lhHroNXq1NUksH3ek7Irogpt7/EcuEQ2kQGkyWKEKqshQFxW0vOyXl2ea7DaSyWrD3rOqDYZUj/x/nYm/1O6zerPzRFNeuP55ac7ypUndsVrZGbxVE4m1vSvv/+5+8jbxrpN7Xs0Fa2n1lzXilF1MCGgUWvAVGYcYANxn3u6E0F5KynZPaWpueuBhfAiRx3iDkAG1zGkX4ZQEK/xW+yiVsPab9BfuJNcW3NJybCc3OJDvvF0gYhwSTgEwYariZKmsTEAb6Q2N8kzDQmsuXqbGZechJDnl/AyPiulaQUqc0N6ep0ohmbUPmLpRo5M7/pX8vcXI1as6m61tyn1Q/31dYM9+tU7EgVDuzI5CJg7J2OPJtLYx3+NVqHa9gSq4uvKBowV9cN9BXpB/vqagZNE1qzSzSadCMgMmI6rGZC1NgIJ1gYHM5xYESBHSyfTKLfDXdmKhB0SD4+BZKrs7JCGSgJNDoCRWMmIIdC3NWBjoeEhITVDYMSSswCfyMFFIp3cTw+du4S8mSTeMnbbzZsRiaZD/aleo/vTBV9rBZmC2GtomRD0TmOx8OKqbZE0Dpn20JvYtujyvmGlERVfsMh+VwrLlFekEz+wJmjqo8P9BQRMq4Pdp1l+PS5fmuP2cd8YUP/BlDnl74jsfdGSYf1rw+WPij4dgDccykV1QdKcdwN2CD/1cXldmD+tz2le4pfBxKBzS1XrXVLLduJTw209GwmVrHC9KjTVHQ4IN4Cnau+kG/OP98P+c4X8SUWM5X4Wpgs3sJmC4lIwsrK0hK2O1H/aiezb9VoGBXkIv6mIz89DUuJVJkaUzbyk7nFFW1txXVcYXFndUNZHRiK5pYEaa0lF5O+o7q5tFq8CU6McbHFLhWkKRL+2NOXH4lIWF388SDONTkXCy4YixEtxj0RoS06cVFKHRbkow/voW6j9iTCIzEgpc7lRF2cLnqV5bfpui0f5411KvwqZ+b/m7E8P6YCxNz2BMG+6CsXfryPEg0Kdx4hi8tznzpGD5y5jcaoetCJiEZUE0+grdE+zrec1/1WGmHxVNr3waY3Ee6DBSl1uiillwIMMGqm1MY7RTBCVfqoqi3kzpcevIXcBkXdQlP468FrVPGokUFzzK+VMjWvWGd2dA50nqjessr/qvRBIUvzCwu5ruegZ4L8iqVULhJYPB8XpdQHILAXwO5bclLcJNSlrMvQY0AURBOVluotjAxlk5YNRwNX1zJRzLtdgyRNWTDIg0EsIRIMpN5eUTxxeIIWf7Cw8JBej8kdjNIviDa2ngCBZIO5vDwAg8VGHN5ukgr2nL+vpwsx2Rh2+uWRCIPu5Ml4QylwxSc1V3xCi5X2ll51nZhw+ya5lAGo1lxV37jSrm6hKmrnAOPznQEMz3cREDFnke7JKS2sOgs3U9bozIThBEY9Wp79g/8/71MDje44oDRy65koQjIshN6EjhTyCj3tn2X/grE1tfxV3Bpif9jqOkQ8OgsluOZWXb3PvR8ktG5ntF+RIu7V6ltTvbOmav3ln/VAwCKdtLgsXQbnVUlooeIbokUTk9Z5PVqp6f3Ji5utC7TK7U0+lVB8srS0+NRMfFnuUkbZpEPAncIbeTGu1Gbxs4Bngc3prlS69c9RvsCyySWvpQt2TsXFzvR7Yc40fTHd+U74oLNdcTHD6S5119ZZn+yhigzZfkE+8Hhf5yn1ac8E+ZqZ8lpfOeJTy2pItr/HSup2+44LN53GMOzMYxU1RIcf4r+1+d/61zXkHzEKf3O6DrI6EgyvVXz5nAR9AH1g7+RqlD5lIjyN6KZL9D6NFG22MEv6ELqnDnFzB0olWVNnx/5CdWzWMt98rUVmg9b21F9xIgBAr9kAEUkpYdTcqprpddeqa8YArmdJMnxIZ83eYGSYugM6ExuMm4FIVZ+PUpeWuis2JvfmLdc6siNWuK7rFWmhfnURLk+UizYOAICdgVoDBoyNfSmPcRmZUPRD89g4QaPx2zqnPCOcGmWRaG8pHLUVVH7aL+pdZrHlphbEwzVkVuRkzi1f7q5wrTQ1iGo4A1vs4isMrfAwN1T2xULdnmJA9BSDNJOSDbkOwWju8fkxexzTsY7pRIYWN8tSHDrPEwSXan9DEY5JL2TgsWuey//QDE1bQIAMbYPm5MMngt4Nx8FHwyM8098RyrBiORDPCci8jR4fnQV1SJH12YS+OXC2ADkD2s8QC4o1zPM/0TjgLJj1naIDfsLUsGN0jhblGeUnFg+leJfLnaAQAVRN7/L1cf8nsRs+/CYKGxoHLk7CI/v12fmAU26L0kSd/tkFyKEi8spOnTiwDX920JWl73q72LZ3zv8M7Xc4dvbAX61oWrNLrV7M1ah3mUFN7qLaVKZrsv9Gx9RbzhfqP+sDnR9eV5QChRWdoQjL1BfpDxOern4n9sMLOwq66RKXchdwhhyteLjVMXlL/gtR7lNNIpEh09I3FwRcNG3jtplB+pOczhhvi4jXdLWMcUZemxP63ALaiWw2qAzn/zHo4DeyIlFT01FuaGP/1TaTPt4Wznc6d/McOq9t3M79m4uykW6TTbWn/Xe4OC7m4qRHcyJ9nD7vd3Q50zQnf7tEIqcn9a5ZJ+dMJwUmJgYmJePJioQkr/p6r6SE839hiVhxV0lqEpU5L3pR9Lzm5wDMiUxAqZPF7OtuZFbdyK7DwY2Mutpi9Q1tghmeXDPNaWOz2zhcKLY5cBMGWW1cjslt8qPAx4Hs1O7vZfl4f6BUIuIBomtdrUVFPCKvA2SkF/qlwFpnuxcuePWYpKu1yOEOcPHXqBIsHdiXEASmS0Q4wDWJvxTOCyDTxm9VeODFXE4U1hibJX9ncfL1jTtDO8ff7wjtGN86GFeoFtK41ynlAVPXa/VcH/nZscYAzHydIfC/9EtjczNzpO9qEmSgmCWAZkIgRz+wDPBQTUyGkwIrkV8ywNIK815VwDAemRFt+UrlFwtHXNos2SFSVq4/JmAduTqUWDVuKcLCQu5VsfezeLgba2Xsh/bAHsaZxgOaaXiMuKeSyHAQrc1bUrQRpEWWwWZwQrTJaPS+14MRablC437ATHiQ3kSnGVVFLYoKkyL1spFmZQ+DLZAI0fUsNhTiYvNDFH1frq1V24zxOOSOy4GysNqLnvZzvKee6X1Xg+B5tn/tQHkzHfkHZomBRKZ+IiCYXx/aGc1pRX8LiwdGj3eV+cfk5svpgsbrqWXt9jwSShSLJFHOapcIC7Cs2NEXLouAR6Why6wRZG0TYxJtKEfmu3kRMqYnRQvc9qMUKQ2hu9TaioRgQholCOamdNHLrwUiLuU0RBUn9wJdgsy8pGDpwc/QHUc/D9tZRENR39+mmS46uhlY7kRBN8BL7Zr2/vua7qNWbHw0BnubZnqor2tguRMqk4OOjtomPDdw49Ca0s/toW99V/qxl4VjipjmYqWn8lGl79zu4Y7GyGhqqtCrq5m9zEy6xa5Trx7zu3iXt8BJJH+b3E1RxHtXR8eODg/hnvfI5Ptjx0fHJnWZt7nmryb2kO5Z/Vlxwn3y8eERqsrCVLw+np4xl583Ork6xjDWgk84vumCHxJ7tlSAxRZl8l+x61liR0l8yVg6PNvH54q4yPYBNU2/DnaUJJ3K/OL/4os1jcXbK79/3yJqyFGAidtNKtfo7e8/nkbBhMrammuF5prSI4Y3o7eV+ZArALJ5ItgAZG/fhi9eUXohtLnipoF5UYgVK4hGHyHZScXVpCihsvIszm7m5oRQEPI61bnjbuWIUYe9YLD0YL07g/kJRSgVSR4K0TUSE3U8yD1zJRfDV4kLIccDjAkeJbUISogF7BWPuyeK/hTk/WpnZOUxB2YVjp55zV+XRMPsESH8iVyGdI/N0Wx0xBDIXjwBbfmY7Ge8lAyPyruw3vocXMrdG3S4I/+YtOUVvYXLZxVzjnXzIg4TGShPPCMrcuoPH4C8UTUwyssYOFJktTk4udIcYnwPFkOw9XZwYWNoKpmlRBBDHRzWKedlhWCgDI7hr2mC5QPUJAaIKAw/lYFrpLR8plKlWhHFZpE+zTCW72kaY7GoDCpnUOtKpjTHY1VuaOgAS790dec2/9nOvviN57piOiOT4HHBwjtRcmwUFYGfED0FcMm3GixpXTPgQamS0TaW6k9ywB770ZZP6M0gTUbKroQigKMFWM0E85j6AwPHvFE1MAploh0sJKJ4axk6P5y7LI22Wui3ANf4qxv056BSOL4qNkwq3CGDm8NB5U9VxVizd5SAn5tvSOsEUHBVTcNfJQcsVQ/mnT10HmI6dDivcTW6Vod+q7pYQnEOEeeIXSPRds0c7f1/Cw5AVbJd3CZQg3NYyiQOQS91rxaIFehk9HNwzgRQ53lFtIlt2JWzPfhodKZyf4SP+bJBx9V9n+HqgJZnOYdETLPcvuGZUKt8ytcXgsMVeEBpe23tDj8MApo0yujpmrOkgICYx2Egf0xkLA4FYgbGuOHAUUiUXJjn7gXz9IZ6eeO9PQkUZXlOiS5TNpzJ44es2YsTvpJCMoMEzGX/xtZyF4vAocaLAb1tjS4WQGTwarCRWercte47HpZ+riEYKyugGxXyHoKajX+rVtzzxUZaub0PJEW9h0QKs+/mJLxZ0fGjFltLB3V+bd0wb4skRno5RudkqCS/ehG6hh1sPQZSMAfAvF6ho/47jmT4LfLrHv0eaQuPGvlpFEaLxsWEBH298G0LL6vJSkOmRX+99YbTtrI5oKpzydH/Ho95Eu0hCcaGEnmR8/eYRbZzVCBiCJbhAXkRLaMl32X+tATpcAiA/t9S/2vHuH1zxCDB/CjEuSQzfKiRMtDg0ttmYeVdltDxHUw8u8Mi+jOJ3je7Ayq2sAp3fWh77xLv3/SdaTLP/t4ROP9gKt/2rrv9XTL/70xRIGygeKHBpqDEgyqgkCgSCrXEw6ZgsQFiZYVRPk2vTw+wspJ2R709xV11/Jst9UKsEl5E7G3dG8DgRLB1gNkoku4x5BjzGBL9JIbmiYa8K4Jk6ZDoXlCg2hr5Z3rUSATuQuPwYTG8JwPXxb26d2YeyY7wyPH0QeJp8sO4vekm2n2ipVvIWybH/md325/JnC+Vogii0KveKwCOiKBybX9GOSlRIOx9eg2PWF1d4umSJsgkUTIyDdzy1anVdTwIsLVIXl0m5FeXyoEv5QthKrIyYhfhsMVYaDcM3o2KvAuEr2kq5IqsDr8CZwqCmKpOdrsHQuLPcnxRYpZvFGQnZR93qTyp0FMNzzpBcQiE40JQMf3Jm9VReTQgKThq7V/zmpGapRlg0N2SUcc8hdTOwtLS57637mGceGKrRbTRhdq3c3Ok2MIyPNTX9p5+A2GDzofhwj8yArbY3xn8QNXPJQuNNvkMpanIJJzmyl9sBFmuSYd+xjQK1kA4cRZh7sAm/np/DtQiZP+jKIjmGeFP4OxVJv4auPi7ra6AIV5c8Y6Nx15u9O/HG5aZDV+yHnQjg9V8lrEjRAfFF/L1ZznHQvpBzNFmLvzvpQhzZt2xsC5znetuu6dKLAVkt1Y6lpExJpUCGIM0Gzi1pqnbYEiqldhe0ab0p4W+93E5jQzy4aUrnfVtLyrJqse6X/gJ7XXrms71vm03L/ojwDOv2bMxtxq/Xhq5iUjDJKRH8IK8Xvp7hmXncw3iHAcfnjfgQyNS7Zyh6T+lekUheQJpHCku6NcV7YxlsmtcbnVLf0Pr0BfivIFfcc2GaxsqNmKUjS/Rn4owVZtuhn4OsMdmcQLfg/oVwDGz8LzetmkFt4QONq0J7gESQAMzdr2HTh/KytieCg7bnA0cMQvOslxxox3r5LWMdeXXpyCq/PXsehv5NDLikxH5NEK8DrkdchXyUAnYB5QPz/9v7yxL/NWgnvosKg93qedxViUo1ysvmO1l/9LKLZ4noQFl3s7pAIhZYpASvDepNOF1GDHRiXnK0dqTAhKACHebNKyC9mPIkNRgD1fyp8kWOQSYHl5FARGp/upNTJaXqEe/atFPtoiMm3I6jsqKF8TVGohswF1IQPnz5PX8l9H04N118xCWaCinxpMuKMS+Mcp8MIq612tAtGA26P9bn6ykAnwBwWMYcVAibzA050wBKT8u72Xc8hzDdrCQT4xbPTCG9Widrykl1irEKh6o9n0Nx4Pxnj67d/s4pwMQg10XZ7wjjFNA/q8tBIrrqGz8BeHh8OT1znGsX4xRQ98AQGjcujcSqyr1xYFwPk4GqZPzWoc1ARygYTn03eVMa7o/rhKCDaQEwbu5JD2KYBkjdlR50FyygwyRmmDoGUwIoNGtS+0t8hf6Z+OUFq6WIcpW90CcjbMifAuYlRDnms6xtiqUEX/xdtzRrjHyFeEY+HTpXN4IY7LX4MS0AgCcQ7yf2VtMuVsB7W1dTrg5X7/mFG6CK4NlAd3cGb1QE99lTov18pteQUJ9XGpHQp18xR5/mP8Dnh6OJ0tCDKFFPqC4aeveynDawUSy5zLozmV3m7ZAorAXnyfDCMy3N+SEcaQ4cchhwORd6FoPQpxnui1DFf+GCZiye0EGtrS4eQiQ9Np1PRzvDihJjVjrHoxssITL+YAfCJYBuAwbwMXE6R/P2oelhtTHakL/3yY0G8wYQZ6sFy8ktgXauF++A1omex5MpIVX9lpPx4GKfAyhkhBy/Jgn4B/RHyJiX6fQkVoXHyhyZdrPK9ac1hUv1OhnurmyAGWwCR7udO26s9sJF1t7oJX7lIX9M7EQZwCYVgan3skRxlzedCkGrgjna4ztOxy9fyHKrAqtOa7pcQlg1pZwhTPOJtC9VRli6WqhzMYJ/UX+au8uXTMAE3IGqgk2RAZl01xUHmLHGIKlHsUldcODAikQbCWO7m+defld6LKBAwxY47DW2UlqcML54EC+papI7N6tjQQAvhlSNf4Sx3Jen3w4/IKQja+jincBD/+vgAjj7hjjsOtiAEh39tm928cTjIfjX/sC1fFWIVaxKSZfHXq9wQOz1fgEycJ2jHneynhwfyOA+SZexbBN94zzIKxVQScBh4+JpbgwTk7PUUCGDS6AYPka3AqXWzYgg93XpkbAAIlw/HrX1x6AxJsWljLwQlOiJjS2PjUkzP7sl2lAdkj3I38L5OsQ+xvuvH4nS6sXbmM+thzmHxz43E3fqx0FOAptbK/IqlsBgA2pgZZqwMh3XTIA+NAt4j4DEOMCSGbaAQghG7ahAwhsf3vbDZ8CrYiNEQFshwB7W0s0CpDhr2gVPv1JEMre52MaDU17N7rw4ccb9iGvkRb+dQQ0x9ZnTPfCytLJndZWfKmt6bJ2BBxW+35TLl5oGbEBAGi1C7syyeoDQHDXOwWglu5o4QkIxwDweQkQAtDbNoQQ2P6bAiIaiVaBn9C2QiGgJ9rS1j7gP+RbQaTl63wMwKY5qx46dvRECjcaUpmU28nZT7oPuo2yU29VlvmN5uuKUecVmEAdmqiW3Nv50oDt6VKBXIZZfVtbbKotq965WSot6jAFzQFXri3I2C8W5rUGXEU4/2C4XtzVVYw6kbmeGc0Kfvo0mBEdAglmfsFyRv8CYVZyMSEh0cEMgKQgn+D7NKOHsSxEecstBBdyLyQoxOCgZuGiB8NAuB8eju6tDcOHJwuZ58/zmTSAa4luXvq0b2FzH5u8b6nd8WTCUgP9qDOiPgHAJQlMBwEWoHDAxlvnTAvzZpzrWwhCl7ZXcW4ObyYR3XfODS8c00lDcbBKhQJPOMzUaA4xCXhFtlD4XtXaij38gC2oxwrJu0fNhZErSH9K15F62l+9aqf47okPaXtO7LnAHndPOPMwgaBQCEWq962PMraT58cI2vOQw0Dh1PQLmJGcHFBlV7JQbKMt8XDF8BFkkgThghkwv9PF8FGn5UEQgACIxjQHwD7bqr1UK6pB3NTr+vlgasUv5g501hyCaTOPWu6AIx9pY9Y9jel+6LO1lVnTRkIh2G/77Q4MhE4Q6TRf5FX7WartHG5VDedyIzdJV6hyRBikO+2XQrVervKuQGMq29KU2HYmMlGIK8SN3MRdk9rX409zSs8+BI1h/fkNqf17LRTBJaXTuktYQSBXZXquWBbLptGxbEblVdtS9Qw7K9WrkfVYT/RWwE2TlgcjNlzRi7hsFotetTGsX7BUzSeotqNV92HaCtQ3FKktR0lOAOpTu/KpXa1sx3Zsx3Zit0Kq9gfSsVK3UCsfyzCVqY23NDmGxq0zIDkCaGoCkJwD1XZ6p/GMyZz28gJ05r3XwunZG5ylvc0F2Ccxp0BUPMfFYnCcm5nm86CzT1G5C9TNoA4Zm1Ub3XdHJ1mgs25KszLPmDdMFHrulf2fGi0HjIe5OFkMdg4M+lRdPKd/U8zXNKGN43G4GSoGwbi4ekCDiIvFYOfozexQuhjP5HACXc+Nw1QIx/zQouqlHr3DiIARvPBiCCdIaMpzLuJ/2dwxb1B5TmUybGCHycVicKjz5uHg9IFeLDPmaXI1SRb1Ty2SjZMOY8Cp1l+pYrD2fYN28wkMsnhlIQ4gdvnLJ3ouFkNipWb5ElBtvrRDkN6Exn8mSxAL3XCDNBJLsAJnncSDE37Zfo1EcLEYHDIlst8xKnfEDT0mMnpRCZMsw4ilfkxgcokCvgXyOGQCgOSRBPpy+ExHz+RiGXxuHofM+jqICbSBma44FmYYwwT2eXkRDMuHMcylJN2YycUy+FziyKYomfx26jybuG5RQ1l4Q2DHUoYkYymX8RNxXWYGkD7TMM3Uz94+M+Gv1xBEBESU0ZjhMkZQcxkj3nEZttjLGFELKe/0sKJ/rt9Jzw3RuyVz11js//kAQMKQHUUGA4gjGHABG8l33vzYCSKbgy7ktmEhOpu1wsfrzViM2XnZRnsHBrJf6MEU3DUlD4nz9pNOxmsHBpa0iXgRvwODUzxEvBlBn+vqyp/N6XDqjhQ27/73x3qPNHSz9gGtjkIN3wXIxxIpR83ztXPQzKL5d3bwVi4sWfWbroCYTuPAn7NXRjf/TD7oOhWAG4YtzzWpMfuXJE1jgNf/6Xln20TOnSq9ahAwkG5dff0LqmFcJ9j6nt1+Qib4Nr65EI1MuLNSfviGRjTbnmVGd2Cw+LUpAwidEWLeDgyhEnZpCCrjFacgtNjyBVL3a/9bIDzL4OI85w0PoWGNGut+2rttV8cEjS5h0Ia/Xll3YJAocnzm5KU5J2bNTrClzNvi5r+hug0zIKZTSThPa041rKEUnSfHVmhYemsjC/s7dzy0o375xUewzKm1KTVwOZ8F0oAZAxEa0E50Zm8ExYtpOSXV1MXnhCm9UhuRYLT+iiwyhIhu0cOCeFvNiZWcnp/ltRtPgZouQ9teyjIKAmaTm2u1hFjdvd3f+wzvFXLVb3a9k/Y1qZ/EYCIqdmm8XmGU2zr9StRaXKpbo9fk1pji3xpbkq/ErZ3Ww/fHF4gNmyaVfgPZH5X75dSbaPSqS8PQl3iAB3mI3/I7fs/DPNK8aEV/LcfPI4zVUwD68mINj8SsexfpLy8rJY5FS+toK9IznLaNpUCTRiS7xv7etxgQOQCC0theRGj9aO+DaxztfW5lbYAostJc0LQQ5Puv/Nf+G/+t/85/73/wP7bNTcCUNNcLQyjNyJLmNo5Kgr40t5YoGcKuebQv2hIJD4WIW2kzuLnttIdd6QTZdfb3vsSAyAFQls5abzBEDxmih/GWoV5fhfTW7qXaXsqexeCRkr3rRb9BEm/4iTcMmt4qLdr1WqwMZDsZxgMQSmUApzJQ0Tp4ICB0Aqoy0GogNiAgIuLBQlD41nWicgFFp8Xip8XhQ3wJX5KlluzsO6HeiZb7qlN01Ku+D8ABPi7SCUgALK4LGE2nSDgVy+8uWYrTtOfagGX+rMefGe0/J+uc64SwuiQMz8D6gMdRsYPn9YoYoUgdipymKOKq5Kcq/aHKphTzPQ8wnUd5/NMrhX7/Ejio70/xVSSelyRGkKQOkpxGUcS5Sg24Vh3IsqnvAnP2JQuGJjZeEScUSVCR1xTFWZVoKaYUBqCp8GcVsVKRfityn6LoqxIxLlVlsGLu84DQw3TssM7iA+j3zLB/Tqhi03rQxEquQguuRg8BRV9QIpZUKiiDfwvs2loWLCQ54hUxVZHGFPmNoiiqEpYqPVBl3xXzAw8wnUcxjisKf04RmYq0rsiDikJWJRKKCTAAA4U3HBI7UnhJhjOc4QwX+ApUKW5Sho1WBL4CpvMoxlOkLUYykpGMZCQjGclIRgoSIDHYHYvcj5yMrHNSFY0/x+b1oEnrXI0eAgpZUCIhKMUJyrDlgoOdktjKFt81Bow/lFJwQttv+LkqhzfeQAeQuk6U+jdhyPgHGVcDQGt93B3FFCy2UHGFiy+hxFfgLd+I8UXBYgsVV1i8z2/Cp0QBE28MChZbqLjCxZdQIrKKV1J6FhGbc/5oGjDKy0AzHE7cfcfNWrnnMMpq/70YY9XmjbC0XUWpqLG+A+UZWLHcqGq9zaa22LbGpO1eBKVdPG/ajLmW7WDAWxxaw3UupTkbxtwESP4Bny043xH8CEFoLAXcbncvgDCQibFKapyYb2C0ZQ39vE2VzAgoTh3J2H4BghW8UhCQShI3MN6A50uGnh2Ayb8E6XkcoChXgxYMjLLFc2BQLwE6Pw34UOo+7zZ98aRPDPCsxpXQ24YN9DYywoShD70NnyiEQQO9/bxIGNVNlcGoHvAlHuikSu/Su/WeQqeVvv/14Cw2fOA2dRrQARg1yZmmT+nT+ow+S+aIDcwDf4GhyKyCz/wAMwO7qFF7rO8HQAcLMxgzAMQDJZXfKBD40SX4NIAAUN+pkndbbij+ZcgDNJBSNr241WqSbVygJ9XW0sy74aJbFiTu/Jst1isNEj3xpePB4ZD7xpz7X0YuYVkSXBCxSQMbowSgkM7oxzbrn1eCYpB8EZUlSdBQ/Kj+HPL3s0j/I/0v/FyJ1ABtiIDieymAnk15Mi+JCzpJ12EJ7j+P9l0946hJWgJZm9IfKYtSpslE0jDp9B4a0DGRxLDzSaeLcWpKtqE2iAPfVv1fxvl23H+tXFJLV1kHxIOmA/jMi1Wuo27MFRbqAx2+8kIYiqiiLOqXtvBxa/rdOk1mrYGliXhO0guZZo2CLztKZI6RCtj5XGc9py4WRQRvW2cw6Be1idv0bu8nq2XVCHePsjMY9NqbLIb/0km7MiBeFT7fjtyPW9CzXBSPfLgyXBEuDzPD1d9VJVC3qmXUoBENqHcHuddNpy1k7UHP6f19F25PjX4uYbQG6Xn6fKPptEFrszDKC6IPfS1qwOc9dJo0B2hNRGwuatYosZBe1l6aLahrqBZw2iOzh3heiM5b7/+PdK0avai9CB69hmryX/bz9PPCz9fPz34Bv6Af5Tfvu1GtByS1oFUtYpSBYTWM++0twzbrvIaVJwkDnl1LZSeB0v5gZV+IzvC6dcIz2EuD1sCdWOhnQCIzLWl/av9z9qdtyTiNgDHH+CJ+nDD/4Je7AdxppwEsZRXgb6azoCedm0qy58LsRW5FRxI+MCW6dhZbUqMUqAK61RYDJqMXKYeah3BwiPRKNwk5n4ExNbb8265NnS5qFuLXT+SolKqousZ09syO9iJmoGMF02NRLTRtvX/GP+//4P/a/8Xov2ul/8Xlvj+ec55l71tfbG19iWOlTduTvLTd9/nDD7mvjpt8W7/+/fLpylrNfxxEGi6+vd+l8QspE4AM4JIyqGWH/YzihHhfeHw3kIlYavAn8JIfv6xc8SnN/3/c905Sk+WHOJJvn+WfK37pemB7yMJ/rV+BV8ciL57GUwhfxDwCqPT+dXD8vwD3XgY4C37p/d9fASxA/NALgUV5tzCQrFN+BIgtKO8MACIeTLWXlAOfwN2vWDx/a2zTaPCrN1tqn1+EQDyuDTjjvwHEUQAIn4Kuyo2QcDROYsDkA7UqKDGyTjf/k3wBzVOQwF7GlYGPS7oKL1K4m3IbmwCY7CS3ZRsUdlFM2MuN5uQrcKzGjUKQGDC5tdtNQeFmL6NG6HjieHVU4UVhScfG1UPAH6cge7nRRjPHaZvEgMml7QXlltzEol4G8eTU8FogCXh0GSenoHiYg2qAk1FYUEoXggx8ZjfGFrsJ3sTgXsaUkKvcCAlH44UYFE0ns/9YzsWbeBngp4iAj9fCQlC4IWstIuDrlDSFVwg4sbrTC2N3S854527hjDPrbK1O0oQMYUg4GldihjAGTC61OJesJzfh1WzuFHQKV+U47xRDaTZoCkLhvBw3O4zDIyEUX5Xbo5bjW9rE4At8jQVeOoknUrN8SXIkpIhVLIWEhx4uicpVmFx3YliXWo1JgjnLBssRiHJJB8QsdBC9jZta/THNir1CSSKh9yB6sdRMdoW/KXqYVeZcfxKBiGTx3eygF3h5BvEbAAOTHAkpoodeasLsCs/onsHWbrFLMaC5zCHYt42uBagxzeRe9s/5kTjGAxnSTnSYRUpXSQIQzS5IC5XXJAY8qTichY6EFLGKJRBehXP0DNZuzsUYMALAzxEDkddC11Wp6xWJEBC5pAdcJQwkgPQFuNB/TJc0SAWZwPVWZpeSBBJSxCqWuI7fu5rh0MOlPe44aqbrvRggDQAxSSJF9GLppsTjVxao7SIookFgaA0CfwlBxHeyg4he5mySSEgRq1iCwnP0cEl4rtJMV8AslblXc4WISBaj2aE5kO/Ba+rt2ShJUswJSiHx56QnUWJdnsSSBLvnaCZeBv620SPxUiPM485MDNgFzZP8LBsnKTM0hTKzkjh6ciwh81zif9CHffSs/EVs+0prAiY5SAg5omFP4vARO7FAtx5ZxjE6SAg54rqS4TEShTfgxYdiPx8DBQJ8fX40FACei3F9WgvZH52hzAqeTIx3HieZk13f5Qg4GXvERbNW64lIZjRAnOMBzmswdD5cPRttzl6BmYUCM0p3YkArq8b30bObMRxbE/XQ4h3T2dHxzn5fjMNVm6OcETa6pCqeRQ+JGZNVvBheLAktZVW3d46ZUa0VkRvoM0bdWWYHQw/v3tp4xx+YEgMAsSZqvDF79tO/pPU0KmHQR6GDbuqiASKrpE7UVYZQajyubRIFLHBXEKkJ19/GTtfqwcz2bn6YsXpWLSdqKZhQ46uTxt0cqbFN0RVGriyL9ZpMyS40meya+1xFmgAO74ymqyi8XUkaFFiX4VfiGHVV2tXbK3eWUTDIahl3HMyT1LXHZpaRMLtHd0MXvbQDOvadU5kR6sVYLc6vmphmJe4Rl3BUuzU/w3EuaWWnFDpo7nqEuyLtzF0hMrE1tXk8lnZpTBlWy4khUhNuHDPs6G+1VdFD0a54GMLt1Wkqj1mlO8MpcMO0pgNQzZpWd2uaJWWeq6zkCceN2JNnYXtQ5Erx0IjHXAyP5lPNQBTGsxBRPLKCuPTO4G53YoGuyAbJ2h/TN1qGlCPHgMVmjmclujq1S+kWd7m7gnzlwvet9eOGxcVMZp3Zi6VziJPQlrxxaHFMWhtxak5xby7xQOwuGLl051jcLdrwSG2IlVAoEjCpbQwKheHTowdasw6pXem4Im4cKobclilOXbrT0tb7K6QtcVRqoZpJwLS9I04FiftiiUf/v+jNQG6Ft3rtTaqpUCgUCZjWdwwKRY9hk9Hjz5DOJwmthhuHqsS3ZYhTyYp7EcSjixejcuDuMySza0bnM6TdWUJL+car1HF0vs9tNGqZjs2z0f0M6bOjtwr910qfDmvHidNKFY8+uRjRNJJ5gy6ZzVQLnWcArokKQNYAjvhyrtYySycBIgasKjy2ZkI1A4aAIQFHfDnntP6krMzNWm2rAK4F88pJLD1MaYauxfLKSSyFzHICtiqDvh/0Etqxes1Kly6hzP0trWTFxLuLVRtjaXU/x3Ruiex8NNGimhrwkMA4oUn0TCr8xFWeStIsso8mWlRTkzG1l8jw0UQLfCa1rESGjyZaVFMDHpLD/OJqsf9RKmNGp0RmH020qKYGPCQwTug5ekauRIaPJlrgH5OoL3MOJ9lG+TB8NNGimhrwkMA4oWBxRkpk8tFEi2pqwEOqML16ThynsX3MIvtookU1NRcYiDH7nmvZrogBTaDjniFFUk3yXsT0d6SDIpn+6wiLRWXDjnDGnubpuy9+ZQ47CifpojpKnFBcPfQRAUgVxndmZDIcgfHuSAlKnd4+ApAs3OfK1e5gMZzkJpSH46hf2iZHVFAVZ4vjSNyWaizSN1wkY6MjgsHjjgya1I3x2RllaZHn7N1wD4rEmCS5CTY24qhf2hxHVKCgOKONI75F1WB8xcgIR2C8OzI4IXUYn51RltznzH64C4vhpFXsJMGcRhxxTVErYo0/n69dw4a8qbxKNTvygPq1a3Tz4Vpar/KQ9A+nQssH2kcl1V+twdbJcfDXtcBWXtn1xIbcGvsjtRYU5WrXYJA3t0/xnOM8bNernzjCo2zbjig7M01ls/JsPLF7dwJTnT0O+KR3710gP3YDMAeaoiqsbFupUMT0K+EF8+BvdTXVGq99SQ31Gg9iw1Hv1ZQdTGvY9rHCEajw3adYMZyjYi9QSkpA0w+iYz7uOjgASDkvtXpKujMeyx1ICoh/SGKA0mDHmtrUnFS7CvKLhtULbNzEC8DfgpKxsjj6DLCxCX+1vuPr6a+bAcxNWKlDh6eH5AI73+jWaHM3ySKDdmo7959QzFuE9OH0jiERas2jGUVG/YAv6eTQ42yoELB8Dh/qUznDolUBXJsT4GCHbc4NtXn2SOUMADzYJdiZR93HLOb/Nedm1KopNTRvleFSVXlePigKzqwhaKvPg0c88lX2ByV/0GPEqWfoV6inUB0DLBGNnOBuKbGKHu+caRVT0RQf27AeutvccwMwJZW2Ji54gs3511DDwt678+u3YtDVOpISC5htgXUGa2nIMlpGaR/xh1CwTvN/qjgmfsRKXTqpE0H722HhECrqQDh4vPwJe3rwIU195OA8zg+Sv/rf5xn+/YY9Su2DOcS3ojWJWdDFYcV9EWVQJ/YArukPKBVDb3zbr7xvvVK3evaKt60PdM59j9tsaeaTNX6l7g/N8V9IyHUsDx23m90DG/ap3y7tzI7cTTMOEyWMWbwuYpGPfYRRHR6/PRUam4FAcAJ7sz+xplaI6ATv9n0t+7d9Wkb/8lQxsVs74My+D8RLyI+68exvIlEJjfIxaBy7YTlHfNP9FrAOQeLB8RL3IQngqjtfLNnp2uEJSjwCbxt7aOS6K1wJNcc2NJSuUF3fyIZDMl73a9r/0QDb8M/0SlURaduahiuAQL8nnoPzbHPZoz1x5+jKD9fK3N2HlbuZW+Cyyiddn1uORvlbmE0xwMHtHLDWddbr3QQa6ihFL8ZPC64avdw+frhF6OGHkau6OiGQXXGsIw+4uL/TOMlqx8sNIAGAfjzDHgANad1x62Xdd8PfF/xzH6w2HfbpXo9YVKmPuCVRCgCerjGGrroSxq6r2HXOKR40/mkwCPrkL6w/yeCXdkM5Bm6dJMkLbLTmt2PKPkSwtEQs+J4eG77g5TYS6RLwyPEyxeXrTuNUoiC+Cs72NvS5YRdWO/xXKtwASs++xSbpgV1K04oTeQa2p7lTVSdKNAEyIcc1m5yId7lN/vg0XkyafKJzqE1rccOCIyM3qZ/q404y5VnS5jRSkOCwGC+CQs9iUDqxQARLYf2+DmOYt3IPRSYSQvl+0ZCDmYeGFJMNGTRR2g+0P0hwKII9lZEl7gCMCg00stQcSXgTPjJorWnHxEhbJ2bcAOO1Lp+/P+5lXxWcwnS1XrzsN7jVaXfaDC72BECON1BfjAryiqOmklY7jGZe8ewi8N0Z1WNSO2QFr1M746YN8VMAJTeuDbbrX8/Frb7yw27n8DD3KYps1v9naAY2GB7w+ziKk9CLWXQXMxAHQeiiekBsNeDlF6Bsi9tLeUgca5h04jF9oOZRd0KP17vlN6o/nLM/MLJKcjI+34DSNriNDdSOClT71TGBkF7P4+58ACRwsCJ8Q/gXk9MNuarD4KA7QrlcmoK1mTHcMRD5V4LoBhuNXNBxTdheCh3jvsDM+nUjhhyhW/UN9RNbS5I/ry0xz4qc0/TUFJzTh+ZI1zLAADIM2qJX61ULHkvPN1HMp1h0LrSBgQ1iq8HLXNsXwZKYUS9EKKw+tJtvcQBic9yMbFybI4kOf9CIfS4xu7JBAsXW0/DtmiqxB/75Gm9QrIo5vnEMAYJQm2hOu+NMgOw7ZH8onJkpQFCMMwKAbvfqlUJRv0CsG85J/yz8bYTVoh/ZK1nznDubWhQJRl+y7/i7Fpgebea7Ybgpo6SuAYMRd6mi0ylTcCqGCJHiXIxXqDOIyl3VLIy82kiM81BZc+2EgLhdI+ur15lfIFyeydcPwlChGlULcrWbIA2K7czlaBUH/no41ZKEZ33Xhq69TJr1Ogur0SOXhqQzgdsQ+19y7NP5ud8d877odzuO6VHrE//wczk+hbpmhmmoXShTu5dAROTWybzSR6ujjJSruMEfDTpN0qK/3gDTlC1VXpqjTUmrXWrdPgywf+PLMyhnhW+XVaFLzQiC6blrmxrzrJ3QUzQFVwGtiCUC2QaLEiAFXLePAZMe72QgQQUHSz/XGC4g8JPH8igHtb17sRLaHpsBw2/INWG5Evo832FgsO+XwsX4hcxMHAcxKWoE88y6XZUrF1BKtx3fmED16mRE+2/BP/zs41NI5mUUFua70HZIWd9KaOSXWtp4PRnM5aY7xLG1vA23xtrD6j2sDo5+dQY00A4wZav6ZMYVWYHBHnau6FXrV2p5eBOQInvadU2RU7zb8Q59AaCgNWOkquSM9sNMlL2G/gn4HKhFkYhBwQNNADTgYQce0FmwoVCeGgHtw0KEPdUGadgo5byjDErqhk6bQRZmBJm1gQm8EvqIOSb7DV9DdDrkAnsBwOJN0pXowU/ipMPAyAWgycZ5qGVD5iQssGK7z0Abehi4cjDoRztVJSy0HyRAzXrKJBye3M8NOOTP2CaDulydhEZAZL7RQC//icNOAAkShRAxalWLiYeJaIjJvtdjvomPuUF1CuXncpuK4lUNvf3rZlnz7vYDop0APTX0MMK917AECGcMEcf0t9/U8ZxQ/0Py2FjdT2IySk/LOeufO/42sgztf/j5cHwKmdEXXgwg8+Vq6+KUJu/bHemcpcVXPoRAy2hHBlTDoQxlYuu2gNdvWpgItODn02hTRuiB7X0D7F2Xv14WqJ+dfPv66fnV7Xp6nB/TIPumyhhKt5qBD+n77BD+hSDy0mPmU9LUVx/Yqv27QXw9gh44A9P6Ne7G7WzE+MRXoq3FOmGc14D4nSXnuCENtnIho4tT5bv2JaGmnkGk2XhvFdBqRuIojP4GTumZ+Xz6s9kP3xH9vvD8NHQ39RLSiu1xgRGQUmZ4sIlUcm+dVGyxCmejci/7Y+Of3jEbrgBk1OgzFj5/moaqIChkeabjb0aydZXQL396s/BaXu/bp8C+HlUCQTo4BKX4lvBvvwFdtTX8y2iT2WwVACsXMMvFbVyjb0tTGYStQghuIOuYpQSs2IQvmElD2OC4z1jw++UPSw9lUXRl56VIVka6SANv32gUGvYJZv1XPw+PT6ELszJQYggyqSkZ2AD4w77l14x7FtlnByDqe3xB+xtjd5OH42E6z2dvg/VI9V5uPPsomsF35gr4PxwJIS/9+5y5bHCssw7wKLZ/olfz0aaBCYAEjjhYHS6QSTsgwihOJ9qvGSFRu5ZrIcrHkWyGp4NXLwCzFtQ7JCM97rRwboxqjV3wLhfPjGVEeZfVprzds0KkK4f24gZm/6aoxzdu9fCL2Zt7rYh51jKec9jJatvQGer2RPYzDKx8UOE10M/P9Sxu7C/C4O0Y+5YBrXxXBsHEECVaf5aJsHi2QKFQJ3BwoEejvxklGIc9ja/OFLlBXiG/bClSpGqblIWmmVwPM3qBwXwRk6N4v17240ugY9fkOUeabwz3hvEyRxWXUR3z9ewCaMlQaDHsaim1drhKk3uzyZpGjjXEl7YGZdTvMbJ5N4NjjXv0NN/p4slxe8XDfp7GwRqtCNo+pkcW6XTflwqn9nrpqj7Jjf2QX0q5YqwXsfRYBQLFuedPN3c/GM3QccIDwWxJN8UvpyRlei7nWLwNw0pB7FVIK0X6MlpYpIs33hy2VKbk8OTkCJPdyHJP+QjbANlsg7Ug/H09WKO3ZXPw2Cyt43csQKVNdPhsEEwDBkvotHOegdAotLgGN6O8FEbmYlqOTyxFbK9hNdSOpjPd2T4She3cn9XOGEWeRV6d8Z3mW4KWgOWJz4xr1RxROSta9DnIHW9YMbQFxt9Yj+yiLIs8ozg9d00GntKnyud/nzWF9wxsOOYaDj39qhVBr9/Db6E7onJggdgeDT2M3iKsmmgdlLc+DUAE/MpY7tqTtEp7ZCBvwmSzCby47kUIrJKwE4VviYTuES1nqLeX0fAuxZ1n28tct2XBKYKrwowz9MLtBwsA2JsiLkOCXQDoyUXiDjPwJgNWgYBuWTR6THnp6LBXf7i8+J7kuTzr6pRTuSf7P1B4e2gD114zWe2Ir/fw3uq13WONJg8TxRlN1kdJtTw62200s6MRVH3lL15Y49sPr6/Pt+fDbC720rc5xzCeknhGn6VeX4+IWepuLenq8+JK2JeQjaCrQ4owAUNSXBzWdA5jCy7HVDXfztI4Qianebbs0XVlqmm9o/ArO+LgcIlLCe7GAqw1qSJDNa6tjDT/WPzJ6crd09cuoi8j3MUHLwW6J6KoA2REpHgSqzVos93CsU83iPX5LyLe6TzEXH2hVZs6f8r8aXr6ogo4Qf9Lg1Sfq9YB5sYr5cqMPOJhJOeJu91Z07CZqxzinnPDFhTc6WYZ9wZXotK1/lj5de894sCUDwnPtwI4y+i/3Z96q+F9+gbx1OSD96EdUeV+0BBxcI5/5BH6dHXBI5NI3Vnh6SoUVBB2Lhur4QhejiD79Py4L3OCvGv6TcbnDRM/SRWsaqXnXlbMPBdtTlwosil58mHPrPaHuP7o0VeOKtnoTIhwsbvANF380zwpg+cZuZkLGKcPPOB7dgXCIcCCouHfa3ynFKyCR6C3GNh3vBgNocweipqTBHoKVCIVWXi/RKIHe7Q5K+XHTjg7cVJQ4dPTPDPOpb5mNlPJFaHuYg/n3TqXE/FEXp6ixBR5q1+u5WjtOy6qlTvuYbfesAKbeiJP9Bbapc/jr8gonCcNIjP9J/BgW5dcZMJOcFGnKeWX4IjOT3ywZ4FiOpHMFj5UTayxoycJlCrrXSqMPJ9ONwELI+oln1zBxP/Eu4OaBnXSJ2sGC1c1Dyslu5xywQOV82o+g+3JOj5HmVO2XIM4FUtq3GkRhL6gm5VzzrJo1RB3xOFyroiwAgpk44cE75uONxYKTpcMsax+io7hOgQMznAMSjy6D/Q3PeDdlEW0c61qErCZUgKl5Jk3f+db3mlrGJoqYYgvp2pEwjrrThNwGNyG+Hj4nFSzU0w7artrQNTEINFrk6+Kap5HH/qiwc+A8HbtO7kM3O672E9xQ8v4gFtxkP0ScDpodK7ZmM6t93uejGocAT9LNBsjDoztBjTvM/ptpIh1b5JffLKXCGUMezJv5oIWOY7ZRUheMUxra5g+zrpN19e4hJXV5XkWf2O0bZUzuNuKd6zsF7q8VxCVd67W+tWrm+Im2kXXd01dFhjhBzeCu7pYDEuP83JdjtkrWMqWRHg5DQ6srtTbMlXQZenGfCiDhlxJpMkd21JzCtMxFq1Ynu0ULZCrWw9j307d5JUoR40eEiV10d2JoyxzOgR8Wj8pHIMJx6igWqljaDLRUmWkbjE9bNfyqI5eizanraKKa6FxTGCjQlY1OJY0LIYC4SLDAEyoWzQ8wkovsKnzaPTgT31bwNAgrnGmswt9DocWnkmrsNCgNmOaxZAuQZuxuZ3ZpfQv09JmNH5gLElgMUofs8d+O2hTqIlq2/Pa6k63ICak4Lc+OgK6Wq/HU4BBaPxcQBuF4PWc53gu+tq4ViX8iTjKEkAMz9HWcBzQrd7hm3sukmNBtPdJL2RUFkafBH/q5ZI3QXjIx6AgS74mo2vJz4942Pv24rRd+3gYrezLnJH0hAt653M+UEigiBAa+/VED3+NW7qTWg5TYF5t6zQ1p+lLLVeah8AuTEDuG8qagW1+oDEZaUXXuQPHFDW0qlPetAkgZ4h+UeCroFBzuOw+VooAUAMZq2aG4IBSRCZQ19XOMzGdW4wb4w0sMOWUK3SXJGLVSLPYQb+vwomCLDWm5NproeItqPBb4nGeW2zB8InKSNaWdMg2sJ+73wnmo7lGEpDD1ebzsVHob4TisI6cDwZe6Bj2hlU4Q1vUnCrS9bxnHSEMIOPIDXmftBnuQEQlBIcrqQO4A5UEUOvVMgS5hFnYAtG1dc5RakqWBrZ7Va9ks5CZkxQGC0DFhy+RRX79J1WDEPs03ZwrUAkRI4HweK1UEHnBEf1FzN7awou6UtgnOUxVx2xbQmOGxgkbOWZyatQM6+XDRfsH1lwWLCZCCDBDzt4TIChIaIHVTpi+o1LlHEZ4EC1XnAFoGRP/bwO3sz0wV2+Z271r5fB7IYh7E/92v/SwrIuOYE9BKcRXwtHNnND46EPRWjsrz4VLGqVpWvUWOP0XXTd/yxVkvLIi5sp2T2tWk2mWB+zH8are0RjHeQDDLxBktNnJU8ZXGB11gJGC295o/kBA3oRfNQHH78IRUP+9sMG0+Vh4gWuUDfjuepQe4odvH5YtN1cANt1wM74US2woiYL9S4ze3gGhSh8qj8/b4HSCNnx22KRLJZbflRTV4JJNDkw9lSfbL4JgqSy6946EZdZtGI19WldkuSiEHSvQCKyVCaAtUoWmQCTk8a7QPs8cekg0qWmNZKYODYoxsgA12bVHGxCERsi12AL0h8dNGZcK1EAwVFuiekkf7f9Rt8wKENE2kolQ/WMtEo0mS1QX9LarTxmM+2SkWEUbBTFEFIZwWFdJNMMNTrt+FaJaQlr/OWz1UGkrq7jnCm40sjcWy/FQIatbUYVPh7ym7O5eqpjSyfsl+BQS+bkj0+nOh6ZchsiL4ggmNsXkmZzWTQjEiaUAlKjyEjcAIimnuYKgBmvUyjnbCWdjB+bCcb9M1TvXIQac52W/E7/B6+ILXPRkyPRA41XOZUMEp4NjUEvUYfI4WCVfBbl2FitzvgBnY9DKTap3jt9BdkjkM4aKnnRlnTi+m8ONZmequzm0bGM0RgRKRFEXDWIxJQGomvNeXyNiJKVXMghtSLSrpd5AvDDS+Sgfd6ekq62CzGav8yKrqZeeN4daRwlPXkoTN6ul4afcFj6XS1edn78Qkm7wga4TlvXMNUoxF4WeQjiLMdqUi+r5rVQH9gqbIrfs3r3Dhs3MtWdNn+hGMS4Tr6ZcWh/tblpKM3MNcds2zjhWd+N6HYZ7C+h8/WIjFojjXOEzjppooLcDdeJorO5TO9sw7z3TLrT53LIRGapdRGjFizr0FQz2B7KlmZeLPmYDUOjJxWgaN8tdQ9lVuwr8nCcoO70YDtyTh8NNfdc2i5/ykxUmnKg3qelkT1paQPI/ptTXtmiwlJ5gCm3k+9o2NfoXFceSyMjXgxw0/HBqYiZYrCo8BLLZPXu0bOjNYJ85r8JU8CLj2xhJoMqrVRcWE4THggoGj0FwmsmTc8Hkfm8O+LJFRt11U6jzegzlEn2WHjXhcppdE1nBkx5QwuQNPo8mYe7rOTakXYI8InlIhPc4kpaj6CDKKQ+gh5HnqAqzoHsHY1SJ1L7CzV9n6KvX7vDPN33eIk7o+hSPD+6Bmfd3G2AqGLUclU9deBRqzff60XXf5kxIZ6nNgsuv4nILQhe4ew/plN8hMLe/4D+aAa4x86xrKgn05k/oJ/3JtkQAAq8Vb/O9NIDa8eloo7B8tiEo/wQXs/0v4Lt7DQ9jXzin8I2DBooyK/gpAkjLX6iwjELvKa+83FKmlxdn2g8LyqfKf7JK1+gkIPHaaMDxKdJQUQXTSe1CRU4akEEb6G4dGQKmsFGzJOH54i0ohStGYv7AZt0hHp9tOx2ba11IrwyxW3xL8RwU+0rkT1U4JtldbM7xTqturv3ALq071QE44aNrvfYaZWcgk6Uyi1GyGiOWcls3rWvBahZygesxYZa+EArbikx8QgwmlyffrObJHoYDlv1M52SxzsJEcJ/IvSWPpwBEMgZajQYd4fuon59QohzM0N91oQv61F9UzL0SEOreGHEF1EqRwsQhif64nMGaQUXd+9VH9ADaShtkOH+jkiLymwnjmEQmBeRtvypkYdTna5zG2zE5e+jpyjuXSU/+GiM8oP9YRdi/xHJzxmdSZ5OJ8XYG4Qi+fAKmBN6F5HLtfVpXeVu0xkiy7JDFkCb3HSqWUitrF8oUgs4KkC4IUZB5VjNQAcNTFeybD3uh4QlFmje2SxCsyqzJG0ogR9yqVZ3wO/83DA7dr6KGxBirNroTT4gRC5R+w0gkfIA2RMaNIsME4qkWPuHIBOny9GKJfVAuz1wHirw2OFOZwhSmwGDwjF4sakLphlNdCIIbXTRDBxh9BfLjYNnEgnWU7v3U1AFqZd5Rr4AXvmOwrFPuIBRjGVOHSJNIWDFDEpaKjfqmF85ibipGk5ULmkNozc2VL7wSEEi4SIAcXLpB7M0J++ti2GCz4qPQAif8LGk86oZp5ljWFOGtGmFb1gMxukgzKNIAEwkV/ShNttGQw6bZ1YrLTAxizruKDbNSK3VgOgfqyAfukBLfeSHUrKWtress0WQ3FLYnR7VY6WsnCUpRgbOrm8/pQ+faRuveu2irVW9ixSTIwt9USVa94wnWunrlX5Tu32J6AsErZcwnBU5HmNIubDW27T1bxtso0pTvRjzMVxL/zIq47Op9AsBVXMRpSpQ53/ZiVsqY0lI9gilt9CJiG40Cob8K5jdr44pUnoLqMBPrMV93KkljrWguTCrSaw4iFB9exI5q7GJQo9vYP5jyNmvFdXgO7JbB5ZZb76mm/WEZMqlcv9GzaxtOGfdt+jEej6B5D+BBH1HeGnWf3AUWnotDD2tKlbHIfytctVg8w+opxRNUvCdREXW8sULlVlSkiluEdl7DiFGWEmLlaZqBrbEqMZCniQPwDURkeN4BEqE7DIjkGzJ6Hgej/rjCAklaiwdfdqnqDrM8vV2zsJZo5a9HavW7KAzLBp26H29f0ovEpMV/dTxs0HSfknpNMxaoDKPDBs3POU25MVkj9AKdLUBu4lC9YMFSvei71iuhLePyep730DYLIK7UYFvBeYUWpZ00q/BfKGWkg/CYLEC8ms72XvZSzOeqWQ47t82cumLuV1k0BhZW5qxGk8Ts1dHMYZI19zjhkFzJIFI+DVHH3rQ2p4cJJ+W7KdavM4YqXO127NIVXy+wqwzIglnn+hSs+2pJ/pSuQfTTk/pnuCXCuZ2ZGunegifQawgah7dhcTtDQMmUVggIWBpVFH9juK8OHhF5KDdR7lOMkO3Shew0uMJqnVHFQDAjGTUJj7wgqIf9sIkfTSwGKnXjftNsdsjHlTF1/qlWS/CIxJMGRLh0AoMjXusuxqPRPYuoqq482AKdy3BKnJbLWM7GqPoA/PkWVGiEw69+3iwgUTba+3o9JUTVYqcq0VbbJOmOaeSSRa6CSQmNx/knm3/dvZ6N0e5Wz4STywPMit+ox/zdc0z2FtviVmVHNCEPWbxHQX3WfriR+doifTE8pxW9x2t5CwVQGKa3ZWFIhgeHetLVN3arGHR8drGfw/T9Qob14mmUrf7i0Kq5Y6tGGvgQMM9ucvnSz52keHqc3p7fjlYc5dGuvt5UW/pi8TB79D8wRW0ShDAaMm016pdFHcV7U/sdsti+hVTI2n1YOjGeYZr1qosgTk89bGH05zzlnY7yPTp0ewf0jNuw+FE/1mzkhXBvCaAHW69DFtx/+9a8EKXIp7ANYvjCWEfz0pg2rOkxBLrYsPszOSDskHR/GaEFhxAT40Fmw/2RO44Sp9T/mXSUtaT8ZRvazTWb1Txvazt0sdXWiNnxi4z1vMdhXU0c0h2QGZxrsHccouuZ0+ZL1bNQY3KvmbYOy4g+ee7l+CrFcuk+lYdXEKPPpgjpWeE0eeznYexXhJVZlINGYmOwdqzKQofSOhomGCATvLVWfpS0l1tbQqf1Zyi8b2eGNLS5S3u1xoCGAbdSlnqyxFvbystFGykvxv1R0ywGSD5BHmeeUBLAnQdHABgwqKKRMzFurG0OjCKU41izn0TOSfv54QysKVasv2F6Zv4xHus7WFvd7aTFdhd0aR+K1oC+6DkZw9kBdiZrEWtGxgwTFucjpUFT7APoQzL/hBdGZMVxeKT/YEA2IoZ0nPFzzQ2SEuzvFhFUjUFvdmzHsph3160LO9zZ/UhXfjSxGG2ZNq2FTFuE4g1ob2Iip1OS5Rw0nKw93aYCwqzBmILT5qBw3kKFGA8fi4gSKoMOr0ePLREiIfFfK5zv8pXhSatusNaIQgQQ3DZnl/DROqyLbIQoahFni6yIsjn6TYPNjZKb95YmzEVnbqFPHrLAnAVIMAJv2+I5jhXOx6TvvZbaVbZEB0c/FmHo0CkyV0LYXm7lQdwl9DEe70l98iM8UNDzRBGYap59GKMXUBgb/UH2TBK+Z6YAu9R80IDDjIl4l/gXwuDJT+ZD4t1R9szsnghe0Lcm5G1ZHKCtcrJ5SwEUyzxxKd9C2wTFvo937F5BKdmAF7AewLe85aLUBDIapIgFqjgCGVSG/kJMqdiWQqhIMCePGA37B0MW/QmSDUQvejquJx7+DxrTHZ8hC8mVftacIGBIuimsAFweFOKWMmA0jmOex4uahoWMi9WyOpPOEOyboEPgmYQKCesdqyHBNK7X6niyyOp3cD162G7MbGdvQN/P2Cy0mtULj1iIu+IbAV1sfTJk8bPR0OVWF95hyNd+NbXb5sWIaug/GLrIkJ8iDeMWiGK4C4PwIGLEmxmrgww5Du30gmahnYcL6mJhMa6P+AKLPO+KDsPk1CxhokUJ8NtBMLTfQITRQBsR6ZF9l6OR40dsBhBVx8cybmoMl3Oidx24KTcDU07boRXe6qLbWcjMa7grzcrRPH1IgmET0DRcwh1R03rU+hauRjPCsQfqfAuyPWiEku684ZpjDZ8ednTK84mp7kM8P7j1inpnZYsrPJWmu2m2s+bMfRMSn57No+iKHMN14W36vCWy8xIESTsXJ6nk7hBN9IgvnNpyDTA8lYgFXH8s9MZ80tgMFsAU2Z8iLXDNsRxqf0fmsILMI6hfbG7FhyxG2ibHRTBk23qOAtx/tiQoCcHnBXd8LlJ17jr5UzmLiO7uQvmnCQKZ78bd/jEEHa7wO8OOWxluHxk/ilxl1Tm9glfrvCT9CYquFWFuwEUmWCLtL8cx3l0p/O9zZhHn8u5XTHL+uAu5XfD777AdLTdKJOqgR17cdbvPN4J0NYxAGJ+HFTTLLYZdUFRsLcuUKE5K9ZMCXELSubIvgcPpqEe1SWGQy9rmjDKoQTYInfxDrEeQcg9s6hqXVW4KQ0myagl/hh3L38DV6QSPU8dkR/tGxaF460NYUFQNRYOwJoa4VQq2jUXXZZiangFV6WEZs/iciPHAiUO1eBRmd3g69zRJOZ4FlwO29gkfcPLVbUclPRz342W6WCMHNXgt2sBILYZkfAfuWsHwZ7MQO1M5ZZhCDZLLABrit+PpVop7CPX2vb0Nix/1CquRFpV8ydRKKPBl9hsCIt455IF81hZTWj96d94VDO08BOqBUZZUn/3fq9R3I63TicMIRSBiJB6uBEdN8gTHSM1rKo7oHqAokYkHOjIshyk9FjRMURZsmdOrvNPgbzO3srB3skkwfT7wCMMT8DryNsIixLqirI5xhCJiP2d+K1wxspEEs5x6bwCjnNxS9UV4CDDwq/N8jXAgY72OMfc5nfXoq56PWFa/BpsdzV/0on9T1BOzmxDMkMolN6hgKNTDBVuA05Kz7P3BPYHrRMWEQXHvjLJQFprbesnnhOuJ18WidBFPTqsgTrLaHbC6bbBtvPAmaM5H9+8kcvAVGDuA9949T+S5agaQ+wh8fU3KlcyH1wiF3YVfhcqBrlEW5OgVI1U4RhEtW3wuWDPRkm1PaMQ2KHCexDNVmWfexFDGfoq2PZ8/AXmQd7oB1no8UcDGzOA/l4MGf5ewOeewHeDIF9SMR33avx80ORhjfXm/pPpIL7uPG6O2NuNa3SrxdTS0pUO59hW6vwnc4IZpVlCBoims7XguDRdKYLtRQBBrAK/AMxABxp0SSIB2Af+5uvtbRMD31L+5jssgI2ol6dHvdcG+pKcCu5UC4ibzKXI/hMhwjvP1VcfICR6oAn69/ibCjcMsgUvXzetu6FiHGIJ+1L8NhHdgdBOraM2fsg8CH6IE4si/mOM+GfX8TdLEdisT3tDQl5S+APZwxaVHv9cM7d6CnsUhs0k6MULF01SWweDgB6yDSD3toNuXCNbAO417JHblbl5Ahyx+6+/1bsmHqRYJlwPaJIns5i0QvX2v1kLtWvbjNWfG2RpEzyx+FyDiqSnaMTc28btA2NzOYbo4egVEztk/lwuVOJa0EGbIR1vfkm7mgYa9p5Gekzbpt898x6mzUburGyFAi6CUnkzgAHBFH21q+It010U09NNEtlPx7q1HlRQRBQiaBKcrg7hhcsmfgtNFnK6OaGX3rqvmAoe/LVta2AkeMVm933ux4Xnvi+g1BEZe3ulJXQ7VQHHtlJ4Nhhn7pnTPaHLwEFm/jgCWKpM3Wl96d9rza3yws1qJpsLQS+kpD/+LXQ3quwjFH3XOaQHZld0qgSlLGbtvCfez09oPU51uPMJQtjwMCgzGBvnp6MxlDi/Hg/2Ydl3rJUZuQuUsR/VYO6iH//401Q4aIMrrbslLSLiWDVAkDUcZlO3T0WoA32VYW5OtrJQ8J0VUnyrvgusqwlrYcBYooMS8L/298Sgz5k7Uh/TuyHO8w216mXEyTd5X9p6ttd6aQeho/OcSQ8cL+lC66jndfIetFL3Z404QJMblElFDJ/gvpld/T1bAmh3WeB4rU1jNoY9yLDHkTxqpj/v37EsSx8IKf0pX8n9/7X1fILLgWSpzIbP8qU821ph9WgNfvpks9brXAU+CPc9KV/0x/dnXr9G5i/mBpqDe6eRjKAYB2w94Lz4IRRA5706bB9w5RdKiAi26bhr6rkbTdnaajwfJXIgWP+ZRlD7XorW1lHoDFrHfxqFzCTPttAuLMPM2fS4lEjpN9czH6T0y42LebycH6X8JiFdRFhxLMHtcZGzLjIDd3PTLSGLf/MiRaClarzQvgufoSJlJe6PqyTcY7H1Bt8xAWyJ28g5e7gwiOVpxK14oaVkZsidkxQsMd6kxQRSVnjcfa4Pgs1SkrAdfLGYui5BYqkTDEeanG1Z5OKXVe22/dtN9b76Ua+5OGH274IDDZmDaSFNP+lKIlUzBXJ28/RyGoCB011i/ELxe/qgaDZoUiDREh8MQl2Rcjz0dF0pFHdW+G2XSXkGnADMI5Yr8UWEIsLmQUxBu1tAat5w7SNudaUbRjTEdAYIt9ojJA3N6RZC9/Fj85Tuv7fMu+ZKCRhYRVJ+7hxWqHGrYwvp82NC+2dpBCxRTtRjhz4rjojVSh1Wp6RfDHm5JFEyseqLf+1eNGqXy/3/Dm9OywYWaBh+BWdLIF392bBmCqYItVw8cJUfYEhrJeb2NbDH4LhEyyBMPRsdLfpEF7ABbap9fHGaMKRHE9jQbbIDfB5hxjcgsI+gqxDnv42whdGPt+drquedkkeHHLdWe0Mc+e55KBBkXQWcnGFgNODxYC3pUz4WyYjGOpc6V+7nAzWVFke+iSy/2+SUKkuptEbqg90pZW4yYuNJ6W8eg+6rP+5eN7gmne1zWxD05QDBm35PivE85rg961+QWhUM+Hek56Sf96KPMZlwuvaGDc4emLgjEuRSQFZq1qeEvf537lTOqqJ9DEEsFQYe/9swnn45V6afn2CVtnYlcEDRX4LqZpLripHdI/i6VYE1AlHQe6Kw194VUbbBRB09eBMrt6PznZu6JUZ+rkQGO0RZbyCsYxYtnLfULDOf743G507/f6f6ciV3SGMuXVC0Cf8RWf8zeet9oxx1L8njlEZ8QYRidmOXUFKwv6NpsmOYFOe/EbsvePQ+ycLungfBL6LGtc+fx/gjW7sgAY/iV223PqG9fPjxu59PxMJh+L/ZVQTvWwWS1YYIg2dKyldMdzOERlCm06wtxjg3pkKz4d60llIvaLS4+5mmO+3HQ8vTf2i7OVLtcXZXntodTw9IXUt/f9bndnjjJV1ujgWKcHB4ObvGDtzwDy6fXz4/bidb6b9oI+mzJxyhJo8LpDiVVRs1VaQMRNSfbfq1nDxphoVAt9MsarmAgLiqYYrEA5S1oZZjHQTPdDnyzshsJiclMVMJX6tpfpAqVGciBimpxOlorZFlfVGGXOLnwevS3a3eVQYy2Fy6Cl91qrjChWHhmJOhgcGv9wdotGqxlsxC4zhvwxViAageNrPQU1M2KCqbBgzvAklPycV2WjPvIWDO6TQev55nPKDGlcqhW4kfy97Oy9LAsVqPTFEySvafgVM+6D2C3pMe/DhludklTZX3e2znSSXdQqSkJI4x09XgtCrcY16vmI0CuyfIjO0hc72a+IkYeXun6qetTA4bC+X/VZKTgEwaNEtdyb46kruNsp0GlVtmlZIJ/liGM1YxSd6PspzxLt7fpVnnkUZapMD5AldXgd5J4VRkYwcc4bHSOjZY5gE2TNO4GukGNPyDNsNaGKA+Z5iRC9I69L1t7SWdeaIMguv7AWGkw6lpo3GrgAy5mh8fDCudepYvod3Pvbh0jx53ufQF5F16Kb88PjDYKrVSfFQ5TFv/ClRxUoZAe9kpQhXhO9ds1Twvfnrb10AyM7PYSD6/ZOU4CpF2nS9beAFutgLKymZNAQVklS42/5eFwnI4Lqh1lMC2ji0l9n/k2G03V6hKlK1+Y5VNzC1Q4DbNKWZ8aVviD3RJVOVsVEkqNpggJjLE+4BjxqGV6CZzh4VxPLxEX0cf9pM6HYpiLqybPnt/TnIONwfzqP9heWKCCwoxmpLb+AOp+WE7rvUFWwKMYjIXxhzbvO9aIEwOglb2zZrRs3G/wTIZwb6y0h0jqtqxC8WbdB5Qw5RT/KUPv2VhdPxcroFjX2gtC1zatre3EQq+ovYdcstuKO2W6sfu02f7qrbflktZGi6hKwI2wdZPHPZR1XId7LzINrS1pHmd9x7KgSshNU7UiSxb1rKacqSQg6qJON1YP/9i4bAg071wJO9SxIi7PqVERb5+yjOI0BuO0Et0o6d+cLmLJznU9X6YCbKO3kW1Ksme1/EP9qWWE1ikSI40gNooLW0cryO4QA1VobNKSHiXU3XK5RtQs1/QTzygiab5bKIO1aWMJoSEKRm/MqOZv6/OHKxDb6+1l+9K0/4hOCpC875TWre/Sl6ZKoaACet4mW2nKEGETQJkJFlGXdiyvgt+HWUhLgpafoxr4Fwr7SwKRHoNaqXOBVVDqd1njsu6+6/l2SlTRNgHcQeyQtB4az38ffa32JNCSyuE18EeYOZ0L0q1i8iVHMpaSfXQ5gx4HX5q/TedotQZie729bF+a9587qI6eAF9XfYAvlk5aRnZwwPCwnUpzuxf5cJYOFd/F+72bti/zyMWq642Q+tUjM0lIJ2oCjFsFzNcwcLOOypy2rDUm4nvfj3/bWkvru2OUHGDDSdnaKN8Q7Zgv0v6b/vmGk7alT9wxSn7pdq6XvnQYTn82vdFTEuw9DG7qfiQhc8JnO+pjePLmn5fssM6B4u7AJDHglIGEK3yaqq21zfxrrK2rAleNgHRDsEH4Uj6h0seWWfbInJ+CiKikc7YNYfL8yQjhGaNPmmB4JS95xW3dq351BgV4B3oHssPSnlB5Z1Hl5jvrmrQwc13O41/iL2VA/bFOzkuCQwThS/lWDv/J3ujmLap+0IFKfvsGAgDk4BA5murNSKNkLSMh3vtGllXwUpVEOwPoV2de8ex473h2dNoaBS+zhb2y/vj+zfPTY0uaWv0L8Q1aM+LBZrjhvrGv+oO7mm+wLHHs2vKmiMVWzH6OTwtwTgOVNnwRNQFaJIbc8QMyWHzxYhL/8Hz+YQqGn1I1+/z1DYCNODI1m3VUp50e7t8aA9PkBjV5/Xjw7YPHw9s3r5+fXj0u59MRvTLyYJewgXvNylqeEHUfjz1oRzmapD13ib9EKDXLQCtShfyEKJZBVEQ+s2s1gH61I6W/PPOOZ8ezo9PWKHhFrPWBQYEZLgih1FjRfQwVX/OUtuYz1D4ly1tEHBekMDOa8peNgNZ/IjSatjYDG7K0aQu2IvKSl5qXbazaHp/61U6Q/vJT5lh3GjsppyNCXr6z3Zv79QJxq7GXAVL0UmYnsNZzVve7MiafU+VcLrV8b7+GXUvXEMq2H3iFDd2k7QYWajOp2EetCPpq71t6ZPKSF7WEYfzK16bcOfrVzpX+8r8JTsvOB6vF6bd2/nBsWvkXQ0Br4UR8u0udW1sl+4OPNnD98uH929dDXcKg4Dul83+L+4rULqt7Tk/OqOYUlZyNs/qXye7TNJ2bf5bAzDCkJ6HWbcjbFVC/2vESNez0xbvz2Fk5LVHyIj8oAIedxi5fdBS5AnOSTUbAAOEz4lrGrHaYth6dO7i2sOD+EW+Isy1h4LOrDCGtexWDRhsB70DvQHZY2hKqmBcYK7NwvzVne5Z9JbiVWpZUcFd7zy+W7r76F1S7oMtT9volqytlUFhiswQZZxaYER3AVUpty0hP2S12J4Wu7k9ck2bLNC9dyXgrolCbAehXO1P6y0+907Hz2dk5nUkQsF/t8c2nD7oNj8uvz0c1kOVkAh8UyDb60M9WZdIRrjrhSmyW46OtffAtgpI3f4dAwVsHs/3efrY3LYXBM209Eri7Oe5Fx0ij0sxSIkL10J9/Nj+boqnxKqNxVCuHCrUp42fXOBSfNc0A1t4gYuhqf1w7wzuDnZEdPxybApim6bPwLGAZwv9p/PLXm6stzK+hGC106Xeon/iHb55kHW2NT5KSOlJqcRQ+0kDLW7sRu5gkiWbeHp/61U6Q/vJT5lh3GjsppyFCMUk67sf5Zr079YBofQFaAmwbmp0ylhHFulvCt2Y9iG8tA9lubzfbmVZC4Pk0gXx8kSl/MQqZyYPbwyedZGJ18c4BR/iAjYxmbwurVRDb6+1l+9K0f3FwcPkgs4E2Gi8TRhccNspnrgj0fZpV2wD7td9xaia7fb1SF0DYMaurHJImhBcFwzmSQtxuUMbVFKwjcHPRC6X0gnZBoTvYeIZCrwbg8X3LOeJm7du7u/jTSAYCTjk/pNZ+vuHDeIp2XPgKdZMz5gd/Jldup60qr8Aknqepw6SAhckn27boX5Ci684G5dPgstNu+q22Xei3wElDnRS9VwMnlZM7UUD/kEzwNt3VSxtcduw/Lz+1QIARQ2CQm7oRzjJ44FIduiyyUCm7crvlq+blkbZlUOw5wUS7g6T/efUvpFYbQwKLb9y/36prOuaT0/SYH0qbgOoFjpp3dFYVVqA9t5IvLyJRC6acWsPbUGAWRtNPRnbgGlmOLlD8BLQaGHeaTNVdl1lfiPtjroy0XCuq2dTboiCbkn9euzbbpKnNzUmR5xPvI+ZRy7rLYNvklSSgVKJwgO58w8ouShmC08BqPhbfJ1AW1d/zvED6qGPcqVsfkNdwPuVmgf2i3q7YYJwEusLnObiTmzrt39asV9LpxWgBDhb1pLNRMEcGhjNuLDqZ6zulFos4DLfP6Zn1rtbnVJWYNFku/INp4BxzoZaeftGQqXtNAWhYWSOj41wUWTXldpueefiY5iQeqhq6ahFQjaq1WHKEXvQp01M9cLe1SisvFzubbCWw1CyYcY5l/9Gt7zhcJZbCMk7mkBszxf1cjJpYTuOPRNl59l+7ap3dWLl4se0zKOTqjnjEOPSop8kFkq0J4wKXaTuj84atsvlmfFxX/HJ5XX1sI23OMtpoLTlvTNSoF1G53FQV2lFMCzLMvEua4rx7s4f7LQynqJBkLe+UTmimHKaV+K/Csg1KuTQJZ6RR0MlrACwGhZfGI+CSU9GpSHgMBMhZr3O+W/iK/pPAyVcb/WDC3nRGMu58dFi6DUkiSsaQVD2AKgpkOCaXp1yPQjSNb1scF4XOoJJNP9a16dXSB6dZARj2VqIf6rqzBMg7A/od+RozPP9eQOkuy3JacGChodAJ8CFvf9DtQeJG4h5lraRBkcvLuGmKJYb3kebYfx/z0rKqH+Ftw6Fe/m8K7FVHvHXwX1bSNF+Mzs3kpdRNnqr1S9322J1fwsvxNYvWdXd6B3q17XWl3zJzAgNdmToL75MzyyYdKkU600m3m9v1ch5PKc3TWJF7GcjR8q+L7xB7i/9+QxfA2cHIDZR10/5J+6BLyLzaHgjYmPT7MQkJpoE6Rua1l648EDGL9/eBZS6zFr3Lkj5pp8f4ZilqUf71nbwDFqZ1Mh0m/xlO4XzIZbbz+ll+OEqj0tNm+Kv0qu+bsylnSE155mc8PajnBqFxsyqAn3g2iOgLLAa47Mw2nGcD7T9WtKmAi539fBlCEP5WLdAapkWBJltrv9vSzJp7pQ7E3wAQ2L6dWt5ELMfIzhH8PXrzYf8UqZG/ARu4IIefgNV9GwNdzD7vWlRhGgfighql5Yf9fqks3W2HbsPwr0mx4Jguyb9U+G7O5FswgoyWb2EJF8SMd7GJDC87TbiQSz+I1PChLN2uwF8zZz4veQiK+Qul8jTTLafpRXCR0wjkjdGfwF3U0z8/g/4rBPblE3i5ucSrf5u9JzzdvTrs+zZTvKyCfGO+TlfrdS/fpSio5c0mhIvAvnCjksBiElMEGcd//E6p6zVdfP3Id8owPhVlS2cWmOMqB+U8bOh2CoiZfyT4u+byDAaDrmsPw1oP1pQHQxuSizubLU8675yKmQtOQCNlsFmt7s5pMxmtrIqKLxuwD5Fz7YdVmLF/9ghqNWz5NIHErcnq5eux4fiz0XUYoRzGXUie3/fqzePeAqI9D/0VZ8IJPksfyf9UcpJSFbaZFVe/LVSnkJr7osjP+mDDDk+meu/90vacHHW5GLHJPH5AzpToqII+dZM7bf1SKxX/5n6Bg4NWrkao2Ym3MGiQP6z0QJMUNUcy9/Iw0viLROgypaK94g47WASlzHfViErS5V434mAr6x8MB8gJwSWNYRrFCYpvhEkEBDF4IcXas4u6YyB0Q6dKv6mtiYN3YEzWyIgIzxp+3SZDIhziPu5luAFJ/hgfRgEI6DSinIarQ1+K5Wf/xW2WaSmcr5Nv6NcrHc+x63ecyNbgTd/g2a+8JR05ab3SxtV5O93MmrKQ/GsIJUtpdEQeCxiV8atUS9764zyAE1lu6qwz6L7nRGLNmI1iMOtij8wLTYPk7TnNYmr6Mtb1ctddrLRZhrSTnOcoEyR+Ry79dQSSqQRiCHcDuHPPpkqCjGWZgJjQs6TxrHmLLr/LhOI5EwuXOVkslSgMYMhU2fY5yB6bAeIStmTmLzkCsoOAi55HYp9uoWR4iccWT73ZrOu54KO1U+vNo/03eL/8V5t77m66gPYWoU/2GQrTv/h6haFRTLy020pmf2wyWxU5vhpPBCCJsYnxGejRC3Fcj3ZApR9ybm1KKiXf164aW101dGWNZeC7bmO5/aoEYVmvb/Jj/JSvdBaWk3PtMrytaaxiLzp7t+nKSICx/n1G2PR6bmu4ftrgCvZS6qHFNpz8shDr4wq/wTUPyei3z0cGFyNiK0g1TCbuG6cZd7n1bcQhGfs1YSmH4PBOgTqZX4jx80+8+66Jym964aJ4fR9rKD7d6w84x3lZihe9brZGkHl33sBHp1VN3iHYd5u/KZj/cJQkoIibx8dbPEgu/ubecJxKZq7mw5nRO8jHVTbfTLDKA+yFGg9B4i2//xR1o7B+MkOt+OG+MPO5BRshGRXG3mMJM7/lXHO7OTP+y4HmXiV1Dr7mxOw2iphN9FNx9xQ4UFyhZsxm5pSdU/eBo7f7GUGJ9HON07+RyQc6YfH+oxpZvfzxcZmVrQMdOlLTcmWRhHhPe3cqh72ompMyFbaH7WzwrY+tZlviOgPlZn70jeGcGaCj+naiBD4id3C/h8GVTYj3fUzWUhTg8vKni6nLgiLvta1zY636lhmq27rBfnTtPk95+f3+I5LHqc/OwewNIZbemrJGWChOZ283fdioRwVmiQR8wLQltCce3G2z4vPXTqLlMp8p9IyIt1Yj3oZrhevsxwgUhnPFHV6fS7H6+KvaymcN6Usc8xQr4USvooAUTJG4jOddF/SOqNSnty8K512MOlNU2VjvU7f57mPwChDZ/VBLB3MujOe83//CPPFTc65wyG4BYBAj9+X05Ubr/8mZZ0PzCtvD9rExA/PEUGLqjt1oE6mvor14LXfY8BK/DllMeqW/gdddYkuOIC8AU92eu5+0QBbAhfGuIbtReoIjkx1Wuy0J/7u7+/n3xuoiqVLyi69V4O3f/fP5s6fcouvU/u0E/lZ181/8/2FlTaKvZML97XwjmbqPt3dSJe8T2IqV1u4sbVps+uuR9kn3EOCUkylO/gAnhYO7ZzrZDmFtcvPrIwLnv0jzxJlv9+BCamsqjPqi/DyVgi8VSIme10DAwpPASX4+rmFuYTacphv/aHa3ICs+eEQUdxJPr2c5TUntpKqdI7lWGZwpFeLqxR+QlMyyTrKwlJOSg/GbgetVBCOWe+pibcxch/HpONz3sJXbND249IlF0pv+6F5Ta7M+TBY3eEW9nn80P/PIFnW5XJGiMZN6a7kFFzj5ltNyAoc9Fks/M/0xtceFC5x8z2lbEq97jO7OtcvF0x3qfW9jeZLa3UOfZelMda6kCxc4+ZGzYo5chmw2D15b5Dv+8uZj7M5PTDmHFw5tZl4Y3df1djS1a0acFPUm/JphvHnh3GhGfVt+tt9t1n+8f351eXd9t5/02Zy13wfxyP8gC+XkBf960UbTxqA1H/eGam0de/vZLX71I8/Q+emw36xPWgseoO28f2lHbBCbjWyat6p0f/0DM9vcMg1w0jApJp/F1d3jfj0rpGEAtfQGX7oroxfprBlPDZHzzMKdLsIO//4+0iree9EwETlqMLKAAyWVW6poA4uuH/ceLs/3T4cnb4edKnJUbDTv3ydDFhHEq7swkyx/icseVgqjwDEqNzSjXo1TtT9rk3ffZ5iFd86qBfJmCTasSoAyROkfLzjVpSruSas8jR4jY+8dwEZEX4MXBi1GJOUtSm1h6ubY5Ne8X1h7BFeqP57f9NfESgNx74lIKUUhQB3i2+iema2eIjVXQe/vI1VJCmCZbJM7dIjElPDKMczjQphsFe/RVy7J12TVklhKEvAusTMtLio5qdCnURMgUoQbYRd7RGa72b/lS6Rjl81KCBvt8MK53sNrubvoDHicI/vmd+pSoAQ16d8sFMSikQCd35OBrQe8iOPlK99+5/7+6fHpuNeyLhmJB5/RL37nULixK3180ycLEGIDN6RyC367gNKeL/HxcTCZVDT3ZEwHHL7KV9l16C4+x/X3f5SCcDfrA03aMOtwQxiWuhbtYF4nFgC/LIm/9+ejB/duz09w9fB8uyjR1KBv/UP5OfRTdJmic6lqNmeeiPuF7sPa7GAVIrPXTBmIr04tDdP4GD5KnUOm74+aViQj5E5VsRJ+QL+xydeaz3RK/+QOKD4lU7EaYw9Rinii6UhK9/LKFBp8Cz+8Oh1G278Vb5UaGF0jpm5v6R2T1LB3Ii3D7nxEB57kI6asjVd+vIOMJofSs0f3mE/Pjo/TY5b7qP4gDhFlZr/6/flyI5MscVk9/G+7pevn+k3lpv8qJ1QDGTLYRBEU7vBZplAVEZuKBpV8LMYN+e8YW2xJeGcUfYI0nQCzPsNqT1hiPKx1WjYNpazkflAY5NGGCnW8z7FfAL1Zzm0TIFVTze9aWSzjPqXtjtMSSfJPU8TDez7PUPN4j6lFNfkvmtbppNPryq7NiMrFZgSr7oWvYSfRxuv4I86Lu0wfPoI33tSCgH/hKCkW0AcWr3477DJ5FO/iq4NOTeUBOaut5IB/Qq6oCryq9CI7w2SuhkJAW2L7muVLyAlTu3XtMSX8f6q/x9EqNnpfZy44dvSvRKQSRWSF45mzK6Q0Y/JUXHRWDd+6F3T5dGcrYaGojInen7unyfc3+YZR/UY3vcvG88IP5YKHkXGEs3QYSNBcfOcSlZFo94RAjgjcMwj6wrXlNy3z7bwsRSW2CEKFjB88pWen2W+VysKl/oZNmGBTOGaZ2KTqrQPZL0zTaOPzCmPBvSdIdf8j6BUpWrvVr+Z+NfvsrFVyJj6+TO16mUczpIrJJwBcc25rVjqLDCL8ktFsbdHpz33n/hkwm4H79gpreav9WZt6FyfufwpKzAWBherEK4ICTztDF8esX6U7Cq5tBelj4jiOTCgDtFvRA/B9FsKeFqny41vQ26+TBvYYw32UXe+JHNJRfcx99NaSaEDN6DqRDOOv49CcPAZnmHAQ1mHe2cL3zXUDeD/9XkMkovaDOy2pOHV587ieBomgfvz5M9mTU4AWzczzuSjhQaVQ7fkzaxY6ZTimLnj9+nCcVZujL1/VW0bJAelxufL1/DZNL6qpZcTCbGMeA6jd+f1Ezpx2+dtIzqP+FxdamO9MJ9Z23g69brfG/z1u3+3+I0JwdXIS2DU1awDt4TWt+ZoMJcV6baFKKZNKMsUioYDDZjFJxBQ0jq3hDMGl68YS0pn4t0zXhpIWAZZprp8xiaddf3tDbvppu4HL53fPj/vtfNjPgzWrzNA2fYZRXzSFq/NtsuLoHMoljwH9aQq2nM4VmTKcAzBoqnWDeiW4YSDA4hwiuviJgcGKZi3w7fdX/MXkMc6nLVFkrGgvbS6tuzFWkKdooUST2OHMkN20pUfsnM3EE6lbWrZDzUFOwOjAfocZmrekyjFGL2L5jodxNbeBN963DcT+xSV3fnDKZefw94///TvLm6Np2Mr1b6aLz957edWY3X+cK9SC9yuyY+tB3893hgYNoYfZWXlOT2pvrRtGd1k753rZXP8HN4T9P+Am8P8H9oGF1d5WbszNEQmxmNgYeOuv0f7YtuH24fpaY2t5q06bU5ZbliUVqkVqFoNCxgiwgnhkTEpsCjOmoT+LMyzGMkpbKB2KQqmFCtvD5vqSiZA0px0LFxZUGGHDveJSmwft5zAO1VesHWCmTZBbTqR4AMb6K/myCVN2Dbpxnm/W7BRRDce+SQcNxK6IcaIr6bt/j79iNfi/YbvyROXDgwBBx/r7/Hh3e3N9dnJwdXjVaf1afvM1N3wrrKZKKRqd/gPrvIode4ar39nk0ioucwfjproOCiVrEmfLGvDnardqYo+uTBvPyCYl7esQGNvLLCdD0sGOmab8Vt6akROMAG3kQtj6NmM28D0nCUEgxUWPYBnuzfps2pkTziEnAWITuiIAS/O3x3LE2hPe9LG5F3GRhEteFNbS2rZOuXcM4ZLmwb/hlaKl+rx5rpd9c2PL3GofSkgK2VSb3tAHH+1hG6TDZvX+kJLfcmVUn5kB1xD+qNkl5rvbhWR7X4d7Fcy/6jQ1IcYUTAL1+84GSmIxuXyJXUKIh6rIZC4Jj2IyNzEeGlpkgCw7i6Io0dOweRf7RvdZVybWn7/Y7OZxPx72ZcEZTlsk56kZUni+yaaHKcOttpQQdrNgaV7EhaZPXj++ebofrFbjOdn7ZZxhv/+V6/3Maw7V9WE7Ur+Bc2wkHTGRiK4JcyATLsRPIxY5+X7mTwkHrct/ExYydnD0G1STz/8rrnx17gOJ2m6lt7/7Qbk1vxxSl97jaIu1SlloAzNj0gE58CJiR+igmdRXkfjuv5fPry5OB6x6+/pE7JhZy69CxUQ3/5bgLjEInmB+cQkc1m9jgNVhCXzZ3hmezuK3yoOirY6dYvQ7jm84qFVE3DgAYYivKGdzPbL96fU8GjV9uWCgmZ8Q6Ce78qrrLTdyhzD1vvrt5LYjFlJRVmlvtfu2NfjHN5Gr6QgNpAZwtXioWZUtLtvv4ZuteNyN4V5ankUgbepI6ClfAY3GPOvMQeL21xC0HVf3EbyJbIEvIW90G6AI17b7+Uwjr6qMl9549o3jG16eQZ1s/cv9u+vLs+Nus3p+elzPh1kf8vdtqpx7f8m/QU3UE/Pmss/QPb8DY0bT1pWNJYvXYeYnNPabgrVeuc378sKWS9BqY+A5lRL7gSWC9sGtq8NnzFDkyHLmBc7dRm6/OcuOuPw16l7NL09BFvZpqFhYiTvULfzXlstcvwawQhujkjc9+oFTvN14zrf3nkeq6+e5Xuapa+jABoR/B8RknBCtZXt9UKzm66UExa0CTFsHy6ZVxgXO6ua5WWfwfWzdQSCrYddmMvg2/9vS95o8YnYcUZvZpbWExUqCD45HC5OhHXJ9w0ExrnPt1PVNWhckZvp0aAsGy2YEwNY4R7YCce/jQ0QIK9gafMsJy5KDssdXHscxVOS7lsgFDxuEpDtNsX9xBeYRv9rGmTXiU65KfVAqkGFijVKoJebndKigXCNtNRdLxLpc2PH1RBmlFy04XceUyK/pA5yh+YaTUF3e1V4dQ0Xx59bjSiXJnNQTZegxAlHPF1gKSFgLbHoIXdPgINvIRsPc42FVndS9KQVoJvdCMYanZJjDuC+NusR868D+CGhopUpQkOQ9to0Z3ZjZAVRV38XeBm9sOw+ldnp0iVJxpBC3DLcnT55ZruIhLdst7t33xi47lk2zrhk0d2IWZDEMb831sjaalXIh2FpZZg7igeK4aus9PLmF6YOT7iKU/zp9Hl/K5DmnJ3Nplm0h3FTfNPDVPk1Ec+yXW3qUufczHFg88r4Vn9YmoQrUhniuxi7XMnAK7ZBz0knBuYeizWDb8KqcZ4WhxbfbVMnwj/R4hHE1ei7P0yPyzpzsFT+fclYdH5SJMj8Ok6t+9sNdL21pT+axD3ONU+28exvTrrHcuBdUvZGocl1wHSe/p88fhgJuh7eDbU7iT6OSi689KN9+fKPO+syp19En+peXpkO/1X9Vy019QeIDMsgbcK6baDxPx9qojnjrVAmf85QvxsJxivvFUOdyEZLux833l/ren0QryJofNqX44083N9ub6Z00Q1902w3M3yp+Ip9z6r72R6wGUFMF++QtyHx6A6J4j1ciDSMcc580Ug29uN4fsqi2zJduOa9vy3t1l2CjUoNe1lf6wEJyWugpaMlXrOdrTIIuoRAsCVV3CYYH9hucwjjktJUygSyB4XUb2LZt5ty0bpsZZYI/7eyyT2LgBCHz1TnZo8De9LjXu1wC66VYt3Kqh6eras1LTdKYr3mkyPmjT/dbxhdm7zFtYavOj0r4w67oVgAbugPNLJcCW/2K/nP49p3g6o/3dVnkK8csCY/s0gklfsxJU71pCWTw9+W7Z9BNdMZK12CNoHcfulSfmp5GH8NXBx7gfold0wVA8xvLW7PqVC9V+CF+ek6nBeVKw7hJusYipPjiQRMFEeeIEVFheMGyw56aNNaClDth9eAXmWmauuYwdzY0PGe+aRbqIom60zKVlorD50rJNfxbn7GSJZcQPaOOdYQbIJBUV8TLdy2IcB3yQtJNhakOav89JvxiFNWCj4/VUA/J2vIIrWBcZ8riPUXiROMAB8X3UsezzDHKjboGTaIHKu3nUCQkXCzT4f2PFrDA+qdWGVYbBBdCfXbPQoGBxu8NuoZV0+UNqAu+2AKx14fRioM8nFQ0/cLxYT9rWZWZeafHhnOHIiUsr3yoemAehh597+2HM1otrhOOKfNwm+ZXWZv0JSykiW902gcjGFP6PT6Z31R7zcRNLLFnoVN4Qef7CscoTqj0PlG7VD0TeG1BjPFmQ87JuRmTEFQEjFbDLt9AipGWppI0G216ussS9z/Dx4dyZNti18wG0lgz0A2VJyAHtvYjL6BqHh8zTZZ/9gTfCJNxjDmvnfo0wF/IQ2F/STf1Ye8rMEssF04ENtrNHe1N1KAB0jfuaHFGIixWLtSWDWnmiHQ9p+ncjz712kspNqqblWj0h5LhT3/zE/rYPXCufWvYT1VTbygBVqUpagEfe4pGvHt2O88xbfy0Z7eb8XeF1DgV5lWC64mJGgMqb8ZeRQelL/lzZIg4igDtrQNI/+g1UPE+Lo8IsYda4qC+QMjsYBM5ZvbUIdl/8ZJOrvjZTa7xuO+nwXRNcS2vGKJPQC2npdQ7cX1Lz25ByfoDxTLbtMx5paFqDyfi6fXoJ86YhMBMTvw1GkFbRlqqLg6So82agXAKx1TDa4dNLA3HJVF3EvuI/dK30yIrqjJl1AJTQ9YOOcs9ATaiTwU5KziAjkeOf1qGzKQ4xIafCjR8z77miFXkSxIGUdLkeWz0qWqLnpfs3kpuyISFNDAfdJp5Hcf80OVpw5pQpVzPCvU/FgKaPvaIHJ/2Qov7oJUyy8MXqzmeM7rdAp14mtnMZ8dmplW8R1I6SZATkWCcfKbd0AJVRBwwl4tv33Zykgq4L7Cas8m9fiu3p+qNhDDFB3e444lcQxToxcPmpgGoVYjGiCM3QXOLNtzwjIDmrUdpjI2OwaDqSmKzEDceNFfNdbGOjE8mhJXY7aVZbgkLCyujzWjRHtsyne7N6seCo8YpeLjdOnubcUeFfHPmN6bso68ebtoX6q3IqG0vUkX1hu9Vs8qqP5XLckysoNx7mJ6tI+i4fu9Eelw9+oZTnSNv+TRerDGb6K280toqqDxc7byG+tMCiMQE81W9GqjH1DHwluS0KS94i1jBEXJCZjizCrTcjVSVk0Yav6ARM4taBmrZIZcc4463xhho1Pfs0lX/pUZGuAFiHLs3xRNcqA3K7fIiH5qepdERU3Tne87cZYfQHI7Cx6/kI25JUei69GPufO9RgAh8cXc7h6PQ4lUAuHrhHIg8R9wdP3CKxWol47bPHDQThREUwsgbllb/uNdPAbsmqCuBL+nfNM9v6FF7pTnxrG9wyKLeFEFpVRDLMKhy28U4ttgyNkdLbdcjfK+hdAr0gi911xRFXObDPU0q5dQilYac9OCmXfO8tUYMckCzEIeJWOe7f88unSozPnbAuliJXAq0RTWK+KmuEbvJxkwYFUgccTm0jR6zSIpGtUpcCws349x1Tqp6FDrZoX1aGUMNEmv9WD/F4dW22E5zw3mZ0ZDMw2CjyZloJ3AB1iTmyzYH6E5WSeb7DqUSD6h5ELQVOe9Bx1533V4RGbvw0YmXV/OV5XP1Jyd6YDiuYeeEk7zKVYUDpY6t1Y+OLuyepscP9bmPziSaKI3Z1CPFLt4U+Cwy6ku9S00v7iTQlDZ9Jip90QN5QcrDwlFJd1RSYUJ8tyvLUTlHJGEYTdNeitv89GZ7CNyNmUPX/heVXp7qlkmrVO24h+3Uo5ua8ZovDwQ9YhLFU/LtsreJbeTHJRfIwh90Ui/gstEn1zz48BVMPJLn/c9A4MMc4OB38P7G6rYuLuUFNqMeKdUrqd0dtJfLpXq3gfxYUOzqShuSAyeeYaXiiA9IxcB7gsqXG6B79/3I3yd40NloLOII78lY0GZjHnBY9j4ybo0AnAzeqDzr++x8k+xhb7lwyga9tTOSyBeXTeAKwqyvPkDdyXWoTE2Kfiu3JXMN3FwNvj07mqPokvWEhlaTiRYwgKF1KCsCcHtK4dHsrYY80wBMKH6GKTeGEnrX1tBJPfY5jXv0vkLJXOy2nGhEAjfmJqt0qm2Vm2Op8WG6DjtyWXMuHaxmFDKECmcsCBQKQcdT0XHjEvndytOIStGASOlrbUOvv8dC3VsclSuKM9eGZXcIIsdSn4tffiilD6tQDflcF7cEuLC/y13pQX7m2jpTubICDVR7sepiLwoO9GdjFG2l134U7zdGEV/Wl8dAN46Rd8ziOQbS3PisKpqe2uRZvzqjAr5DvUPZgWlXyJx0JXUGz72MRsHRxxg4Ge/dnXa7H6jbOPWfCwQ7vzAhiQNngoMze/5KiuyoEoOep1uahoHjvOXPjsXdYd93u0XkM4NG4pA5KclIIorIg3cMFy6ru7mfDRdlYwvdT4LMC0cN79RnUmttrIILnHzHKV0N2wszocQEjcbGJFuc4X1PDYWd/MPPdQH0xwHonzciE8vpNS+zpVvzjLZhEJYlzxYgPchZLmeTk1lj/6RCYeOeAwbW+vS14a7Zus7zeqXIw0ytdO4zg8gS66fHCaurnva8RsLJ28Lvh62odPV205D0pLtYZZ5E427O29/vS7F6eXvhH5Hg8mQ3m1bTXPK/WKhv75c/wNQ/+rQ8u+zzuNtR8FG0XoXp2ua2V3GO1s5e3LRbtqa9eYko9Q/j738IV/dPt98n3wlTWpm/nFUTNcr8Uo7KxTWBmCPPQxq3fQopJv44PKmmizwKTjgEJSSfYZPSskI0sx8PxG4Lop9FKJXJmSXznEXV+DOwYGcFkf0U+Fn2cUDPj9yZyaRecUB121CQ/HxdX0au43mCL2vntqVmcTTqDJd3bFdaCE58kOVL5QQsguj7rLH0eGDFKn5wlsHTcdw3YWUjpeJyqiPcU5NijktkC3AjPRt4ynJWUy+MHJPdP6BW69Cw+quzeBplUO76QM1gXnUR3lhff7tzEXl/bZmFhYhHfhCF6eSlAivQCf5wRRnFLB5JdDkp7rDl1ljQX2Aw72XBElo6wcVM+ShC/6J/h0+sr6oQ/4BPHT10u6/zaLGfdcCSroO18BHLZrVJ6xdyfg9J6EsDwqeVq79GDl0fUKVo5OIQuIss379P07M/f528RHf7TuLgS5mJzIQcNsF0kkg+ZQzL1Dgf8rCDGvFFocTBKnjCCP3IW6ITktjF6zaMj0qJtCsuMHQRUrW2UecAUwWG/EJUFObEpyl7/QzossBeTc7MreJTsjp00ZmAHA0h26nPKkzuyJrnotCn5fKhEFdTzUxWFAKGg2CoB1O1oHNJUNrd2/HJGE6KCWsSBwHZHBaiDmLCrqhcUYs1SpWPMESXosNOWBOt1tjkFMdTzysY4MwZZdD+hY4HXnbXTsRzlOxsIkBXK1yXi6e0usq/OkGCS3WN0OSYRAo1d3XlQr8OsEoqbN9V6zvpw1e83XR1bUkTp1ipRAPeVxGhZZzVj67h3rFrQB7i+vgVmPRkV8HGjV5fvPcQhoexbsMAXOBcS73Nv17t+tnTNGnt20eXMaYjYG+OUbIqd+vTQPZFtd65zDnXhVrDhJ96/WnLNrH7tkSu/1ksW1qNHuv1vkelYJ0I17TSZfOg3+AqTdp5Zgo48zMb2xCPUkeIBMrF4t2tjZdr0eSeoUW2ZvjhceBBfqvB2qIDVvgFecqTcOHRZCQzvx3dnHEw1FkOM6GmVFI0SOqZPMCeR+jY2au+FXJNdN703fJa2x7pPx9aLregkuuAohOIjBJVpRFFu5sPiu9QikgjVjOJKdv8Wp4BoW5EEmKJe1TNA+5guCMZkkVl0woWGj7DBbt3J+lkwyLsGYqHRVZyZlFnaYQNCsVqjMbtTVPeeJueC8V/gzHyDQfS8kueprRmNfWw5KjFA8+epZmJLY4tM7SNq4767vzcKBUSG45RkMV8aejHHJMOMQM2B/G+cM39y2oXeI0pr85X5Q5Q4dbBB0tkKcTi1sE65WlX5FQw4SoT8A/TUN+1bTDBpOsJ6oI5KqZAYSnmStE31ctSK2MsYrOdqTZ6mg/3+mZu9Udz6VslKIKc8jlQCCtA/JevXJQ1c4mPj4/AtEj2/a4AHpKbTGGSyYvg0DgEBVgZF3Wa4WLE0jBMDjkR5htwHOC3jjs2JgmO6/4EAmVGsn9wuzKMenBwxepeF13ahSBY2KXeWBz1LXDT09YsSZR97DlRqWo6d6EnHKRYuhWfabNNC7w+j/gUbA+7uoogOra0upjNA2f31i2vTXNUcfKbVcN4PnvJmeoMkcZfWYHY78fbIgGwjXctQyM1JSx8/4ih+xZx/g9XakGpXJ9AwQzXwuhSWsll/Bq3MhIfR/BGOzqGOcYwJ2RSJmPK2oRTawsNLlW7EZZ2025SMdoOTYlJSrbKzpK3ozg9W2F8MqdGs+GpykPc00RConcCYZUUwtK9pbcNDpTnJdAKLY7THZjttPR1TKoPhwG00CFL/0mGEkgO07GyaKxsPKOT4FYpt43LJmYyy6uqXD0/ZVylbCpIzRKhOizkt4pTbHbhEu2y7gVPoof2k+baz8zDn5ka/3SscX6aOtTlHDRmMoGGTWbEfkQeNrhBaiUQKvQSKgEKvuQwlzHBtXhyXyMNj5OVj4y9MZeMlz9Hro0lV1XidZKIODS+l2FFtimCxI8mS7RxsZpKPtUYQHTtey9LlgdDOlGJ4ThXM+v6YvLUTZQ1r6cgM6pBgsX/gCuoe80WDY5lsmN7PFCg8jdTB2Zcmao3JVEf6yc5S2L5E+S85hAB4W+S0IBsNx74is67NpM0W3YYmz4JKowIiOXcgQiwUVEITjCRlIQDRRMtJKHX2sJklwT5QmfUcqy0olfWGeJwonvEcjJKeN7sqh5HLrw52EHruUEqeaqPmM3QoGlG/BPreZLP04sWtDbbyZGthSWL8iai4gxDceE31iwRjWbH11aC+H41HRZEIkZqSewGkQsRWHM0gwo6K9rg3BDG+k0qyDYafV/R40fSAU746apm0ELV/QYus7qzbU9dcAbc9UXOwiPuoy6HMDTuWF2yNIvGtq3t/sVeqeTUZqSLvUUrklNDFZLYEDbg7Zj/hpwq7rv9nmup+irHMuK7P9xwi95eIBlFTzQ89sEnw43RabaEJczK7KkaZ+E+kWrFEua77j79bjvY5RSgp7PavSvvIo6SInUxR6BrUTV46Whz4Ep8PmLvEySYlrEwtdkPZN/czPY5Z2O1TTNGbtaCyuQuEszTBjLWwz4XVk01e86J2UAcWyLUthqIuhAMiBOFSjwkJPQSbtmek63UDyoKQjas4wwYEJv6mB8qTbxruHaEESP6x2Tv7YHuW597ON6QgdNAx5BZdQWnuK699WmRAAa9fysj1mmZ1pz+p6auZgSimAWodj90xo1DOP8YK98cF9lfDVrrFDg3gVC1EZeY3HO9izK49UxrfirY2nvSSiVRDunxNMQZO9mdkSHLZrjAiSuHKVzreEPmi8KY7b1A8mHR7d2f8P5m9E/J1Vv+1kdr6XNytbD4Pv/NIbxH2DRvwnKthIzH30p2a7IcW5/gt06ASAnhLAGceOvEkOQEtrMhtEZiaD/Z4napiUT6xxFiOJK1C2TAB+YLBNEPF0Yl/QJhk3/lYNP2/xrgvNwmvtG66mEnHahD+J2wXeyEl7IPKJ1aTut3AyTT3IShygivlMuiox4aVwAXgkDQ3ATpuMRERq4AIoO1yMycRY4Uz1P0mN85gNc6wGQFwk2QiAn+cxxqyS4IzRowFZEaROI6ir67qPF3GUPHgoIdgSY+IuEMF7YzUrTX1rbuPtoYSiW7mtNz1bLfeVfOuPnQub3XzV+1//o73bF+p4/ffAz6IRfTw8NyDPwX4ZzEtCumKTOBzFhWMCyBmHCoHp14jyoQazvHD9rHqPFOUHxpdMKc3C0IeJXvLHnwZ2dlFBvY1yiJRxyyYLhTRtHF1IRVj8t5oFjBf7ZKqL5LwMzP2sQCj7+KO6YuNqVg4rjgCp+90o7Fkc5Mh62a5OOcur1UQdvS7H5DqepUMEB/lXU+wAv9EIGdny6MYVDl8zK6FhTvnHX9pM39FRpweX9vfjeJI3VuEq06Mm+w4ZUkdaSc1299x0GWinybFVWxA9kOC27I/qd6QoQWQAofv8X2JT4BXUNYGXNai/v0B03de5S0HqOnMrK+futshaFc3+yoCVNtaRDVmjEf0yT2x9yVHmPciqXvXB1Y8jWtVJM4t/N5gmxyZ02kSdPVPyFX0k4L2MYJBQMhYluJou3OsAz2+2BES9owq3fWdlnihejhLkfS+q2qw/B4vuJAwcIpfg+rkRzrENOnbaP7TxDFk6MguMlZYyS3hy6bT2Tr5fQzmO/hTAONsFrRXNP8E3emFbniRJOozoLHboVEXd2kpvVHkyMmZGMXtcMrR7k4I+ynulohHM5ZEJ+btcxYOo6xy3XI+AM3lsz8Cm/sJzE/b6KpkBKX7aRabRq0RCNMjphX+22z2WfnjxbeOA1q4zgduC/0/u1uO38MK9kLPaC4ilbMTvyj+QidTe0PP149c7JH1os0/0XfzUn2QzJ/QIf1aZ/1qH4HmqZQFTAdKGKzCm7zn/OnudvM7+6Xw2x9Fe69YJexkP4H71zv+3xR+ur70z1UsWegviBwqLgcrqoF1T/rUff+C+eDy1V+8u798+UP8Q/6LHtHWxVRaOFfgC8PQyP9Z58Wh1Dx8zeMytDrhzEzb7iR1dFRdizSTnkUvei5+tHWdddc/3J3c3G2fbF7sXzaxcOjxp+5rw+l1a/3o/U5oH+zA67+aZWHZc8OQOWH9yAzeiitSsG6de7BtjYOvHzF/gn/9Mvp7f036Zfw2JT0xm6/PNsr0EWl6q7Y153QM3wssuGu+Zx01pMeSwARsEf5J4VOTkpMiIdhEdjoqDBoOPQxqP3/LzNg1ccu7FAhAohhDSKWAIcj/IiVRTI/hxNK8EGhgQch/FymG0E0QvIURBQSpMmjmMYQTxRj6MVCCzSb7T4FPsRJZ2bTjyvYwaX5J0bf+5WNCbzw4QwEheB9G79kMFBsNMjfYXBhcCvCgYu3Btqb7bfLDttt44UHDgK4MTWIaBA3XBuYk7ljJf7YUMdfZ7/EhrB604RYLKEePEqxCa16RykcFV8HDmY0HIc24POGfd56jYS9Uk8aFq3nJqymnrlh49YrTth16qUn7HjqVRv22HphGwGCA4L/AyImwJj/2Mvh2Gdghqj4QNR/7FX6bXBY6XtiP0ofk7kjB39siGiHGtL0y50eJ+d/NeF/O//QDD4LCx0lFqtIBcpTljKUrheKU6w8RZWj7umWrGShGzKSoS7qgjRFEl7SZI5vPlXYbYP1/u3G0h+5ogfFFNKFzmSRRSIOkh6g5ItPlGEJ3niXbMl4HW1teNtHTwvNeW1oDcKUpRS+oq/nZ4s5//s5lKZB3Wq8POMONb2J25LwZ/alebPGdTeTf337KztIwseLmrhrw+FFUoMZIUgLrdHjJ9ZYPEnDYGI8lnjTcYpPLHYJfqrxHs0M+9VXkkSS/m91EsJJNeIx4ic8vvXQ6YzUpu9/hfQ/HTpvZ93/GhPqHWzwNJ3E0/jvPqnLW8z/F4uMN6wYntSiyRF1M/1AT7IrTStyEaFXo1MNUlurQquk4hkxBe+UG3yy62IE0L1R9CjUBPsBLanz2vpUZzKwdHij6riOx20wBuB5ysoYwvHQ0VQ75Pa3Cf2u2D6kse/aFuhI5lt6gjrJyw9PUIxTKJULBJE8sVAqTu0QNgeiOlrnOA1adb7ylMy6AEcOWGssPgGhoZgG5Kus9RElcNw3YPE/WzHLpcF1jN2cU0qJ7nw8dh4QbPXfkWLiYwmzhOBAd6N11vTOPz82ZmH33K/KdtBxHzsPMNFl13mALX9fFSAABywJ+Wb7iavfhuZ/sRhMGiDi+Y933nfNuPV+ISdyAXdZxGt8pI1IIcSWs//mnxcp3Rj/2MAp8o+jptBLMfb39J6C3F5/i7QeJ5DcXs59gF24hK7iJrlCgaFw6LUQHi+Gq3h49ighYsLZ4+SekpX3fmRJE5bn+nGcGzw5yvi0HnPyKDa0jlI6LK4PrFU3zgWQ7+/6lnELRO7130jvcZh4SniKsYNyGg1MHlXAiuTd+3zCHIb7GYQdVo6TSnBYEQtv4JQqv8TazXm0jVdEBLPbmnBaK6QdJUPsURmH3TkjvEOHjmCLEBZVBBDjkHisJD6fT/E3TunLYFM5LjyV5gp8KR8n9Tif5sbHRnc0egCV7XMaV0v1f0Ff2OMhh+wbWBsPFMtKzhcgfoqgkJ45QEs4v818DWqKeol1GXw4IQcHaYMLGD0OXqNJZ4jDAivOuJE4g17fjfUvRwiPdC+4s7DCGigdEpNK9+gE6kn2sZJI7eCkY6lD1ZDWJEYFgOEIXYGFdZ0/S96pXPYIujdXrS0eR7LzLpRdA7rXJoJlZE0QDwYBaZaDiwC8TDICLBKAiBZ/HJANN9a6bjHon7OuRtYSEXBAoNqOP4MMjhW4M6e1npGfi1oz/cQ6A41LWPkrzXhfsGrQI1Y9ZcAIw/whE1Nx1N1V7pbNtS55VrhHW8k1ZQsIQxlzWuSsUxIOZ7EiuNRH2ceWs/QxzCS6fWINJZEGAqCqOrjNnIRIqZZ0rywrWpPNhO/UT0DDekgtfpeMvTM3vrrpIZMyvEIsAghRI+44lXDQCZqLuAduZGy9sdZqhmR3nOUcWSuEYkl5p7h60lWwLx111tnqNVbKXM1aCRWor4WQZnyYq9zuuJLMGzhUrIs6z4LFPUFDIvvESKVtRn5ocbdKM6FAO9Lxvc4sZ0lHHBNs4BSXpXk5vLp86gGrtSJEDLnGbF1aF95mWUsNSJhyxyBfrNj/j661va6MjJw/5wajEl8YyI4EC0ML0/qNXWPutZQN9eIor20EdJ6Vs7m+duJKXZ9sf1qfY9eRPQ2Vf5iom38njDsjne8EPrJhbhnDFRydHFJBJVnqXxMMYazFOLzc0G2WXY1CzBHORTs/Hc/XB6TVoc5yPAQ6N3O9pRISv8W0oExQgwfnlGGnH89nRQrpp558nKTzqVYcZ5l1kspw4yzXn6j2sQcR94EB6eQAo4s0eTlKoTFNCqGUUUsT8xRQNEeDKFK2+5r2qSdvafw/SJ4H3kTJcBWSgVJpyTIUdFDAGLH/qZxkUp+s/p1Ve0t85w0H7DJLFr2qvUqKi/nM3/WG9iav+dPGlfwl56p8Iw/nrC9K751ZxBVhz6tyhy3VwymDJ7fPRnY9rapSHlztgh/oxQVIsRJH2/W+Fl9uY76XnnYecCriouR+N/uJ4RKT7q7Bun2q5d7IeZ63M2yyo/XK9Dx4oL2tkV3EAYscRMat+X2UDR5gDU0jJa1qxEaptV73LW7MqNp1bzz5qVfpE7aRzr0jTG/aNPnTfVgs23JSYAmfLvV2WVXd9kf+FHlKEqjNlJ3uJqldL8C9ns5oe7xMQvcCpDrZtpvOSpWccDNyM405G3vwpqQ220SY1XfIqNNV1phhm2qqOJcc7MsHvS0/Y5GJkoMIk2lOLOsATpJ5iGaT8FVX0cCWd8TBnc/swSJgTnEvyXVGOYPV+nALhtCNsy6mWY2XoR8U+X976/8PreVpargGqIqRR6Nol609gjZj/IEgdQAOUfe9y9S318tXMMWepCtfua8JFsYFXPWm+uYiEnKsp+QfsZeso+lIKbHK3cl3K59sI2MbVzMsq4j/wmXbkSszM/JDyP9TFQ8Ws2ZwDdtR5Fo28J/GbYQX9Pi/zwVg3M9Yzo1SPOdtZ3G2ognC4eI4z5dlnN4ynkaPPWRbzqQbl+v+vlwbo+cs2zRn/EalsyIgvjZ+hSTBdTHgCuYNbIDp3gXo2ULrF6ux3zd7f6WwDyb79r2WkVH8L7W1r1fjFa3dMB1/LsBgb07vuZ0krgC4UZoOl0fDLyReuTETjcYh6TVCIWc4aQefSKE/jRFt0pGz501buetZt3nsyTWVDmfudYfYiqV3ZoQb4SSFhLBUdly6d6uUNcZa0tENrydPGqgo9AhP9Nx6PgXZkCjbUm6/cQ0LfGpDebU3Uh15SQuePXE3yg8Kw8llVxk4khRPOiNFTgb2CYGGHzewF9c8yS/1juAYnnG4PCq6l4VyOqOAqk7bhNTZc+27rvd6fSlBoKoD59azzKSGYkK2vvNkpXm5x31mfuKi3DJNnrS9siYjJ8YXRixvh/6oxOEXhj0+bW+qWMv0r9W9HBCPljIVpw0l2Uyt1yVe1+UfEWut64TNuzSu9wQyRaUbbhmPpKqqc6cYt1GXfNSwsTZviGkt3r+o5YgVWGD9IxkgHgDEyDPG2yzh4RNfOCddhw78cElMhhCODBev/EEvizkLOOKFQOBDUb7eDKd4kooJoPOpqsD6++Is1ozENCd3eUlA/DKwA4ryFc/98p56oj1+kqhm5Son8f/zaCX5iBvS39jF/FKDElSO6fx/Zl2qs9mv/yqWRP8/6mTgBUlGzd/g30PzBnOVCKtgV6N/TRJwzxoGw0zmg4j28WYe6JZbQjAwAALYyYDKVgn3txEh223ZZ47dZtDdK7cpMrL2NouUhNzmID3o21yMifVtHoxLV97L5kH5tihkDFPUnzl1WzSl5MVfHQGU1FrQOBw06jPk+WKpWq7U9192lcrSbU6hbVbmGFjKUu65cskGfVVObqUhw/atwvgstzStbkdT5WvprHooeUDaxQcHaFiiQkkfCPq8iHgttV3WvvaX8yQG7GOxbHbgW+vXbje/aXTZz0isJi5p3wuqUMhaaqlEu3Tp2QChErUDz1LEMUeFQjuw3bTbaJZhv5d3Y2wuZNHXkivM2MWMAspQOV5SgXsv2SmDzVXRH5KVQU1YVhFUGwcS+/ylgu54oLN24DT6b0+vTHRkYobDwg6ttSS2kZmkpiLDad/ctKviOjzYERuH41jGP0RcWZKDupS5oiMHbo5Oo3oRySKqnafZdC92cGgFDuxwYsnG8bB7UqjvVRtHnXhqIIElw8aVt1b6lTeCv6rcmWk7Mpub4jqq2CXb2/3WX5in8oAIgn/9z6LZkeUUWTXiK7x7FiDTi0GA542wI0gIBUbaaWHQoKMsV0QwKjCEAdl+DBZiAzlGhx3iAC94KZzg5XBB3KCTXH/mgXjpiM5xojPy4oJXIoRXveZvr0eY7vRAl3giP17oGm/60Jd++EqBwvgzgIGozVEUeSPSeNNd3s4xArEoBOzSotgvSnRLKMMYju4B4xv/2EsUo8cuFHp6J8p4157ZU+PX4zQpMmc0V5JUnz6LoX/d9w66HIqcOHMslbm4L6PigosOXvRVa/R8DzPI59ZoovJocW936DOwvff6yIMhQxNejdB4jT2YTGdzRouly6u1K5vtzq5PbjPZ2z845H3kKp9jfvz5npzKPBOgDNcP910/v7hkduWL//83IgmZCuSZe/jokQZ1T8+/VNc9xSzfIQtm9CvD/1bTcuRH8luGyTxFIFFoDBaHJxBJZEoZHWQYW1D0nnFB71Akti74+p8rlCq1RqvTG4wmpmbmFpZW1ja2dvYOjgAgCAyBwuAIJAqNweLwBCKJTKHS6Awmi83h8vgCoUgskcrkCqVKrdHq8tKHfwxGk9nSytrG1s7ewdHJWFwEkHQGk+IyoHeoeAJRZgZdSJSaQWv6Bjg8gUgiU6g0OoNJaJDpcBlfsOlDN4PeY4nUz0BfWBoEzi0srawLCAQCgUAg0HcdCCQKjcHi8AQiiUyh0ugMJovN4fL4AqFILJHK5AqlSq3R6vQGo8lsYWllbWNrZ+/g6OQMAILAECgMjkCi0BgsDk8gksgUKo3OYLLYHC6PLxCKxBKpTK5QqtQarU6PhsBOR2YKrKxtbO3sHRwBYAhOCBQHQUODkBCNweLwBCIJqWA7VRqdtiCqQCgSS6RUBSGFDDRkBSGVC0IjGTx8xxKEgTHNhCkz5ixYsmLNhiApmmF7fTADCq4gtILBCe+PgjCKx0ma5ZNiOpsvlqs1BEAIRlAMJ0iKhkzoxQuib0JCVdMN07Kdp+VLALUqSbO8KKu6abt+GDENmIUBrVtvtrv94Xg6AyAEIyjKQSKCpGiG5Xicg90qyYoKcjBED/SAEjvoUDIbEIrdD0NR4yY9NU434zsgjQ0SrbfZdrvtd9hxAORBPoxuUD1BfeAWJ03ujFpCEh6U9xcsXLQY4NCdLV/h9a1Wk8boOMlq3LvFkDhk86iH9jssRlhYFY2wbmHhlcOmHQEJJV6CREmSoaXAwMLBIyAieWPMIFQ0dAxMLGwcXDx8AkIiYukyZJJIk+3fLHLZFJTccZQ5WaIcuTTy5CtQSOs6dmX1ipUwKFXGqBweo3W16tQDgCAwBAqDI5AotDqZP4cnED3BShSqNZnVYMKImTlkYlpyMt+oIxV3iaVsV/qN7/ksUqalJ4s/GE1MzcwtLDMyZQU2zGn5+zIQbEixwmC+BLKYHkvKjBWDLc23baMoYVMntU6GOxRqa/2Ph0V73x6sIGe+Lo8v8EcgscKKC61Vyvp6p9ZodXqD0WS2tPJJIJEStDZhb3OeaoSU2nnPWse61mO91mejrN9G24CNsUEEEoXGYPX0DXB4ApEUPLkXI02KSqP3cyFMFpvD5RnyjYpjO0VmnwMRisTGEqcy60QBnRDV3MLSyhpkzVTBU9IOeeRkJd16vMkmFxhci4QstbamLw0VDd0fgWGZtEZgeD4hBYRExNJlyCQhJZNFLpuCkopaTtqtjalIMRIisoLmUIQ8AzOSvGxsutY96qqbHgua6cs8SPwrVKpSDV02I+rUCxIsRKgwdOEiRGKIEi1GrDjxoAmeJxIleZs4pHraDc85yTTQZP2rbUYZmvUXl1n/OZl5SBSarcQPhyewsJEobHpVFYOCJ+lPWIyf6CiUKrVGq9MbjCazpZW1ja2dvYOjk++eNi5pmMwWrDa7w+lye7w+BBKFxmD19A1weAKRRKYEa4T5n0ZnMEMk95NsDpdnyDcSCEViY4lUJjdRmJqZW1haWYMAIAgMgcLgCCQKjcHi8AQiiUyh0tpLV88ixTlyQpHoiVyUFjq3+mkGk8Wupl+I56mcfrGqfokvEIrEoUDdkcrkCqVKrdHq9AajyWxhaWVtY2tn7+Do5AwAgsAQKAyOQGIyxMTi8AQiiUPh5q/S6Awmi83h8vgCoatC+5Vaoz2svcFoYmpmbmFpZW1ja2fvgKzQBwJDdBWo5tOWCjaBaKzQRaUpK/jaHC4PYIHQ5EViiVQmVyhVag3hwum3p2IGo8lsaWVt08pfO3sHRydnCEXVJLphWrbjej5BUjTD9voDjvdZmIiiarphWl4LXy+9oT8KwigeJ2mWT4rpbL5YrtYQACEYQTGcICmaYTleECVZUTXdMC3bcT0/CKM4SbO8KKu6abt+GKd5sVytN9vd/uDIwIJCngIExZxGxKJohuV4kQdackxF1XTDtJlgHDNeNwY+E54kzSxHNl1WNCJVxm2BlSHr8ES+yjDfJ/qZ53MfTF186WOf+tBHPvPFbyGGEyRFMyzHC6IkK6qmG6ZlO67nB2EUJ2mWF2VVN23XG4wms6WVtY2tXZ6Gy2awBzUaescU7AOGpTgXRQHdcbctBUzyyREgbxIqqS/BXSqA40AiVOEAInGAoIGjh+2BU5yOCfBTpIHEFIhISknj0f4ElWOik4SMEWVHJJV3ryF9rOq0tdEpWqBqgbArqjXCurIdXKoLVJcSrcNa2p1LhRr4Sw/lRD8H4qkxCns6+tKCzFpkiIEUWoyQT0ZuF3J/O2P5VTF8N7VDLanqalKsYwwqrByuDt7sMVJtYYqMvDtV9pg3ye9tz67rc6WjfnSh9kwv1RkZzbPGdBEcZxq2M496DPRoz9Vt3X6CczNxynuR4bZZEXd6v3B5epIJi5yYU/2z+HeQbk62EXtMv10epk0LF2597wH3zJ8VuN6+LQ9gpwpoQaUbA8gOOc5tYG1zkKBAgfneFj551id/oaKPhYEy9Knb65Mh9KoheS2qd0Dljvtp9vNr/dvxS4BE0mqa9dl1VFxdGB/z+AJXRpBLyaNALOn2+0zkQ5VUzAfsc+ioT4UydcxjF/zA8/md/ELonhC+0AfpS5EiIZ10Mce92MXcd3333ntv50oFRTz4zc+AKxukBHDtzpvtYTm5BWKQYJAJ8Je6JSaXYsDsBJItvpF2QHmwvkVnL64vQ3e+XdKlFsHUuV2VwM4O6NdtviYssk0dMz+jbMiG8GX4zvfP8i2Ez6yEEo65epYvyJoINgCzUnFKUH1hYcmVHMkRFk88YXHiKytrruZojrJ66imrU9/Y2HItx3KMzTPP2B60A176uaeoNqFVBmgvfUbQZ8eOo3IPTT9AuTUHhxe94HDByellLzmRkwqETQUBIhR6gLCoIGzucssZYDaQzzk0h/vv+4m3ojJq7/f17sB0GS8lvqay+UdlvO3z/cW/fuXdBJoMLX7FwjROvK4JX4utLRzM7kl3LTSsXWzC5L/6mESxZk+q4HvdziQM7n/DEIXBpOTYJo+UCyJaAK3JxiEmObOiFjYMTMMwrewigKhrmUWE8jESba21Dd0WW9Ih7RIzMcZc6LY2G6Ft4BBhQhlZ5YAIS1SaUMaiXQBEzvaHUjgB9X0Yd//fTHAvnH72fa2XNIB3yd3EhIkp9Y4Zy9Rp3DLElEudWRMQYUIZWbUAESaUkVUbEBHKOK93CoAIE8rIKgREmFBGVhEsyzsGOiVWLgo9Fr4jiMIXXUKQ4yjGlGKM8UNNY4oxxpgQQighhBBCCSGUUkoopZSQhwox5VKbNsSUSy61aUM8OlKj4ThJ/WEa8tMSUy41N20bESaUYUFMudSmDTHlUps2xFRq04aYcqlNG2LKpTZtiE1barNsc/vmExUsQ2OtUrCMLUcwml2nHIAwBO/PzSk3OvBHHGFKRk58dBhyo80/KyOayjduQRQB1YHQdsGQl0NBDi2kxRCdhL+VoYSGi0+VirwQDDcgtS7mqOHko2FOjBbmL20WRbXyFHdejFOUp2JDk60DLqUxY15cNjOl73zmE8kS9AyaEmerskzWR7N3EW4HimLrUIcxPvEtHGPXJBx5uLlUpvVgf6xsCKm0YVrZ1Q1Nn31JqyKk0oZpZReGVNrInBHUGGIfktKGaWXPAMPYGZpU2jCt7OKQShumlV2zoelzvpREE6WNzNnEnuW1NTVtZtdqaPqcL2XRmtKGaWXP1mx712fii4amlrZOd56ZCuiARvbIKxVl111q8G30nsBUjFAapNi1of/QY4jIoTek0T7ieJhx5/jeoC95R5QII5MocXaimUL7jlMD9TJd1IH08ibnJuFBTDb3rMdYFdglR3qqMb2WAD3fLVDVwO6tIN7+VGF1f3axvCL9AHN2hwDd/5p8/6sQjMYui+J/krpTXVsWY3ziO+KgYzS2NziIMBW61xyAQ8CEsng5BKs/Kjerqaa+AwARJpTFdSFAhEl0PMU3ASBqEMrinJ/GLdRUU68EiDChLG4UA0SYUNaW2QpP85aUVVTV8qkEIMKkWy563a7Uad0CwCGHCWVdi0pblmVZ1sluAREmlHVpo/eLj1Mj1dSryiqqauo++JhP9vQ157vXPQD8/f4PvI8xsJHDqfVvQJWVqYPwfRWBtMxClQpTvFYkx0n7wC7cyiqxJWFMcz5h49e+Ov+4Lfm+TglcLkRsgx9nFAa2fmW1RL0gT3H0BiQBOx2KAez0pwginWxUxWtMWyrWotKyziQZfuvMCokPmPegiuWQ7YobywAR2qxhaR8B4KADEsACKdABAOm+ti4DNoOGDBsxasy4iTLnxUuxwN0CHHRAAlggBToAIB35HFhD50ZHKzjnnI+fxq07MKGMC+lhvlVHSuCsMz9VpdSMJ6sTZYpMZ0v0Tnb/Ydf7S3lD69wuKLrYjAFWn7Wu4SWzY5oPgcsttH3hgZ336XZ+UVTETJ/w983Xf300AKaEv4IhAu27XEH3Dx+vP5v3vvs/8iGxADfn/YT1fcAd9IgGvFnhLXKFLVqE37NswMho7I8DKN7NXMFy7i0FFd6/ndyqgGrhyvoFq5mOOO4xBUUexssek/YOFmZmLEe7MD56uWk/qLR+wmIm2vKa8QzmyLen/vwQIg5XLl8//uE/B4PQWjjQVgVVHlSG1KzpNB3LiQpbT3B0PutRo7Ht8cQbdfDonAfWEryJxbjXeFwUuxiz8SjuWmHuqt8foD3dz5U10knYKgFP5YgaRJiclTpDY3K8UcLbpx3usRgMJxxV+ddTC1VQWrYyujMAhSsGMo3B/8hroXyWo4USKMeyYNeLMjdrLuqJueZlYxalxc03msO74I7U7XzbUV3BIs1zms8wbVWqzJw6G0/TqbS9jde2mXcFFg2e5d2ATdsNe9nkVUu3Hjf9blO1KPGsb5WOG1Zhhm+wnWQ5dd75Q3eoAAdg6Zb2+59wi39++J83O6QdW5vJQdmN7Ut3ouk2g7ChhZzqwu5lBKqKNHxNjjEit98FJKzs02AkvXEeQ2fTMRHZXAtB2WxcXKdQS5mbhlVB8zOhSu9IeVjsKo2YfK7no6VKG8LU2XYmBvewg06+8HLJWOTA6i3QzVje/7NsjyJqDlCW1/cu1dqGAuhU3Uz2X/D3u9m+zzaFU/vKua2P4We9JPmDT7pKzsHGBF3tVTdpG5bPIT+bd1BP+E8+cjms68VNr9V1X37FtXGy7aLtiwCYDpMRu6VsxuHUOBlYvEu/5fusIVJATgf9pKP1cg1gOKe1O0CKT4PPzmrviFSBZetMEWCWZhtuPtf50PB5S8PA6ZNciiVmQxrKU4FlVVq++J8aAtI7FlhNKUqKh0Zu6xYSKLoZ1X7e/vZvhLtrIc1JPao1DPhxY5HFGJM0QI73vNBM19vOKGu2x4WdzMbWEOyOtSFQIgwNOV0YIMKEMm7aKo9chZ4tGpq/lkKkZzoe5qVKVf3mYuTHDys8Ai4cUZPmUkFhs9dU7dlVoz+NfE9N0gX7zOCfcXjngSIV7uFU0yqCTEWfa2uFRuUCPwZw/5RZu01OP8TOvQRSphw8OIiLiZbJKd0dbB3jDOaInC2f8lHdncU2szP+nlUWD0UL9ZTlRV9H9os8wMD4JHtyB3hw0lvQxbMCfoj+ZoscZzd5LYhHlca3szDZmMXU8/ltTIvRqalz1QKr0vLCvXXy5IJI6E/PgHr5eOCG+GoUd9C6VHxhrC0qIOrlD8+CEt2Q+LHCh1/ci+5otiCkzFmtisvLWzqlMDQv3L3ngYZo8djJfPe/RKxfJAUsIMJ9H7+f3UBVjX5aUHY72x2tGs/nJQ9le2YADX8Q8VwNn79+C2yJl0aqSgWlz26fL1YFJmxyqmPH2EVx1nc4949rXhg2bLayigDdTON0Rq2ghxst6TATL+KAYi6SqJDOiVVF6ML64U55RVP2tIcfdU0PXtjU2aJ5PoZoWg1rWfVsxFyK9awwv+yKXOKW0U0Pv/1u1YJGlu17emRom0hxB10CANRu6S5oCUHpuCzMOpu1VnieFBNTFpPBs+RyhIA95dAZ/9Csa4FDm0swZOobJz2dwmoZnbyN3jdKavXf1m1SccWegO1nfiRuecZVVTZRc2vPkEXVQOENFvpIwaaDDbzMoI96etSWy6x5fSHFay81KJXjJ9rLi+7I5SAOptDsxDp5fFGLbTwV6p2/MvHn/2Qktvq3VPIjFw+Ma4ymqzrIx8O355gcFMmfTiskdbhnOtL/yLbHQTM41kKXMyccz0NEvsA9IDQhaQOSDRBQAWfUikA6V6e/OtPifRMV+SrSedTiA4xqdBCTdLpF3EjiGEDsY/jYfiu33Ta2G7V4Sta3vQ2GnoZ8Lz5LdXBBWBZGvA8iuVKIuDFEFEDT9bYFVbundtTt7q2o3F3i1LJtK6p3tzbUAyZDDHfzvyqhV/dEzseQImKFmegyYse0xqZPpxZUpD3OSFoi9KQ9zlLaopSdKpAAMZ4WVGgL4b7oyJl5e/JW/F27tvbqmLHWvs813QcT/MGQx0cCCJThOGP5dbmhlhn7ULP6vL4RR78O+0e7oSu2VTdu6XlQEojPo6mZpUXwLaV/QwTDXSd/sOmcjaY2wkZrS4GjpZ3Q7b3/1KF0pSLcOockXiFLu1qTdKUqZfvau1LrpMrn0LptX+T+0oouqj0yAQS4j2UXNXOW153Gil4lGRs2lTVJ0czOyy71zmKqW1wyXrCSc8zjtMJRyD/sg02uoiy5RD2M6hc1Y9kaNrhlG18wX7fKxGJp1l7Ryx+tXRvnkclgf6yTYxjJsUCuiJrnzYnR4AjJTmJ047iG7fVSRCnySU0YN2RYrv08HO077xnZbaBl2wu7jIAsdyWTFYzT7QuV6YeM3hQ8xjl2d4iAvNjmU0d390HUJ7AU/hVAXGO9oiyVQ8/Q2H2k6P1dYvJ2BzLVNeegZprO9rKA9SvnprJaspN37cLgX1m5lE4zJlst9+eddNlLF27ViNS8RvhBTRs1JmX0x0WXqeZDl8WsbuLR26LXe5rxsD9oyA6iAM9FcCpHHHtLOeeBTJ3GUZm+xfZNvSLSxfJ31b+2J32d3Isokt2gbHr5JoJ7E53bBwHLLv3SO9vF/XEnVydwWFxkf5zjtozVT++0Y9IDkyblyjPahQDTg7kD2XTzscuBrXnhkG8rSRL4cQ0wRmPZSt7D9BOLa0ny+cE42oczMsvSXt0TyMwi/NsnhTWCLpfQTFmrMlUNEJ35nW8aljEOQvZZz48CoXcNxkdlDQAklHEhlTZMS8R8Z7EMXlwXaNEoGWhef8vB6I4WxwLDLR6xeaXG7viXtkc3CvBwitl+kXvnDdy1JZk29Y95gwmvVepdNRx/jwEipn8BO/oK9As2pJ4+nrqLouEdsmoQ1zc3DDm5EHOLS4EGokTe5a4/wmQhloi45PZuGr6uYcF9PYfKzzPNDd5dea7GVlse5mDzrN2zJ1CIMOPR2kJZvEb+axmI9GKtWem9ADp2w7Sy9zCI/1krgcXyewYdYZ0J2QeMQgGJYa8huHCQxaINQEJluOBKLjLqhOE4mIa2bBUpSzbgBQw+ASRamgKFy/r3OhbrXzZ9e/kNX2Kh/G68tbi5wrymSIy76d1ieIBhSijjQqquFnwCpGL/Vb2UEjY/f9Vigq75Z8Key2xJ1KPyNcyy4t7BmzK6PU6IV8m/0nYRFtuTOs4zA65uWEO4M9yd7JQbYnMxzokJIpgJyQlnFKFBqjQeQHyWnj0CQ+xDTBbMBYQcsk9+GydetGAHyyOrIKedFOWTsnUH7TR33sJbGpq2E80cZh8ySl2EhB866jIxZmmd5hFteR0QBRUrkDFtFLqMx9JsMQtKOUIHtMRBtrHAGgsquJpkUZRcSHbHZdPMi1Gr6xBWBY+j8785sjJBF/rlHyBgjlPkfvovFuS5XW/SrP3Q7vjBPjzbpmM6xhR4eLVzL18hSzNFEL1EsGynSJMjf+y8Zggy9+P/gNATUU1h/F8CrMTZNzVkhrFZHU+tVWAjRrO9RCbitSSDhd/7C0qgYF3Ubb3KW60qrMtxB6B8n0Yev6LhK29+EikRgWi75yj8ohPky4Rr7gpzgF7+62JQ6Wa/OAOU0OOu8AkbAKXxeSyAYAbgk1+c4XbXOoZu9EEM+ulPeqgLqll2Ti17nJsq86X+BcwZY9Z5HzazbmP7c6e8rnOIwlMkpaZR+mGf+UoOpBB1SijjQqqJ+nWYQBreooeJqfWOD6qj0siZo2IzAUD+DHrueFpGKPb+Uv5TNuI8XwbM+U8BXLu4vQXyyUSu5rzsF/3UEYQjRCaavRzjqhmYVh5Pydirn/P8l+JaOi2NliNbUhs04JCIrwjahxoQ97MREoCbH2ZCEbebl5ZF3FFEtoqcTjUeMPQBN+8XezqMBXWeR0AoSvHIa1DyIGltTmO7ZBopm6KB5pb/TMx6qCUxHzrn+7G1TaB7PQAAAA==';\n\nexport const FIRA_SANS_WOFF2_DATA: string =\n\t'data:font/woff2;base64,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';\n\n/** Fira Code — a monospace font with programming ligatures. */\nexport const FIRA_CODE: FontDefinition = {\n\tname: 'Fira Code',\n\tfamily: \"'Fira Code', monospace\",\n\tcategory: 'monospace',\n\tfontFaces: [\n\t\t{\n\t\t\tsrc: `url(${FIRA_CODE_WOFF2_DATA}) format('woff2')`,\n\t\t\tweight: '400',\n\t\t\tstyle: 'normal',\n\t\t},\n\t],\n};\n\n/** Fira Sans — a humanist sans-serif typeface. */\nexport const FIRA_SANS: FontDefinition = {\n\tname: 'Fira Sans',\n\tfamily: \"'Fira Sans', sans-serif\",\n\tcategory: 'sans-serif',\n\tfontFaces: [\n\t\t{\n\t\t\tsrc: `url(${FIRA_SANS_WOFF2_DATA}) format('woff2')`,\n\t\t\tweight: '400',\n\t\t\tstyle: 'normal',\n\t\t},\n\t],\n};\n\n/** All starter fonts bundled with notectl. */\nexport const STARTER_FONTS: readonly FontDefinition[] = [FIRA_SANS, FIRA_CODE];\n","/**\n * Utility functions for table operations: creating table structures,\n * finding table context, and navigating cells.\n */\n\nimport {\n\ttype BlockNode,\n\ttype ChildNode,\n\tcreateBlockNode,\n\tcreateTextNode,\n\tgenerateBlockId,\n\tgetBlockChildren,\n} from '../../model/Document.js';\nimport type { BlockId, NodeTypeName } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\n\n/** Context information about a cell within a table. */\nexport interface TableContext {\n\treadonly tableId: BlockId;\n\treadonly tableIndex: number;\n\treadonly rowId: BlockId;\n\treadonly rowIndex: number;\n\treadonly cellId: BlockId;\n\treadonly colIndex: number;\n\treadonly totalRows: number;\n\treadonly totalCols: number;\n}\n\n/** Creates a table BlockNode structure with the given dimensions. */\nexport function createTable(rows: number, cols: number): BlockNode {\n\tconst tableId: BlockId = generateBlockId();\n\tconst rowNodes: ChildNode[] = [];\n\n\tfor (let r = 0; r < rows; r++) {\n\t\tconst cellNodes: ChildNode[] = [];\n\t\tfor (let c = 0; c < cols; c++) {\n\t\t\tcellNodes.push(\n\t\t\t\tcreateBlockNode(\n\t\t\t\t\tnodeType('table_cell') as NodeTypeName,\n\t\t\t\t\t[createTextNode('')],\n\t\t\t\t\tgenerateBlockId(),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\trowNodes.push(\n\t\t\tcreateBlockNode(nodeType('table_row') as NodeTypeName, cellNodes, generateBlockId()),\n\t\t);\n\t}\n\n\treturn createBlockNode(nodeType('table') as NodeTypeName, rowNodes, tableId);\n}\n\n/** Creates a single table row with the given number of cells. */\nexport function createTableRow(cols: number): BlockNode {\n\tconst cellNodes: ChildNode[] = [];\n\tfor (let c = 0; c < cols; c++) {\n\t\tcellNodes.push(\n\t\t\tcreateBlockNode(\n\t\t\t\tnodeType('table_cell') as NodeTypeName,\n\t\t\t\t[createTextNode('')],\n\t\t\t\tgenerateBlockId(),\n\t\t\t),\n\t\t);\n\t}\n\treturn createBlockNode(nodeType('table_row') as NodeTypeName, cellNodes, generateBlockId());\n}\n\n/** Creates a single empty table cell. */\nexport function createTableCell(): BlockNode {\n\treturn createBlockNode(\n\t\tnodeType('table_cell') as NodeTypeName,\n\t\t[createTextNode('')],\n\t\tgenerateBlockId(),\n\t);\n}\n\n/**\n * Finds table context for a given block ID.\n * Returns null if the block is not inside a table.\n */\nexport function findTableContext(state: EditorState, blockId: BlockId): TableContext | null {\n\tconst path = state.getNodePath(blockId);\n\tif (!path) return null;\n\n\t// Find table node in the path\n\tlet tableId: BlockId | null = null;\n\tlet tableNode: BlockNode | null = null;\n\n\tfor (const id of path) {\n\t\tconst node = state.getBlock(id as BlockId);\n\t\tif (node?.type === 'table') {\n\t\t\ttableId = id as BlockId;\n\t\t\ttableNode = node;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!tableId || !tableNode) return null;\n\n\t// Find table index in document\n\tconst tableIndex: number = state.doc.children.findIndex((b) => b.id === tableId);\n\n\t// Find the cell — could be the block itself or an ancestor\n\tlet cellId: BlockId | null = null;\n\tlet rowId: BlockId | null = null;\n\n\t// Walk path to identify row and cell\n\tfor (const id of path) {\n\t\tconst node = state.getBlock(id as BlockId);\n\t\tif (node?.type === 'table_row') {\n\t\t\trowId = id as BlockId;\n\t\t}\n\t\tif (node?.type === 'table_cell') {\n\t\t\tcellId = id as BlockId;\n\t\t}\n\t}\n\n\t// If the block itself is a cell\n\tconst block = state.getBlock(blockId);\n\tif (block?.type === 'table_cell') {\n\t\tcellId = blockId;\n\t}\n\n\tif (!cellId || !rowId) return null;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(tableNode);\n\tconst rowIndex: number = rows.findIndex((r) => r.id === rowId);\n\tif (rowIndex === -1) return null;\n\n\tconst rowNode: BlockNode | undefined = rows[rowIndex];\n\tif (!rowNode) return null;\n\tconst cells: readonly BlockNode[] = getBlockChildren(rowNode);\n\tconst colIndex: number = cells.findIndex((c) => c.id === cellId);\n\tif (colIndex === -1) return null;\n\n\tconst totalCols: number = cells.length;\n\tconst totalRows: number = rows.length;\n\n\treturn {\n\t\ttableId,\n\t\ttableIndex,\n\t\trowId,\n\t\trowIndex,\n\t\tcellId,\n\t\tcolIndex,\n\t\ttotalRows,\n\t\ttotalCols,\n\t};\n}\n\n/**\n * Gets the cell BlockId at the given row and column indices.\n * Returns null if out of bounds.\n */\nexport function getCellAt(\n\tstate: EditorState,\n\ttableId: BlockId,\n\trowIndex: number,\n\tcolIndex: number,\n): BlockId | null {\n\tconst table = state.getBlock(tableId);\n\tif (!table) return null;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tconst row: BlockNode | undefined = rows[rowIndex];\n\tif (!row) return null;\n\n\tconst cells: readonly BlockNode[] = getBlockChildren(row);\n\tconst cell: BlockNode | undefined = cells[colIndex];\n\treturn cell?.id ?? null;\n}\n\n/** Returns all cell IDs in a table in row-major order. */\nexport function getAllCellIds(state: EditorState, tableId: BlockId): readonly BlockId[] {\n\tconst table = state.getBlock(tableId);\n\tif (!table) return [];\n\n\tconst result: BlockId[] = [];\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tfor (const row of rows) {\n\t\tconst cells: readonly BlockNode[] = getBlockChildren(row);\n\t\tfor (const cell of cells) {\n\t\t\tresult.push(cell.id);\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Checks whether a block is inside a table. */\nexport function isInsideTable(state: EditorState, blockId: BlockId): boolean {\n\tconst path = state.getNodePath(blockId);\n\tif (!path) return false;\n\n\tfor (const id of path) {\n\t\tconst node = state.getBlock(id as BlockId);\n\t\tif (node?.type === 'table') return true;\n\t}\n\treturn false;\n}\n","/**\n * Table commands: insert table, add/remove rows and columns, delete table.\n * All commands are registered via PluginContext and operate through transactions.\n */\n\nimport { createBlockNode, getBlockChildren } from '../../model/Document.js';\nimport { createCollapsedSelection } from '../../model/Selection.js';\nimport type { BlockId, NodeTypeName } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { PluginContext } from '../Plugin.js';\nimport {\n\ttype TableContext,\n\tcreateTable,\n\tcreateTableCell,\n\tcreateTableRow,\n\tfindTableContext,\n\tgetCellAt,\n} from './TableHelpers.js';\n\n/**\n * Inserts a table with the given dimensions at the current cursor position.\n * Adds a paragraph after the table for cursor escape.\n * Moves cursor into the first cell.\n */\nexport function insertTable(context: PluginContext, rows: number, cols: number): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\n\tconst currentBlockId: BlockId = sel.anchor.blockId;\n\n\t// Find which root-level block contains the current selection\n\tlet rootIndex = -1;\n\tfor (let i = 0; i < state.doc.children.length; i++) {\n\t\tconst rootBlock = state.doc.children[i];\n\t\tif (!rootBlock) continue;\n\t\tif (rootBlock.id === currentBlockId) {\n\t\t\trootIndex = i;\n\t\t\tbreak;\n\t\t}\n\t\t// Check if current block is nested inside this root block\n\t\tconst path = state.getNodePath(currentBlockId);\n\t\tif (path && path[0] === rootBlock.id) {\n\t\t\trootIndex = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (rootIndex === -1) rootIndex = state.doc.children.length - 1;\n\n\tconst tableNode = createTable(rows, cols);\n\tconst paragraphAfter = createBlockNode(nodeType('paragraph') as NodeTypeName);\n\n\t// Insert table after current block, then paragraph after table\n\tconst insertIndex: number = rootIndex + 1;\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.insertNode([], insertIndex, tableNode)\n\t\t.insertNode([], insertIndex + 1, paragraphAfter);\n\n\t// Set cursor in first cell\n\tconst firstRow = getBlockChildren(tableNode)[0];\n\tconst firstCell = firstRow ? getBlockChildren(firstRow)[0] : undefined;\n\n\tif (firstCell) {\n\t\ttr.setSelection(createCollapsedSelection(firstCell.id, 0));\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/** Adds a row above the current row. */\nexport function addRowAbove(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tconst table = state.getBlock(tableCtx.tableId);\n\tif (!table) return false;\n\n\tconst newRow = createTableRow(tableCtx.totalCols);\n\tconst tr = state.transaction('command').insertNode([tableCtx.tableId], tableCtx.rowIndex, newRow);\n\n\t// Move cursor to first cell of new row\n\tconst firstCell = getBlockChildren(newRow)[0];\n\tif (firstCell) {\n\t\ttr.setSelection(createCollapsedSelection(firstCell.id, 0));\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/** Adds a row below the current row. */\nexport function addRowBelow(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tconst newRow = createTableRow(tableCtx.totalCols);\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.insertNode([tableCtx.tableId], tableCtx.rowIndex + 1, newRow);\n\n\t// Move cursor to first cell of new row\n\tconst firstCell = getBlockChildren(newRow)[0];\n\tif (firstCell) {\n\t\ttr.setSelection(createCollapsedSelection(firstCell.id, 0));\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/** Adds a column to the left of the current column. */\nexport function addColumnLeft(context: PluginContext): boolean {\n\treturn addColumn(context, 'left');\n}\n\n/** Adds a column to the right of the current column. */\nexport function addColumnRight(context: PluginContext): boolean {\n\treturn addColumn(context, 'right');\n}\n\nfunction addColumn(context: PluginContext, side: 'left' | 'right'): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tconst table = state.getBlock(tableCtx.tableId);\n\tif (!table) return false;\n\n\tconst rows = getBlockChildren(table);\n\tconst insertColIndex: number = side === 'left' ? tableCtx.colIndex : tableCtx.colIndex + 1;\n\n\tconst tr = state.transaction('command');\n\n\t// Insert a new cell in each row at the column index\n\tfor (const row of rows) {\n\t\tconst newCell = createTableCell();\n\t\ttr.insertNode([tableCtx.tableId, row.id], insertColIndex, newCell);\n\t}\n\n\ttr.setSelection(state.selection);\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/**\n * Deletes the current row. If it's the last row, deletes the entire table.\n */\nexport function deleteRow(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tif (tableCtx.totalRows <= 1) {\n\t\treturn deleteTable(context);\n\t}\n\n\tconst tr = state.transaction('command').removeNode([tableCtx.tableId], tableCtx.rowIndex);\n\n\t// Move cursor to cell in adjacent row\n\tconst targetRowIndex: number = tableCtx.rowIndex > 0 ? tableCtx.rowIndex - 1 : 0;\n\tconst targetCellId: BlockId | null = getCellAt(\n\t\tstate,\n\t\ttableCtx.tableId,\n\t\ttargetRowIndex === tableCtx.rowIndex ? targetRowIndex + 1 : targetRowIndex,\n\t\tMath.min(tableCtx.colIndex, tableCtx.totalCols - 1),\n\t);\n\n\tif (targetCellId) {\n\t\ttr.setSelection(createCollapsedSelection(targetCellId, 0));\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/**\n * Deletes the current column. If it's the last column, deletes the entire table.\n */\nexport function deleteColumn(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tif (tableCtx.totalCols <= 1) {\n\t\treturn deleteTable(context);\n\t}\n\n\tconst table = state.getBlock(tableCtx.tableId);\n\tif (!table) return false;\n\n\tconst rows = getBlockChildren(table);\n\tconst tr = state.transaction('command');\n\n\t// Remove the cell at colIndex from each row (reverse order for index stability)\n\tfor (let r = rows.length - 1; r >= 0; r--) {\n\t\tconst row = rows[r];\n\t\tif (!row) continue;\n\t\ttr.removeNode([tableCtx.tableId, row.id], tableCtx.colIndex);\n\t}\n\n\t// Move cursor to adjacent cell\n\tconst targetColIndex: number = tableCtx.colIndex > 0 ? tableCtx.colIndex - 1 : 0;\n\tconst targetCellId: BlockId | null = getCellAt(\n\t\tstate,\n\t\ttableCtx.tableId,\n\t\ttableCtx.rowIndex,\n\t\ttargetColIndex === tableCtx.colIndex ? targetColIndex + 1 : targetColIndex,\n\t);\n\n\tif (targetCellId) {\n\t\ttr.setSelection(createCollapsedSelection(targetCellId, 0));\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/** Deletes the entire table and moves cursor to surrounding block. */\nexport function deleteTable(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tconst tr = state.transaction('command').removeNode([], tableCtx.tableIndex);\n\n\t// Move cursor to block after the table, or before if none after\n\tconst blockAfterIndex: number = tableCtx.tableIndex;\n\tconst blockBeforeIndex: number = tableCtx.tableIndex - 1;\n\n\tif (blockAfterIndex < state.doc.children.length - 1) {\n\t\tconst afterBlock = state.doc.children[blockAfterIndex + 1];\n\t\tif (afterBlock) {\n\t\t\ttr.setSelection(createCollapsedSelection(afterBlock.id, 0));\n\t\t}\n\t} else if (blockBeforeIndex >= 0) {\n\t\tconst beforeBlock = state.doc.children[blockBeforeIndex];\n\t\tif (beforeBlock) {\n\t\t\ttr.setSelection(createCollapsedSelection(beforeBlock.id, 0));\n\t\t}\n\t}\n\n\tcontext.dispatch(tr.build());\n\treturn true;\n}\n\n/** Registers all table commands on the given plugin context. */\nexport function registerTableCommands(context: PluginContext): void {\n\tcontext.registerCommand('insertTable', () => insertTable(context, 3, 3));\n\tcontext.registerCommand('addRowAbove', () => addRowAbove(context));\n\tcontext.registerCommand('addRowBelow', () => addRowBelow(context));\n\tcontext.registerCommand('addColumnLeft', () => addColumnLeft(context));\n\tcontext.registerCommand('addColumnRight', () => addColumnRight(context));\n\tcontext.registerCommand('deleteRow', () => deleteRow(context));\n\tcontext.registerCommand('deleteColumn', () => deleteColumn(context));\n\tcontext.registerCommand('deleteTable', () => deleteTable(context));\n}\n","/**\n * Keyboard navigation handlers for table cells.\n * Handles Tab, Shift-Tab, arrow keys, Enter, Backspace, Delete, and Escape.\n */\n\nimport type { Keymap } from '../../input/Keymap.js';\nimport { getBlockLength } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { addRowBelow } from './TableCommands.js';\nimport { type TableContext, findTableContext, getCellAt, isInsideTable } from './TableHelpers.js';\n\n/** Registers all table navigation keymaps. */\nexport function registerTableKeymaps(context: PluginContext): void {\n\tconst keymap: Keymap = {\n\t\tTab: () => handleTab(context),\n\t\t'Shift-Tab': () => handleShiftTab(context),\n\t\tEnter: () => handleEnter(context),\n\t\tBackspace: () => handleBackspace(context),\n\t\tDelete: () => handleDelete(context),\n\t\tArrowDown: () => handleArrowDown(context),\n\t\tArrowUp: () => handleArrowUp(context),\n\t\tArrowRight: () => handleArrowRight(context),\n\t\tArrowLeft: () => handleArrowLeft(context),\n\t\tEscape: () => handleEscape(context),\n\t};\n\n\tcontext.registerKeymap(keymap);\n}\n\n/** Tab: move to next cell. At end of table, add a new row. */\nfunction handleTab(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Try next cell in same row\n\tif (tableCtx.colIndex < tableCtx.totalCols - 1) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex, tableCtx.colIndex + 1);\n\t}\n\n\t// Try first cell in next row\n\tif (tableCtx.rowIndex < tableCtx.totalRows - 1) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex + 1, 0);\n\t}\n\n\t// At end of table — add a new row and move there\n\taddRowBelow(context);\n\treturn true;\n}\n\n/** Shift-Tab: move to previous cell. At start of table, return false. */\nfunction handleShiftTab(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Try previous cell in same row\n\tif (tableCtx.colIndex > 0) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex, tableCtx.colIndex - 1);\n\t}\n\n\t// Try last cell in previous row\n\tif (tableCtx.rowIndex > 0) {\n\t\treturn moveToCellAndSelect(\n\t\t\tcontext,\n\t\t\ttableCtx.tableId,\n\t\t\ttableCtx.rowIndex - 1,\n\t\t\ttableCtx.totalCols - 1,\n\t\t);\n\t}\n\n\t// At start of table — stay put\n\treturn true;\n}\n\n/** Enter: move to same column in next row (spreadsheet behavior). */\nfunction handleEnter(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Move to same column in next row\n\tif (tableCtx.rowIndex < tableCtx.totalRows - 1) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex + 1, tableCtx.colIndex);\n\t}\n\n\t// On last row — block to prevent splitBlock\n\treturn true;\n}\n\n/** Backspace at cell start: block to prevent mergeBlockBackward. */\nfunction handleBackspace(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\tif (sel.anchor.offset !== 0) return false;\n\n\treturn isInsideTable(state, sel.anchor.blockId);\n}\n\n/** Delete at cell end: block to prevent mergeBlockForward. */\nfunction handleDelete(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tconst blockLen: number = getBlockLength(block);\n\tif (sel.anchor.offset !== blockLen) return false;\n\n\treturn isInsideTable(state, sel.anchor.blockId);\n}\n\n/** ArrowDown: move to same column in next row. */\nfunction handleArrowDown(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tif (tableCtx.rowIndex >= tableCtx.totalRows - 1) {\n\t\t// At last row — move cursor to paragraph after table\n\t\treturn handleEscape(context);\n\t}\n\n\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex + 1, tableCtx.colIndex);\n}\n\n/** ArrowUp: move to same column in previous row. */\nfunction handleArrowUp(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\tif (tableCtx.rowIndex <= 0) {\n\t\t// At first row — let default behavior handle it\n\t\treturn false;\n\t}\n\n\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex - 1, tableCtx.colIndex);\n}\n\n/** ArrowRight at cell end: move to next cell. */\nfunction handleArrowRight(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tconst blockLen: number = getBlockLength(block);\n\tif (sel.anchor.offset !== blockLen) return false;\n\n\tconst tableCtx: TableContext | null = findTableContext(state, sel.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Try next cell in same row\n\tif (tableCtx.colIndex < tableCtx.totalCols - 1) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex, tableCtx.colIndex + 1);\n\t}\n\n\t// Try first cell in next row\n\tif (tableCtx.rowIndex < tableCtx.totalRows - 1) {\n\t\treturn moveToCellAndSelect(context, tableCtx.tableId, tableCtx.rowIndex + 1, 0);\n\t}\n\n\treturn true;\n}\n\n/** ArrowLeft at cell start: move to previous cell. */\nfunction handleArrowLeft(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\tif (sel.anchor.offset !== 0) return false;\n\n\tconst tableCtx: TableContext | null = findTableContext(state, sel.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Try previous cell in same row\n\tif (tableCtx.colIndex > 0) {\n\t\treturn moveToCellAtEnd(context, tableCtx.tableId, tableCtx.rowIndex, tableCtx.colIndex - 1);\n\t}\n\n\t// Try last cell in previous row\n\tif (tableCtx.rowIndex > 0) {\n\t\treturn moveToCellAtEnd(\n\t\t\tcontext,\n\t\t\ttableCtx.tableId,\n\t\t\ttableCtx.rowIndex - 1,\n\t\t\ttableCtx.totalCols - 1,\n\t\t);\n\t}\n\n\treturn true;\n}\n\n/** Escape: move cursor to the paragraph after the table. */\nfunction handleEscape(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst tableCtx: TableContext | null = findTableContext(state, state.selection.anchor.blockId);\n\tif (!tableCtx) return false;\n\n\t// Find the block after the table\n\tconst nextIndex: number = tableCtx.tableIndex + 1;\n\tif (nextIndex < state.doc.children.length) {\n\t\tconst nextBlock = state.doc.children[nextIndex];\n\t\tif (!nextBlock) return false;\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setSelection(createCollapsedSelection(nextBlock.id, 0))\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/** Moves cursor to the start of a cell. */\nfunction moveToCellAndSelect(\n\tcontext: PluginContext,\n\ttableId: BlockId,\n\trowIndex: number,\n\tcolIndex: number,\n): boolean {\n\tconst state = context.getState();\n\tconst cellId: BlockId | null = getCellAt(state, tableId, rowIndex, colIndex);\n\tif (!cellId) return false;\n\n\tconst tr = state.transaction('command').setSelection(createCollapsedSelection(cellId, 0)).build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\n/** Moves cursor to the end of a cell (for ArrowLeft navigation). */\nfunction moveToCellAtEnd(\n\tcontext: PluginContext,\n\ttableId: BlockId,\n\trowIndex: number,\n\tcolIndex: number,\n): boolean {\n\tconst state = context.getState();\n\tconst cellId: BlockId | null = getCellAt(state, tableId, rowIndex, colIndex);\n\tif (!cellId) return false;\n\n\tconst cell = state.getBlock(cellId);\n\tif (!cell) return false;\n\n\tconst cellLen: number = getBlockLength(cell);\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setSelection(createCollapsedSelection(cellId, cellLen))\n\t\t.build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n","/**\n * Reconciler: diffs old and new state and applies minimal DOM patches.\n * Uses block-level granularity — changed blocks are re-rendered entirely.\n * Supports plugin-registered NodeSpecs, MarkSpecs, and NodeViews via SchemaRegistry.\n */\n\nimport type { Decoration, DecorationAttrs, InlineDecoration } from '../decorations/Decoration.js';\nimport { type DecorationSet, decorationArraysEqual } from '../decorations/Decoration.js';\nimport type { MarkAttrsFor, NodeAttrsFor } from '../model/AttrRegistry.js';\nimport type { BlockNode, InlineNode, Mark, TextNode } from '../model/Document.js';\nimport {\n\tgetBlockChildren,\n\tgetInlineChildren,\n\tisInlineNode,\n\tisLeafBlock,\n\tisTextNode,\n\tmarkSetsEqual,\n} from '../model/Document.js';\nimport { createBlockElement } from '../model/NodeSpec.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport { blockId as toBlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { NodeView } from './NodeView.js';\n\nexport interface ReconcileOptions {\n\tregistry?: SchemaRegistry;\n\tnodeViews?: Map<string, NodeView>;\n\tgetState?: () => EditorState;\n\tdispatch?: (tr: import('../state/Transaction.js').Transaction) => void;\n\tdecorations?: DecorationSet;\n\toldDecorations?: DecorationSet;\n}\n\n/** Reconciles the DOM container to match the new state. */\nexport function reconcile(\n\tcontainer: HTMLElement,\n\toldState: EditorState | null,\n\tnewState: EditorState,\n\toptions?: ReconcileOptions,\n): void {\n\tconst oldBlocks = oldState?.doc.children ?? [];\n\tconst newBlocks = newState.doc.children;\n\tconst registry = options?.registry;\n\tconst nodeViews = options?.nodeViews;\n\n\tconst oldBlockMap = new Map<BlockId, HTMLElement>();\n\tfor (const child of Array.from(container.children)) {\n\t\tconst el = child as HTMLElement;\n\t\tconst bid = el.getAttribute('data-block-id');\n\t\tif (bid) {\n\t\t\toldBlockMap.set(toBlockId(bid), el);\n\t\t}\n\t}\n\n\t// Build set of new block IDs for removal detection\n\tconst newBlockIds = new Set(newBlocks.map((b) => b.id));\n\n\t// Remove blocks that no longer exist\n\tfor (const [blockId, el] of oldBlockMap) {\n\t\tif (!newBlockIds.has(blockId)) {\n\t\t\tcontainer.removeChild(el);\n\t\t\toldBlockMap.delete(blockId);\n\t\t\t// Destroy NodeView if exists\n\t\t\tconst nv = nodeViews?.get(blockId);\n\t\t\tif (nv) {\n\t\t\t\tnv.destroy?.();\n\t\t\t\tnodeViews?.delete(blockId);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Mapping from old state for change detection\n\tconst oldBlockById = new Map<string, BlockNode>();\n\tfor (const block of oldBlocks) {\n\t\toldBlockById.set(block.id, block);\n\t}\n\n\t// Insert/update blocks in order\n\tlet previousSibling: Element | null = null;\n\n\tfor (const block of newBlocks) {\n\t\tconst existingEl = oldBlockMap.get(block.id);\n\t\tconst oldBlock = oldBlockById.get(block.id);\n\n\t\tconst oldDecos = options?.oldDecorations?.find(block.id);\n\t\tconst newDecos = options?.decorations?.find(block.id);\n\n\t\tif (existingEl && oldBlock && !blockChanged(oldBlock, block, oldDecos, newDecos)) {\n\t\t\t// Block unchanged — keep existing DOM\n\t\t\tpreviousSibling = existingEl;\n\t\t} else if (existingEl) {\n\t\t\t// Block changed — try NodeView update first\n\t\t\tconst existingNv = nodeViews?.get(block.id);\n\t\t\tif (existingNv) {\n\t\t\t\tconst handled = existingNv.update?.(block) ?? false;\n\t\t\t\tif (handled) {\n\t\t\t\t\tpreviousSibling = existingNv.dom;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// Update not handled — destroy and re-create\n\t\t\t\texistingNv.destroy?.();\n\t\t\t\tnodeViews?.delete(block.id);\n\t\t\t}\n\n\t\t\tconst newEl = renderBlock(block, registry, nodeViews, options);\n\t\t\tcontainer.replaceChild(newEl, existingEl);\n\t\t\tpreviousSibling = newEl;\n\t\t} else {\n\t\t\t// New block — insert after previousSibling\n\t\t\tconst newEl = renderBlock(block, registry, nodeViews, options);\n\t\t\tif (previousSibling?.nextSibling) {\n\t\t\t\tcontainer.insertBefore(newEl, previousSibling.nextSibling);\n\t\t\t} else if (!previousSibling && container.firstChild) {\n\t\t\t\tcontainer.insertBefore(newEl, container.firstChild);\n\t\t\t} else {\n\t\t\t\tcontainer.appendChild(newEl);\n\t\t\t}\n\t\t\tpreviousSibling = newEl;\n\t\t}\n\t}\n}\n\n/** Checks whether a block has changed by comparing its children, attrs, and decorations. */\nfunction blockChanged(\n\toldBlock: BlockNode,\n\tnewBlock: BlockNode,\n\toldDecos?: readonly Decoration[],\n\tnewDecos?: readonly Decoration[],\n): boolean {\n\tif (oldBlock.type !== newBlock.type) return true;\n\tif (oldBlock.children.length !== newBlock.children.length) return true;\n\n\t// Compare attrs\n\tconst oldAttrs = oldBlock.attrs;\n\tconst newAttrs = newBlock.attrs;\n\tif (oldAttrs !== newAttrs) {\n\t\tif (!oldAttrs || !newAttrs) return true;\n\t\tconst oldKeys = Object.keys(oldAttrs);\n\t\tconst newKeys = Object.keys(newAttrs);\n\t\tif (oldKeys.length !== newKeys.length) return true;\n\t\tfor (const key of oldKeys) {\n\t\t\tif (oldAttrs[key] !== newAttrs[key]) return true;\n\t\t}\n\t}\n\n\tfor (let i = 0; i < oldBlock.children.length; i++) {\n\t\tconst oldChild = oldBlock.children[i];\n\t\tconst newChild = newBlock.children[i];\n\t\tif (!oldChild || !newChild) return true;\n\n\t\tif (isTextNode(oldChild) && isTextNode(newChild)) {\n\t\t\tif (oldChild.text !== newChild.text) return true;\n\t\t\tif (!markSetsEqual(oldChild.marks, newChild.marks)) return true;\n\t\t} else if (isInlineNode(oldChild) && isInlineNode(newChild)) {\n\t\t\tif (oldChild.inlineType !== newChild.inlineType) return true;\n\t\t\tif (!inlineAttrsEqual(oldChild.attrs, newChild.attrs)) return true;\n\t\t} else if (\n\t\t\t!isTextNode(oldChild) &&\n\t\t\t!isTextNode(newChild) &&\n\t\t\t!isInlineNode(oldChild) &&\n\t\t\t!isInlineNode(newChild)\n\t\t) {\n\t\t\t// Both are BlockNodes — compare recursively\n\t\t\tif (blockChanged(oldChild as BlockNode, newChild as BlockNode)) return true;\n\t\t} else {\n\t\t\t// Different child types\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t// Compare decorations\n\tconst oldArr = oldDecos ?? [];\n\tconst newArr = newDecos ?? [];\n\tif (oldArr !== newArr && !decorationArraysEqual(oldArr, newArr)) return true;\n\n\treturn false;\n}\n\n/** Renders a block node to a DOM element, using registry specs or NodeViews. */\nexport function renderBlock(\n\tblock: BlockNode,\n\tregistry?: SchemaRegistry,\n\tnodeViews?: Map<string, NodeView>,\n\toptions?: ReconcileOptions,\n): HTMLElement {\n\tconst inlineDecos = options?.decorations?.findInline(block.id);\n\n\t// 1. Try NodeViewFactory\n\tif (registry && nodeViews && options?.getState && options?.dispatch) {\n\t\tconst factory = registry.getNodeViewFactory(block.type);\n\t\tif (factory) {\n\t\t\tconst nv = factory(block, options.getState, options.dispatch);\n\t\t\tnodeViews.set(block.id, nv);\n\n\t\t\t// Recursively render block children into NodeView content areas\n\t\t\tconst blockChildren = getBlockChildren(block);\n\t\t\tfor (const child of blockChildren) {\n\t\t\t\tconst contentDOM = nv.getContentDOM?.(child.id) ?? nv.contentDOM;\n\t\t\t\tif (contentDOM) {\n\t\t\t\t\tconst childEl = renderBlock(child, registry, nodeViews, options);\n\t\t\t\t\tcontentDOM.appendChild(childEl);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tapplyNodeDecorations(nv.dom, block.id, options);\n\t\t\treturn nv.dom;\n\t\t}\n\t}\n\n\t// 2. Try NodeSpec\n\tif (registry) {\n\t\tconst spec = registry.getNodeSpec(block.type);\n\t\tif (spec) {\n\t\t\tconst el = spec.toDOM(\n\t\t\t\tblock as Omit<BlockNode, 'attrs'> & { readonly attrs: NodeAttrsFor<string> },\n\t\t\t);\n\t\t\tif (!spec.isVoid) {\n\t\t\t\tif (isLeafBlock(block)) {\n\t\t\t\t\trenderBlockContent(el, block, registry, inlineDecos);\n\t\t\t\t} else {\n\t\t\t\t\t// Render block children recursively\n\t\t\t\t\tconst blockChildren = getBlockChildren(block);\n\t\t\t\t\tfor (const child of blockChildren) {\n\t\t\t\t\t\tconst childEl = renderBlock(child, registry, nodeViews, options);\n\t\t\t\t\t\tel.appendChild(childEl);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tapplyNodeDecorations(el, block.id, options);\n\t\t\treturn el;\n\t\t}\n\t}\n\n\t// 3. Fallback — render as paragraph\n\treturn renderParagraphFallback(block, registry, inlineDecos);\n}\n\n/** Renders block content (inline children) into a container element. */\nexport function renderBlockContent(\n\tcontainer: HTMLElement,\n\tblock: BlockNode,\n\tregistry?: SchemaRegistry,\n\tinlineDecos?: readonly InlineDecoration[],\n): void {\n\tconst inlineChildren = getInlineChildren(block);\n\n\t// Empty block: single empty text node → render <br> placeholder\n\tif (\n\t\tinlineChildren.length === 1 &&\n\t\tisTextNode(inlineChildren[0]) &&\n\t\tinlineChildren[0].text === ''\n\t) {\n\t\tcontainer.appendChild(document.createElement('br'));\n\t\treturn;\n\t}\n\n\t// Fast path: no inline decorations\n\tif (!inlineDecos || inlineDecos.length === 0) {\n\t\tfor (const child of inlineChildren) {\n\t\t\tif (isTextNode(child)) {\n\t\t\t\tcontainer.appendChild(renderTextNode(child, registry));\n\t\t\t} else {\n\t\t\t\tcontainer.appendChild(renderInlineNode(child, registry));\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\n\t// Decorated path: split content into micro-segments\n\trenderDecoratedContent(container, inlineChildren, inlineDecos, registry);\n}\n\n/** Fallback paragraph rendering when no NodeSpec is found. */\nfunction renderParagraphFallback(\n\tblock: BlockNode,\n\tregistry?: SchemaRegistry,\n\tinlineDecos?: readonly InlineDecoration[],\n): HTMLElement {\n\tconst p = createBlockElement('p', block.id);\n\trenderBlockContent(p, block, registry, inlineDecos);\n\treturn p;\n}\n\n/**\n * Converts spaces for contenteditable rendering.\n * Trailing spaces and double spaces are replaced with \\u00a0 (non-breaking space)\n * to prevent the browser from collapsing them.\n */\nfunction preserveSpaces(text: string): string {\n\t// Replace consecutive spaces: alternate regular and non-breaking\n\tlet result = text.replace(/ {2}/g, ' \\u00a0');\n\t// If the text ends with a space, replace it with nbsp\n\tif (result.endsWith(' ')) {\n\t\tresult = `${result.slice(0, -1)}\\u00a0`;\n\t}\n\t// If the text starts with a space, replace it with nbsp\n\tif (result.startsWith(' ')) {\n\t\tresult = `\\u00a0${result.slice(1)}`;\n\t}\n\treturn result;\n}\n\n/** Renders a text node with marks as nested inline elements. */\nfunction renderTextNode(node: TextNode, registry?: SchemaRegistry): Node {\n\tif (node.text === '') {\n\t\treturn document.createTextNode('');\n\t}\n\n\tconst textNode = document.createTextNode(preserveSpaces(node.text));\n\n\tif (node.marks.length === 0) {\n\t\treturn textNode;\n\t}\n\n\t// Sort marks: use MarkSpec.rank if available, otherwise fallback order\n\tconst sortedMarks = [...node.marks].sort(\n\t\t(a, b) => markOrder(a, registry) - markOrder(b, registry),\n\t);\n\n\tlet current: Node = textNode;\n\n\t// Wrap from inside out (last mark is outermost)\n\tfor (let i = sortedMarks.length - 1; i >= 0; i--) {\n\t\tconst mark = sortedMarks[i];\n\t\tif (!mark) continue;\n\t\tconst el = createMarkElement(mark, registry);\n\t\tel.appendChild(current);\n\t\tcurrent = el;\n\t}\n\n\treturn current;\n}\n\n/** Renders an InlineNode, using InlineNodeSpec.toDOM() or a fallback element. */\nfunction renderInlineNode(node: InlineNode, registry?: SchemaRegistry): HTMLElement {\n\tif (registry) {\n\t\tconst spec = registry.getInlineNodeSpec(node.inlineType);\n\t\tif (spec) {\n\t\t\tconst el = spec.toDOM(node);\n\t\t\tel.setAttribute('contenteditable', 'false');\n\t\t\treturn el;\n\t\t}\n\t}\n\t// Fallback: generic non-editable span\n\tconst el = document.createElement('span');\n\tel.setAttribute('data-inline-type', node.inlineType);\n\tel.setAttribute('contenteditable', 'false');\n\treturn el;\n}\n\n/** Compares two InlineNode attr records for equality. */\nfunction inlineAttrsEqual(\n\ta: Readonly<Record<string, string | number | boolean>>,\n\tb: Readonly<Record<string, string | number | boolean>>,\n): boolean {\n\tconst aKeys = Object.keys(a);\n\tconst bKeys = Object.keys(b);\n\tif (aKeys.length !== bKeys.length) return false;\n\tfor (const key of aKeys) {\n\t\tif (a[key] !== b[key]) return false;\n\t}\n\treturn true;\n}\n\nfunction markOrder(mark: Mark, registry?: SchemaRegistry): number {\n\tif (registry) {\n\t\tconst spec = registry.getMarkSpec(mark.type);\n\t\tif (spec) return spec.rank ?? 100;\n\t}\n\t// Fallback order for built-in marks\n\tswitch (mark.type) {\n\t\tcase 'bold':\n\t\t\treturn 0;\n\t\tcase 'italic':\n\t\t\treturn 1;\n\t\tcase 'underline':\n\t\t\treturn 2;\n\t\tdefault:\n\t\t\treturn 100;\n\t}\n}\n\nfunction createMarkElement(mark: Mark, registry?: SchemaRegistry): HTMLElement {\n\tif (registry) {\n\t\tconst spec = registry.getMarkSpec(mark.type);\n\t\tif (spec)\n\t\t\treturn spec.toDOM(mark as Omit<Mark, 'attrs'> & { readonly attrs: MarkAttrsFor<string> });\n\t}\n\t// Fallback for built-in marks\n\tswitch (mark.type) {\n\t\tcase 'bold':\n\t\t\treturn document.createElement('strong');\n\t\tcase 'italic':\n\t\t\treturn document.createElement('em');\n\t\tcase 'underline':\n\t\t\treturn document.createElement('u');\n\t\tdefault:\n\t\t\treturn document.createElement('span');\n\t}\n}\n\n// --- Decoration Rendering ---\n\n/**\n * Renders inline content with decorations. InlineNodes are width-1 split points\n * rendered as their own elements (not wrapped by decorations).\n *\n * For each child:\n * - TextNode: split by decoration boundaries, render text → marks → decorations\n * - InlineNode: render directly without decoration wrapping\n */\nfunction renderDecoratedContent(\n\tcontainer: HTMLElement,\n\tinlineChildren: readonly (TextNode | InlineNode)[],\n\tinlineDecos: readonly InlineDecoration[],\n\tregistry?: SchemaRegistry,\n): void {\n\tlet globalOffset = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tif (isInlineNode(child)) {\n\t\t\t// InlineNodes are rendered directly, not wrapped by decorations\n\t\t\tcontainer.appendChild(renderInlineNode(child, registry));\n\t\t\tglobalOffset += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// TextNode: split by decoration boundaries within this node's range\n\t\tconst textFrom = globalOffset;\n\t\tconst textTo = globalOffset + child.text.length;\n\n\t\tif (child.text.length === 0) {\n\t\t\tglobalOffset = textTo;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Find split points within this text range\n\t\tconst splitSet = new Set<number>();\n\t\tsplitSet.add(textFrom);\n\t\tsplitSet.add(textTo);\n\t\tfor (const deco of inlineDecos) {\n\t\t\tconst dFrom = Math.max(textFrom, deco.from);\n\t\t\tconst dTo = Math.min(textTo, deco.to);\n\t\t\tif (dFrom > textFrom && dFrom < textTo) splitSet.add(dFrom);\n\t\t\tif (dTo > textFrom && dTo < textTo) splitSet.add(dTo);\n\t\t}\n\t\tconst splits = [...splitSet].sort((a, b) => a - b);\n\n\t\t// Render micro-segments\n\t\tfor (let i = 0; i < splits.length - 1; i++) {\n\t\t\tconst from = splits[i];\n\t\t\tconst to = splits[i + 1];\n\t\t\tif (from === undefined || to === undefined || from >= to) continue;\n\n\t\t\tconst localFrom = from - textFrom;\n\t\t\tconst localTo = to - textFrom;\n\t\t\tconst text = child.text.slice(localFrom, localTo);\n\n\t\t\t// Find decorations that fully cover this micro-segment\n\t\t\tconst activeDecos: InlineDecoration[] = [];\n\t\t\tfor (const deco of inlineDecos) {\n\t\t\t\tif (deco.from <= from && deco.to >= to) {\n\t\t\t\t\tactiveDecos.push(deco);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Render: text → marks (inner) → decorations (outer)\n\t\t\tconst textNode = document.createTextNode(preserveSpaces(text));\n\t\t\tlet current: Node = textNode;\n\n\t\t\t// Wrap with marks (innermost to outermost)\n\t\t\tif (child.marks.length > 0) {\n\t\t\t\tconst sortedMarks = [...child.marks].sort(\n\t\t\t\t\t(a, b) => markOrder(a, registry) - markOrder(b, registry),\n\t\t\t\t);\n\t\t\t\tfor (let j = sortedMarks.length - 1; j >= 0; j--) {\n\t\t\t\t\tconst mark = sortedMarks[j];\n\t\t\t\t\tif (!mark) continue;\n\t\t\t\t\tconst el = createMarkElement(mark, registry);\n\t\t\t\t\tel.appendChild(current);\n\t\t\t\t\tcurrent = el;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Wrap with decorations (outermost)\n\t\t\tfor (const deco of activeDecos) {\n\t\t\t\tconst el = createDecorationElement(deco.attrs);\n\t\t\t\tel.appendChild(current);\n\t\t\t\tcurrent = el;\n\t\t\t}\n\n\t\t\tcontainer.appendChild(current);\n\t\t}\n\n\t\tglobalOffset = textTo;\n\t}\n}\n\n/** Creates a DOM element for an inline decoration. */\nfunction createDecorationElement(attrs: DecorationAttrs): HTMLElement {\n\tconst tagName = attrs.nodeName ?? 'span';\n\tconst el = document.createElement(tagName);\n\tel.setAttribute('data-decoration', 'true');\n\n\tif (attrs.class) {\n\t\tfor (const cls of attrs.class.split(' ')) {\n\t\t\tif (cls) el.classList.add(cls);\n\t\t}\n\t}\n\tif (attrs.style) {\n\t\tel.style.cssText = attrs.style;\n\t}\n\n\t// Apply any other custom attributes\n\tfor (const [key, value] of Object.entries(attrs)) {\n\t\tif (key === 'class' || key === 'style' || key === 'nodeName') continue;\n\t\tif (value !== undefined) {\n\t\t\tel.setAttribute(key, value);\n\t\t}\n\t}\n\n\treturn el;\n}\n\n/** Applies node decorations (CSS classes/styles) to a block element. */\nfunction applyNodeDecorations(el: HTMLElement, bid: BlockId, options?: ReconcileOptions): void {\n\tconst nodeDecos = options?.decorations?.findNode(bid);\n\tif (!nodeDecos || nodeDecos.length === 0) return;\n\n\tfor (const deco of nodeDecos) {\n\t\tif (deco.attrs.class) {\n\t\t\tfor (const cls of deco.attrs.class.split(' ')) {\n\t\t\t\tif (cls) el.classList.add(cls);\n\t\t\t}\n\t\t}\n\t\tif (deco.attrs.style) {\n\t\t\tconst current: string = el.style.cssText;\n\t\t\tel.style.cssText = current ? `${current}; ${deco.attrs.style}` : deco.attrs.style;\n\t\t}\n\t}\n}\n","/**\n * Interactive table controls: floating insert lines between borders,\n * add row/column buttons at edges, and column/row handles with delete.\n * All controls appear on hover with smooth CSS animations.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { getBlockChildren } from '../../model/Document.js';\nimport { createCollapsedSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport { createTableCell, createTableRow, getCellAt } from './TableHelpers.js';\n\n// --- SVG Icons ---\n\nconst PLUS_SVG: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" ' +\n\t'viewBox=\"0 0 12 12\" fill=\"none\">' +\n\t'<path d=\"M6 1v10M1 6h10\" stroke=\"currentColor\" ' +\n\t'stroke-width=\"1.8\" stroke-linecap=\"round\"/></svg>';\n\nconst DELETE_SVG: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" ' +\n\t'viewBox=\"0 0 10 10\" fill=\"none\">' +\n\t'<path d=\"M2 2l6 6M8 2l-6 6\" stroke=\"currentColor\" ' +\n\t'stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>';\n\n// --- Constants ---\n\nconst BORDER_THRESHOLD: number = 10;\n\n// --- Types ---\n\nexport interface TableControlsHandle {\n\tupdate(node: BlockNode): void;\n\tdestroy(): void;\n}\n\ninterface BorderInfo {\n\treadonly position: number;\n\treadonly index: number;\n}\n\n// --- Transaction Helpers ---\n\nfunction insertRowAtIndex(\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n\ttableId: BlockId,\n\trowIndex: number,\n): void {\n\tconst state: EditorState = getState();\n\tconst table: BlockNode | undefined = state.getBlock(tableId);\n\tif (!table) return;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tconst numCols: number = rows[0] ? getBlockChildren(rows[0]).length : 0;\n\tif (numCols === 0) return;\n\n\tconst newRow: BlockNode = createTableRow(numCols);\n\tconst firstCell: BlockNode | undefined = getBlockChildren(newRow)[0];\n\n\tconst tr = state.transaction('command').insertNode([tableId], rowIndex, newRow);\n\n\tif (firstCell) {\n\t\ttr.setSelection(createCollapsedSelection(firstCell.id, 0));\n\t}\n\n\tdispatch(tr.build());\n}\n\nfunction insertColumnAtIndex(\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n\ttableId: BlockId,\n\tcolIndex: number,\n): void {\n\tconst state: EditorState = getState();\n\tconst table: BlockNode | undefined = state.getBlock(tableId);\n\tif (!table) return;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tconst tr = state.transaction('command');\n\n\tfor (const row of rows) {\n\t\tconst newCell: BlockNode = createTableCell();\n\t\ttr.insertNode([tableId, row.id], colIndex, newCell);\n\t}\n\n\ttr.setSelection(state.selection);\n\tdispatch(tr.build());\n}\n\nfunction deleteRowAtIndex(\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n\ttableId: BlockId,\n\trowIndex: number,\n): void {\n\tconst state: EditorState = getState();\n\tconst table: BlockNode | undefined = state.getBlock(tableId);\n\tif (!table) return;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tif (rows.length <= 1) {\n\t\tdeleteEntireTable(getState, dispatch, tableId);\n\t\treturn;\n\t}\n\n\tconst tr = state.transaction('command').removeNode([tableId], rowIndex);\n\n\tconst targetRow: number = rowIndex > 0 ? rowIndex - 1 : 1;\n\tconst cellId: BlockId | null = getCellAt(state, tableId, targetRow, 0);\n\tif (cellId) {\n\t\ttr.setSelection(createCollapsedSelection(cellId, 0));\n\t}\n\n\tdispatch(tr.build());\n}\n\nfunction deleteColumnAtIndex(\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n\ttableId: BlockId,\n\tcolIndex: number,\n): void {\n\tconst state: EditorState = getState();\n\tconst table: BlockNode | undefined = state.getBlock(tableId);\n\tif (!table) return;\n\n\tconst rows: readonly BlockNode[] = getBlockChildren(table);\n\tconst numCols: number = rows[0] ? getBlockChildren(rows[0]).length : 0;\n\n\tif (numCols <= 1) {\n\t\tdeleteEntireTable(getState, dispatch, tableId);\n\t\treturn;\n\t}\n\n\tconst tr = state.transaction('command');\n\n\tfor (let r: number = rows.length - 1; r >= 0; r--) {\n\t\tconst row: BlockNode | undefined = rows[r];\n\t\tif (!row) continue;\n\t\ttr.removeNode([tableId, row.id], colIndex);\n\t}\n\n\tconst targetCol: number = colIndex > 0 ? colIndex - 1 : 1;\n\tconst cellId: BlockId | null = getCellAt(state, tableId, 0, targetCol);\n\tif (cellId) {\n\t\ttr.setSelection(createCollapsedSelection(cellId, 0));\n\t}\n\n\tdispatch(tr.build());\n}\n\nfunction deleteEntireTable(\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n\ttableId: BlockId,\n): void {\n\tconst state: EditorState = getState();\n\tconst tableIndex: number = state.doc.children.findIndex((b) => b.id === tableId);\n\tif (tableIndex === -1) return;\n\n\tconst tr = state.transaction('command').removeNode([], tableIndex);\n\n\tif (tableIndex < state.doc.children.length - 1) {\n\t\tconst after: BlockNode | undefined = state.doc.children[tableIndex + 1];\n\t\tif (after) {\n\t\t\ttr.setSelection(createCollapsedSelection(after.id, 0));\n\t\t}\n\t} else if (tableIndex > 0) {\n\t\tconst before: BlockNode | undefined = state.doc.children[tableIndex - 1];\n\t\tif (before) {\n\t\t\ttr.setSelection(createCollapsedSelection(before.id, 0));\n\t\t}\n\t}\n\n\tdispatch(tr.build());\n}\n\n// --- DOM Builders ---\n\nfunction createButton(className: string, innerHTML: string, title: string): HTMLButtonElement {\n\tconst btn: HTMLButtonElement = document.createElement('button');\n\tbtn.className = className;\n\tbtn.innerHTML = innerHTML;\n\tbtn.title = title;\n\tbtn.type = 'button';\n\tbtn.setAttribute('contenteditable', 'false');\n\tbtn.addEventListener('mousedown', (e: MouseEvent) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t});\n\treturn btn;\n}\n\nfunction buildInsertLine(orientation: 'horizontal' | 'vertical'): HTMLDivElement {\n\tconst line: HTMLDivElement = document.createElement('div');\n\tline.className = `ntbl-insert-line ntbl-insert-line--${orientation}`;\n\tline.setAttribute('contenteditable', 'false');\n\n\tconst title: string = orientation === 'horizontal' ? 'Insert row' : 'Insert column';\n\tconst btn: HTMLButtonElement = createButton('ntbl-insert-btn', PLUS_SVG, title);\n\tline.appendChild(btn);\n\n\treturn line;\n}\n\nfunction buildAddButton(className: string, title: string): HTMLDivElement {\n\tconst container: HTMLDivElement = document.createElement('div');\n\tcontainer.className = `ntbl-add-zone ${className}`;\n\tcontainer.setAttribute('contenteditable', 'false');\n\tcontainer.title = title;\n\n\tconst icon: HTMLSpanElement = document.createElement('span');\n\ticon.className = 'ntbl-add-icon';\n\ticon.innerHTML = PLUS_SVG;\n\tcontainer.appendChild(icon);\n\n\tcontainer.addEventListener('mousedown', (e: MouseEvent) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t});\n\n\treturn container;\n}\n\nfunction buildHandleBar(className: string): HTMLDivElement {\n\tconst bar: HTMLDivElement = document.createElement('div');\n\tbar.className = className;\n\tbar.setAttribute('contenteditable', 'false');\n\treturn bar;\n}\n\nfunction buildHandle(\n\tclassName: string,\n\tindex: number,\n\tonDelete: (idx: number) => void,\n): HTMLDivElement {\n\tconst handle: HTMLDivElement = document.createElement('div');\n\thandle.className = `ntbl-handle ${className}`;\n\thandle.dataset.index = String(index);\n\n\tconst deleteBtn: HTMLButtonElement = createButton(\n\t\t'ntbl-handle-delete',\n\t\tDELETE_SVG,\n\t\tclassName.includes('col') ? 'Delete column' : 'Delete row',\n\t);\n\tdeleteBtn.addEventListener('click', (e: MouseEvent) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tonDelete(index);\n\t});\n\thandle.appendChild(deleteBtn);\n\n\treturn handle;\n}\n\n// --- Main Factory ---\n\nexport function createTableControls(\n\tcontainer: HTMLElement,\n\ttableEl: HTMLTableElement,\n\tinitialNode: BlockNode,\n\tgetState: () => EditorState,\n\tdispatch: (tr: Transaction) => void,\n): TableControlsHandle {\n\tlet tableId: BlockId = initialNode.id;\n\tlet numRows: number = countRows(initialNode);\n\tlet numCols: number = countCols(initialNode);\n\n\t// --- Create DOM elements ---\n\n\tconst colBar: HTMLDivElement = buildHandleBar('ntbl-col-bar');\n\tconst rowBar: HTMLDivElement = buildHandleBar('ntbl-row-bar');\n\tconst insertLineH: HTMLDivElement = buildInsertLine('horizontal');\n\tconst insertLineV: HTMLDivElement = buildInsertLine('vertical');\n\tconst addRowZone: HTMLDivElement = buildAddButton('ntbl-add-row', 'Add row');\n\tconst addColZone: HTMLDivElement = buildAddButton('ntbl-add-col', 'Add column');\n\n\t// --- Insert line state ---\n\n\tlet activeRowIndex = -1;\n\tlet activeColIndex = -1;\n\n\t// --- Append to container ---\n\n\tcontainer.append(colBar, rowBar, insertLineH, insertLineV, addRowZone, addColZone);\n\n\t// --- Build handles ---\n\n\trebuildColHandles();\n\trebuildRowHandles();\n\n\t// --- Event handlers ---\n\n\tconst insertBtnH: HTMLButtonElement = insertLineH.querySelector(\n\t\t'.ntbl-insert-btn',\n\t) as HTMLButtonElement;\n\tconst insertBtnV: HTMLButtonElement = insertLineV.querySelector(\n\t\t'.ntbl-insert-btn',\n\t) as HTMLButtonElement;\n\n\tinsertBtnH.addEventListener('click', () => {\n\t\tif (activeRowIndex >= 0) {\n\t\t\tinsertRowAtIndex(getState, dispatch, tableId, activeRowIndex);\n\t\t}\n\t});\n\n\tinsertBtnV.addEventListener('click', () => {\n\t\tif (activeColIndex >= 0) {\n\t\t\tinsertColumnAtIndex(getState, dispatch, tableId, activeColIndex);\n\t\t}\n\t});\n\n\taddRowZone.addEventListener('click', () => {\n\t\tinsertRowAtIndex(getState, dispatch, tableId, numRows);\n\t});\n\n\taddColZone.addEventListener('click', () => {\n\t\tinsertColumnAtIndex(getState, dispatch, tableId, numCols);\n\t});\n\n\tcontainer.addEventListener('mousemove', onMouseMove);\n\tcontainer.addEventListener('mouseleave', onMouseLeave);\n\n\t// --- Positioning ---\n\n\tconst observer: ResizeObserver = new ResizeObserver(() => {\n\t\tpositionControls();\n\t});\n\tobserver.observe(tableEl);\n\trequestAnimationFrame(() => positionControls());\n\n\t// --- Functions ---\n\n\tfunction countRows(node: BlockNode): number {\n\t\treturn getBlockChildren(node).length;\n\t}\n\n\tfunction countCols(node: BlockNode): number {\n\t\tconst rows: readonly BlockNode[] = getBlockChildren(node);\n\t\treturn rows[0] ? getBlockChildren(rows[0]).length : 0;\n\t}\n\n\t/** Returns the table's offset relative to the container (walks offsetParent chain). */\n\tfunction getTableOffset(): { top: number; left: number } {\n\t\tlet top = 0;\n\t\tlet left = 0;\n\t\tlet el: HTMLElement | null = tableEl;\n\t\twhile (el && el !== container) {\n\t\t\ttop += el.offsetTop;\n\t\t\tleft += el.offsetLeft;\n\t\t\tel = el.offsetParent as HTMLElement | null;\n\t\t}\n\t\treturn { top, left };\n\t}\n\n\tfunction measureRowBorders(): BorderInfo[] {\n\t\tconst trs: NodeListOf<HTMLTableRowElement> = tableEl.querySelectorAll(':scope > tbody > tr');\n\t\tconst tableTop: number = tableEl.offsetTop;\n\t\tconst borders: BorderInfo[] = [];\n\n\t\tfor (let i = 1; i < trs.length; i++) {\n\t\t\tconst tr: HTMLTableRowElement | undefined = trs[i];\n\t\t\tif (!tr) continue;\n\t\t\tborders.push({\n\t\t\t\tposition: tr.offsetTop - tableTop,\n\t\t\t\tindex: i,\n\t\t\t});\n\t\t}\n\n\t\treturn borders;\n\t}\n\n\tfunction measureColBorders(): BorderInfo[] {\n\t\tif (numCols <= 1) return [];\n\t\tconst tableWidth: number = tableEl.offsetWidth;\n\t\tconst colWidth: number = tableWidth / numCols;\n\t\tconst borders: BorderInfo[] = [];\n\n\t\tfor (let i = 1; i < numCols; i++) {\n\t\t\tborders.push({\n\t\t\t\tposition: Math.round(colWidth * i),\n\t\t\t\tindex: i,\n\t\t\t});\n\t\t}\n\n\t\treturn borders;\n\t}\n\n\tfunction positionControls(): void {\n\t\tpositionColHandles();\n\t\tpositionRowHandles();\n\t\tpositionAddButtons();\n\t}\n\n\tfunction positionColHandles(): void {\n\t\tconst handles: HTMLCollection = colBar.children;\n\t\tif (handles.length === 0) return;\n\n\t\tconst tableWidth: number = tableEl.offsetWidth;\n\t\tconst colWidth: number = tableWidth / numCols;\n\n\t\tfor (let i = 0; i < handles.length; i++) {\n\t\t\tconst h = handles[i] as HTMLElement;\n\t\t\th.style.left = `${Math.round(colWidth * i)}px`;\n\t\t\th.style.width = `${Math.round(colWidth)}px`;\n\t\t}\n\n\t\tcolBar.style.width = `${tableWidth}px`;\n\t}\n\n\tfunction positionRowHandles(): void {\n\t\tconst handles: HTMLCollection = rowBar.children;\n\t\tif (handles.length === 0) return;\n\n\t\tconst trs: NodeListOf<HTMLTableRowElement> = tableEl.querySelectorAll(':scope > tbody > tr');\n\n\t\tconst tableTop: number = tableEl.offsetTop;\n\t\tlet totalHeight = 0;\n\n\t\tfor (let i = 0; i < handles.length; i++) {\n\t\t\tconst h = handles[i] as HTMLElement;\n\t\t\tconst tr: HTMLTableRowElement | undefined = trs[i];\n\t\t\tif (tr) {\n\t\t\t\tconst top: number = tr.offsetTop - tableTop;\n\t\t\t\tconst height: number = tr.offsetHeight;\n\t\t\t\th.style.top = `${top}px`;\n\t\t\t\th.style.height = `${height}px`;\n\t\t\t\ttotalHeight = top + height;\n\t\t\t}\n\t\t}\n\n\t\trowBar.style.height = `${totalHeight}px`;\n\t}\n\n\tfunction positionAddButtons(): void {\n\t\tconst offset = getTableOffset();\n\t\tconst tableHeight: number = tableEl.offsetHeight;\n\t\tconst tableWidth: number = tableEl.offsetWidth;\n\n\t\taddRowZone.style.width = `${tableWidth}px`;\n\t\taddRowZone.style.left = `${offset.left}px`;\n\n\t\taddColZone.style.height = `${tableHeight}px`;\n\t\taddColZone.style.top = `${offset.top}px`;\n\t}\n\n\tfunction onMouseMove(e: MouseEvent): void {\n\t\tconst tableRect: DOMRect = tableEl.getBoundingClientRect();\n\t\tconst x: number = e.clientX - tableRect.left;\n\t\tconst y: number = e.clientY - tableRect.top;\n\n\t\t// Check if mouse is inside table bounds (with margin)\n\t\tconst inTable: boolean =\n\t\t\tx >= -BORDER_THRESHOLD &&\n\t\t\tx <= tableRect.width + BORDER_THRESHOLD &&\n\t\t\ty >= -BORDER_THRESHOLD &&\n\t\t\ty <= tableRect.height + BORDER_THRESHOLD;\n\n\t\tif (!inTable) {\n\t\t\thideInsertLines();\n\t\t\treturn;\n\t\t}\n\n\t\t// Find nearest row border\n\t\tconst rowBorders: BorderInfo[] = measureRowBorders();\n\t\tlet nearestRowDist: number = Number.POSITIVE_INFINITY;\n\t\tlet nearestRowBorder: BorderInfo | null = null;\n\n\t\tfor (const border of rowBorders) {\n\t\t\tconst dist: number = Math.abs(y - border.position);\n\t\t\tif (dist < nearestRowDist && dist < BORDER_THRESHOLD) {\n\t\t\t\tnearestRowDist = dist;\n\t\t\t\tnearestRowBorder = border;\n\t\t\t}\n\t\t}\n\n\t\t// Find nearest column border\n\t\tconst colBorders: BorderInfo[] = measureColBorders();\n\t\tlet nearestColDist: number = Number.POSITIVE_INFINITY;\n\t\tlet nearestColBorder: BorderInfo | null = null;\n\n\t\tfor (const border of colBorders) {\n\t\t\tconst dist: number = Math.abs(x - border.position);\n\t\t\tif (dist < nearestColDist && dist < BORDER_THRESHOLD) {\n\t\t\t\tnearestColDist = dist;\n\t\t\t\tnearestColBorder = border;\n\t\t\t}\n\t\t}\n\n\t\t// Show the nearest line (prefer the closer one)\n\t\tif (nearestRowBorder && (!nearestColBorder || nearestRowDist <= nearestColDist)) {\n\t\t\tshowHorizontalLine(nearestRowBorder);\n\t\t\thideVerticalLine();\n\t\t} else if (nearestColBorder) {\n\t\t\tshowVerticalLine(nearestColBorder);\n\t\t\thideHorizontalLine();\n\t\t} else {\n\t\t\thideInsertLines();\n\t\t}\n\t}\n\n\tfunction onMouseLeave(): void {\n\t\thideInsertLines();\n\t}\n\n\tfunction showHorizontalLine(border: BorderInfo): void {\n\t\tactiveRowIndex = border.index;\n\t\tconst offset = getTableOffset();\n\t\tinsertLineH.style.top = `${offset.top + border.position - 1}px`;\n\t\tinsertLineH.style.left = `${offset.left}px`;\n\t\tinsertLineH.style.width = `${tableEl.offsetWidth}px`;\n\t\tinsertLineH.classList.add('ntbl-insert-line--visible');\n\t}\n\n\tfunction showVerticalLine(border: BorderInfo): void {\n\t\tactiveColIndex = border.index;\n\t\tconst offset = getTableOffset();\n\t\tinsertLineV.style.left = `${offset.left + border.position - 1}px`;\n\t\tinsertLineV.style.top = `${offset.top}px`;\n\t\tinsertLineV.style.height = `${tableEl.offsetHeight}px`;\n\t\tinsertLineV.classList.add('ntbl-insert-line--visible');\n\t}\n\n\tfunction hideInsertLines(): void {\n\t\thideHorizontalLine();\n\t\thideVerticalLine();\n\t}\n\n\tfunction hideHorizontalLine(): void {\n\t\tinsertLineH.classList.remove('ntbl-insert-line--visible');\n\t\tactiveRowIndex = -1;\n\t}\n\n\tfunction hideVerticalLine(): void {\n\t\tinsertLineV.classList.remove('ntbl-insert-line--visible');\n\t\tactiveColIndex = -1;\n\t}\n\n\tfunction rebuildColHandles(): void {\n\t\tcolBar.innerHTML = '';\n\t\tfor (let i = 0; i < numCols; i++) {\n\t\t\tconst handle: HTMLDivElement = buildHandle('ntbl-col-handle', i, (idx: number) => {\n\t\t\t\tdeleteColumnAtIndex(getState, dispatch, tableId, idx);\n\t\t\t});\n\t\t\tcolBar.appendChild(handle);\n\t\t}\n\t}\n\n\tfunction rebuildRowHandles(): void {\n\t\trowBar.innerHTML = '';\n\t\tfor (let i = 0; i < numRows; i++) {\n\t\t\tconst handle: HTMLDivElement = buildHandle('ntbl-row-handle', i, (idx: number) => {\n\t\t\t\tdeleteRowAtIndex(getState, dispatch, tableId, idx);\n\t\t\t});\n\t\t\trowBar.appendChild(handle);\n\t\t}\n\t}\n\n\t// --- Public API ---\n\n\treturn {\n\t\tupdate(node: BlockNode): void {\n\t\t\ttableId = node.id;\n\t\t\tconst newRows: number = countRows(node);\n\t\t\tconst newCols: number = countCols(node);\n\n\t\t\tif (newRows !== numRows || newCols !== numCols) {\n\t\t\t\tnumRows = newRows;\n\t\t\t\tnumCols = newCols;\n\t\t\t\trebuildColHandles();\n\t\t\t\trebuildRowHandles();\n\t\t\t}\n\n\t\t\trequestAnimationFrame(() => positionControls());\n\t\t},\n\n\t\tdestroy(): void {\n\t\t\tobserver.disconnect();\n\t\t\tcontainer.removeEventListener('mousemove', onMouseMove);\n\t\t\tcontainer.removeEventListener('mouseleave', onMouseLeave);\n\t\t\tcolBar.remove();\n\t\t\trowBar.remove();\n\t\t\tinsertLineH.remove();\n\t\t\tinsertLineV.remove();\n\t\t\taddRowZone.remove();\n\t\t\taddColZone.remove();\n\t\t},\n\t};\n}\n","/**\n * NodeViewFactories for table, table_row, and table_cell.\n * Provides custom DOM rendering with proper HTML table elements and ARIA.\n * The table NodeView includes interactive controls for row/column management.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { getBlockChildren } from '../../model/Document.js';\nimport type { SchemaRegistry } from '../../model/SchemaRegistry.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { NodeView, NodeViewFactory } from '../../view/NodeView.js';\nimport { renderBlockContent } from '../../view/Reconciler.js';\nimport { type TableControlsHandle, createTableControls } from './TableControls.js';\n\n/**\n * Creates a NodeViewFactory for the table node type.\n * Renders as outer container with controls + table + tbody.\n */\nexport function createTableNodeViewFactory(_registry: SchemaRegistry): NodeViewFactory {\n\treturn (\n\t\tnode: BlockNode,\n\t\tgetState: () => EditorState,\n\t\tdispatch: (tr: Transaction) => void,\n\t): NodeView => {\n\t\t// Outer container: holds controls + wrapper\n\t\tconst container: HTMLDivElement = document.createElement('div');\n\t\tcontainer.className = 'ntbl-container';\n\t\tcontainer.setAttribute('data-block-id', node.id);\n\n\t\t// Table wrapper: provides overflow scrolling\n\t\tconst wrapper: HTMLDivElement = document.createElement('div');\n\t\twrapper.className = 'notectl-table-wrapper';\n\n\t\tconst table: HTMLTableElement = document.createElement('table');\n\t\ttable.className = 'notectl-table';\n\t\ttable.setAttribute('role', 'table');\n\n\t\tconst rows: readonly BlockNode[] = getBlockChildren(node);\n\t\tconst totalRows: number = rows.length;\n\t\tconst totalCols: number = rows[0] ? getBlockChildren(rows[0]).length : 0;\n\t\ttable.setAttribute('aria-label', `Table with ${totalRows} rows and ${totalCols} columns`);\n\n\t\tconst tbody: HTMLTableSectionElement = document.createElement('tbody');\n\t\ttable.appendChild(tbody);\n\t\twrapper.appendChild(table);\n\t\tcontainer.appendChild(wrapper);\n\n\t\t// Live region for screen reader announcements\n\t\tconst liveRegion: HTMLDivElement = document.createElement('div');\n\t\tliveRegion.className = 'notectl-sr-only';\n\t\tliveRegion.setAttribute('aria-live', 'polite');\n\t\tliveRegion.setAttribute('aria-atomic', 'true');\n\t\tcontainer.appendChild(liveRegion);\n\n\t\t// Initialize interactive controls\n\t\tconst controls: TableControlsHandle = createTableControls(\n\t\t\tcontainer,\n\t\t\ttable,\n\t\t\tnode,\n\t\t\tgetState,\n\t\t\tdispatch,\n\t\t);\n\n\t\treturn {\n\t\t\tdom: container,\n\t\t\tcontentDOM: tbody,\n\t\t\tupdate(updatedNode: BlockNode): boolean {\n\t\t\t\tif (updatedNode.type !== 'table') return false;\n\t\t\t\tcontainer.setAttribute('data-block-id', updatedNode.id);\n\t\t\t\tconst updatedRows: readonly BlockNode[] = getBlockChildren(updatedNode);\n\t\t\t\tconst newTotalRows: number = updatedRows.length;\n\t\t\t\tconst newTotalCols: number = updatedRows[0] ? getBlockChildren(updatedRows[0]).length : 0;\n\t\t\t\ttable.setAttribute(\n\t\t\t\t\t'aria-label',\n\t\t\t\t\t`Table with ${newTotalRows} rows and ${newTotalCols} columns`,\n\t\t\t\t);\n\n\t\t\t\t// Update controls to reflect new structure\n\t\t\t\tcontrols.update(updatedNode);\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tdestroy(): void {\n\t\t\t\tcontrols.destroy();\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Creates a NodeViewFactory for the table_row node type.\n * Renders as `<tr role=\"row\">`.\n */\nexport function createTableRowNodeViewFactory(_registry: SchemaRegistry): NodeViewFactory {\n\treturn (\n\t\tnode: BlockNode,\n\t\t_getState: () => EditorState,\n\t\t_dispatch: (tr: Transaction) => void,\n\t): NodeView => {\n\t\tconst tr: HTMLTableRowElement = document.createElement('tr');\n\t\ttr.setAttribute('data-block-id', node.id);\n\t\ttr.setAttribute('role', 'row');\n\n\t\treturn {\n\t\t\tdom: tr,\n\t\t\tcontentDOM: tr,\n\t\t\tupdate(updatedNode: BlockNode): boolean {\n\t\t\t\tif (updatedNode.type !== 'table_row') return false;\n\t\t\t\ttr.setAttribute('data-block-id', updatedNode.id);\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tdestroy(): void {\n\t\t\t\t// No cleanup needed\n\t\t\t},\n\t\t};\n\t};\n}\n\n/**\n * Creates a NodeViewFactory for the table_cell node type.\n * Renders as `<td role=\"cell\">` with text content rendered inside.\n */\nexport function createTableCellNodeViewFactory(registry: SchemaRegistry): NodeViewFactory {\n\treturn (\n\t\tnode: BlockNode,\n\t\t_getState: () => EditorState,\n\t\t_dispatch: (tr: Transaction) => void,\n\t): NodeView => {\n\t\tconst td: HTMLTableCellElement = document.createElement('td');\n\t\ttd.setAttribute('data-block-id', node.id);\n\t\ttd.setAttribute('role', 'cell');\n\n\t\tconst colspan: number = (node.attrs?.colspan as number | undefined) ?? 1;\n\t\tconst rowspan: number = (node.attrs?.rowspan as number | undefined) ?? 1;\n\t\tif (colspan > 1) td.colSpan = colspan;\n\t\tif (rowspan > 1) td.rowSpan = rowspan;\n\n\t\t// Render text content\n\t\trenderBlockContent(td, node, registry);\n\n\t\treturn {\n\t\t\tdom: td,\n\t\t\tcontentDOM: td,\n\t\t\tupdate(updatedNode: BlockNode): boolean {\n\t\t\t\tif (updatedNode.type !== 'table_cell') return false;\n\t\t\t\ttd.setAttribute('data-block-id', updatedNode.id);\n\n\t\t\t\tconst newColspan: number = (updatedNode.attrs?.colspan as number | undefined) ?? 1;\n\t\t\t\tconst newRowspan: number = (updatedNode.attrs?.rowspan as number | undefined) ?? 1;\n\t\t\t\tif (newColspan > 1) {\n\t\t\t\t\ttd.colSpan = newColspan;\n\t\t\t\t} else {\n\t\t\t\t\ttd.removeAttribute('colspan');\n\t\t\t\t}\n\t\t\t\tif (newRowspan > 1) {\n\t\t\t\t\ttd.rowSpan = newRowspan;\n\t\t\t\t} else {\n\t\t\t\t\ttd.removeAttribute('rowspan');\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tdestroy(): void {\n\t\t\t\t// No cleanup needed\n\t\t\t},\n\t\t};\n\t};\n}\n","/**\n * Multi-cell selection service for tables.\n * Tracks selected cell range and provides IDs for bulk formatting.\n */\n\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { ServiceKey } from '../Plugin.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { findTableContext, getCellAt } from './TableHelpers.js';\n\n/** Rectangular range of cells within a table. */\nexport interface CellRange {\n\treadonly tableId: BlockId;\n\treadonly fromRow: number;\n\treadonly fromCol: number;\n\treadonly toRow: number;\n\treadonly toCol: number;\n}\n\n/** Service for managing multi-cell selection. */\nexport interface TableSelectionService {\n\tgetSelectedRange(): CellRange | null;\n\tsetSelectedRange(range: CellRange | null): void;\n\tgetSelectedCellIds(): readonly BlockId[];\n\tisSelected(cellId: BlockId): boolean;\n}\n\nexport const TableSelectionServiceKey = new ServiceKey<TableSelectionService>('tableSelection');\n\n/** Creates and registers the TableSelectionService. */\nexport function createTableSelectionService(context: PluginContext): TableSelectionService {\n\tlet selectedRange: CellRange | null = null;\n\tlet cachedCellIds: readonly BlockId[] = [];\n\tlet cachedCellIdSet: Set<BlockId> = new Set();\n\n\tfunction updateCache(): void {\n\t\tif (!selectedRange) {\n\t\t\tcachedCellIds = [];\n\t\t\tcachedCellIdSet = new Set();\n\t\t\treturn;\n\t\t}\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst ids: BlockId[] = [];\n\n\t\tconst minRow: number = Math.min(selectedRange.fromRow, selectedRange.toRow);\n\t\tconst maxRow: number = Math.max(selectedRange.fromRow, selectedRange.toRow);\n\t\tconst minCol: number = Math.min(selectedRange.fromCol, selectedRange.toCol);\n\t\tconst maxCol: number = Math.max(selectedRange.fromCol, selectedRange.toCol);\n\n\t\tfor (let r = minRow; r <= maxRow; r++) {\n\t\t\tfor (let c = minCol; c <= maxCol; c++) {\n\t\t\t\tconst cellId: BlockId | null = getCellAt(state, selectedRange.tableId, r, c);\n\t\t\t\tif (cellId) ids.push(cellId);\n\t\t\t}\n\t\t}\n\n\t\tcachedCellIds = ids;\n\t\tcachedCellIdSet = new Set(ids);\n\t}\n\n\tconst service: TableSelectionService = {\n\t\tgetSelectedRange(): CellRange | null {\n\t\t\treturn selectedRange;\n\t\t},\n\n\t\tsetSelectedRange(range: CellRange | null): void {\n\t\t\tselectedRange = range;\n\t\t\tupdateCache();\n\t\t\tupdateCellHighlights(context, cachedCellIdSet);\n\t\t},\n\n\t\tgetSelectedCellIds(): readonly BlockId[] {\n\t\t\treturn cachedCellIds;\n\t\t},\n\n\t\tisSelected(cellId: BlockId): boolean {\n\t\t\treturn cachedCellIdSet.has(cellId);\n\t\t},\n\t};\n\n\tcontext.registerService(TableSelectionServiceKey, service);\n\treturn service;\n}\n\n/** Updates CSS class on selected cells for visual highlighting. */\nfunction updateCellHighlights(context: PluginContext, selectedIds: Set<BlockId>): void {\n\tconst container: HTMLElement = context.getContainer();\n\tconst cells: NodeListOf<Element> = container.querySelectorAll('td[data-block-id]');\n\n\tfor (const cell of cells) {\n\t\tconst cellId = cell.getAttribute('data-block-id') as BlockId;\n\t\tif (selectedIds.has(cellId)) {\n\t\t\tcell.classList.add('notectl-table-cell--selected');\n\t\t} else {\n\t\t\tcell.classList.remove('notectl-table-cell--selected');\n\t\t}\n\t}\n}\n\n/**\n * Installs mouse handlers for multi-cell selection on the editor container.\n * Returns a cleanup function.\n */\nexport function installMouseSelection(\n\tcontext: PluginContext,\n\tservice: TableSelectionService,\n): () => void {\n\tconst container: HTMLElement = context.getContainer();\n\tlet anchorCell: { tableId: BlockId; row: number; col: number } | null = null;\n\tlet isDragging = false;\n\n\tfunction handleMouseDown(e: MouseEvent): void {\n\t\tconst target = e.target as HTMLElement;\n\t\tconst cellEl: HTMLElement | null = target.closest('td[data-block-id]');\n\t\tif (!cellEl) {\n\t\t\tservice.setSelectedRange(null);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!e.shiftKey) {\n\t\t\t// Clear any existing multi-cell selection before starting a new anchor\n\t\t\tservice.setSelectedRange(null);\n\t\t\t// Start new selection anchor\n\t\t\tconst state: EditorState = context.getState();\n\t\t\tconst cellId = cellEl.getAttribute('data-block-id') as BlockId;\n\t\t\tconst tableCtx = findTableContext(state, cellId);\n\t\t\tif (!tableCtx) return;\n\n\t\t\tanchorCell = {\n\t\t\t\ttableId: tableCtx.tableId,\n\t\t\t\trow: tableCtx.rowIndex,\n\t\t\t\tcol: tableCtx.colIndex,\n\t\t\t};\n\t\t\tisDragging = true;\n\t\t\t// Don't set range yet — wait for mousemove to avoid interfering with clicks\n\t\t} else if (anchorCell) {\n\t\t\t// Shift-click: extend selection\n\t\t\tconst state: EditorState = context.getState();\n\t\t\tconst cellId = cellEl.getAttribute('data-block-id') as BlockId;\n\t\t\tconst tableCtx = findTableContext(state, cellId);\n\t\t\tif (!tableCtx || tableCtx.tableId !== anchorCell.tableId) return;\n\n\t\t\te.preventDefault();\n\t\t\tservice.setSelectedRange({\n\t\t\t\ttableId: anchorCell.tableId,\n\t\t\t\tfromRow: anchorCell.row,\n\t\t\t\tfromCol: anchorCell.col,\n\t\t\t\ttoRow: tableCtx.rowIndex,\n\t\t\t\ttoCol: tableCtx.colIndex,\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction handleMouseMove(e: MouseEvent): void {\n\t\tif (!isDragging || !anchorCell) return;\n\n\t\tconst target = e.target as HTMLElement;\n\t\tconst cellEl: HTMLElement | null = target.closest('td[data-block-id]');\n\t\tif (!cellEl) return;\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst cellId = cellEl.getAttribute('data-block-id') as BlockId;\n\t\tconst tableCtx = findTableContext(state, cellId);\n\t\tif (!tableCtx || tableCtx.tableId !== anchorCell.tableId) return;\n\n\t\t// Only set range if we've moved to a different cell\n\t\tif (tableCtx.rowIndex !== anchorCell.row || tableCtx.colIndex !== anchorCell.col) {\n\t\t\te.preventDefault();\n\t\t\tservice.setSelectedRange({\n\t\t\t\ttableId: anchorCell.tableId,\n\t\t\t\tfromRow: anchorCell.row,\n\t\t\t\tfromCol: anchorCell.col,\n\t\t\t\ttoRow: tableCtx.rowIndex,\n\t\t\t\ttoCol: tableCtx.colIndex,\n\t\t\t});\n\t\t}\n\t}\n\n\tfunction handleMouseUp(): void {\n\t\tisDragging = false;\n\t}\n\n\tcontainer.addEventListener('mousedown', handleMouseDown);\n\tcontainer.addEventListener('mousemove', handleMouseMove);\n\tdocument.addEventListener('mouseup', handleMouseUp);\n\n\treturn () => {\n\t\tcontainer.removeEventListener('mousedown', handleMouseDown);\n\t\tcontainer.removeEventListener('mousemove', handleMouseMove);\n\t\tdocument.removeEventListener('mouseup', handleMouseUp);\n\t};\n}\n","/**\n * TablePlugin: registers table, table_row, and table_cell node types\n * with NodeSpecs, NodeViews, commands, keyboard navigation, toolbar\n * grid picker, multi-cell selection, and context menu.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { insertTable, registerTableCommands } from './TableCommands.js';\nimport { isInsideTable } from './TableHelpers.js';\nimport { registerTableKeymaps } from './TableNavigation.js';\nimport {\n\tcreateTableCellNodeViewFactory,\n\tcreateTableNodeViewFactory,\n\tcreateTableRowNodeViewFactory,\n} from './TableNodeViews.js';\nimport {\n\ttype TableSelectionService,\n\tcreateTableSelectionService,\n\tinstallMouseSelection,\n} from './TableSelection.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\ttable: Record<string, never>;\n\t\ttable_row: Record<string, never>;\n\t\ttable_cell: { colspan?: number; rowspan?: number };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TableConfig {\n\t/** Maximum rows in grid picker. Defaults to 8. */\n\treadonly maxPickerRows?: number;\n\t/** Maximum columns in grid picker. Defaults to 8. */\n\treadonly maxPickerCols?: number;\n\t/** When true, a separator is rendered after the table toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: TableConfig = {\n\tmaxPickerRows: 8,\n\tmaxPickerCols: 8,\n};\n\n// --- SVG Icon ---\n\nconst TABLE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">' +\n\t'<path d=\"M3 3h18v18H3V3zm2 2v4h6V5H5zm8 0v4h6V5h-6zm-8 6v4h6v-4H5z' +\n\t'm8 0v4h6v-4h-6zm-8 6v4h6v-4H5zm8 0v4h6v-4h-6z\"/></svg>';\n\n// --- Plugin ---\n\nexport class TablePlugin implements Plugin {\n\treadonly id = 'table';\n\treadonly name = 'Table';\n\treadonly priority = 40;\n\n\tprivate readonly config: TableConfig;\n\tprivate selectionService: TableSelectionService | null = null;\n\tprivate cleanupMouseSelection: (() => void) | null = null;\n\tprivate context: PluginContext | null = null;\n\n\tconstructor(config?: Partial<TableConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.context = context;\n\n\t\tthis.registerNodeSpecs(context);\n\t\tthis.registerNodeViews(context);\n\t\tregisterTableCommands(context);\n\t\tregisterTableKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.selectionService = createTableSelectionService(context);\n\t}\n\n\tonReady(): void {\n\t\tif (this.context && this.selectionService) {\n\t\t\tthis.cleanupMouseSelection = installMouseSelection(this.context, this.selectionService);\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.cleanupMouseSelection?.();\n\t\tthis.cleanupMouseSelection = null;\n\t\tthis.selectionService = null;\n\t\tthis.context = null;\n\t}\n\n\tonStateChange(_oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\t// Clear multi-cell selection when cursor moves outside table\n\t\tif (this.selectionService?.getSelectedRange()) {\n\t\t\tconst sel = newState.selection;\n\t\t\tif (!isInsideTable(newState, sel.anchor.blockId)) {\n\t\t\t\tthis.selectionService.setSelectedRange(null);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate registerNodeSpecs(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'table',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['table_row'], min: 1 },\n\t\t\tisolating: true,\n\t\t\ttoDOM(node) {\n\t\t\t\tconst wrapper: HTMLDivElement = document.createElement('div');\n\t\t\t\twrapper.className = 'notectl-table-wrapper';\n\t\t\t\twrapper.setAttribute('data-block-id', node.id);\n\t\t\t\treturn wrapper;\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'table_row',\n\t\t\tgroup: 'table_content',\n\t\t\tcontent: { allow: ['table_cell'], min: 1 },\n\t\t\ttoDOM(node) {\n\t\t\t\tconst tr: HTMLTableRowElement = document.createElement('tr');\n\t\t\t\ttr.setAttribute('data-block-id', node.id);\n\t\t\t\ttr.setAttribute('role', 'row');\n\t\t\t\treturn tr;\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'table_cell',\n\t\t\tgroup: 'table_content',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\tisolating: true,\n\t\t\ttoDOM(node) {\n\t\t\t\tconst td: HTMLTableCellElement = document.createElement('td');\n\t\t\t\ttd.setAttribute('data-block-id', node.id);\n\t\t\t\ttd.setAttribute('role', 'cell');\n\t\t\t\treturn td;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerNodeViews(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tcontext.registerNodeView('table', createTableNodeViewFactory(registry));\n\t\tcontext.registerNodeView('table_row', createTableRowNodeViewFactory(registry));\n\t\tcontext.registerNodeView('table_cell', createTableCellNodeViewFactory(registry));\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst maxRows: number = this.config.maxPickerRows ?? 8;\n\t\tconst maxCols: number = this.config.maxPickerCols ?? 8;\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'table',\n\t\t\tgroup: 'insert',\n\t\t\ticon: TABLE_ICON,\n\t\t\tlabel: 'Insert Table',\n\t\t\ttooltip: 'Insert Table',\n\t\t\tcommand: 'insertTable',\n\t\t\tpriority: 80,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tpopupType: 'gridPicker',\n\t\t\tpopupConfig: {\n\t\t\t\tmaxRows,\n\t\t\t\tmaxCols,\n\t\t\t\tonSelect: (rows: number, cols: number) => {\n\t\t\t\t\tinsertTable(context, rows, cols);\n\t\t\t\t},\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => {\n\t\t\t\treturn isInsideTable(state, state.selection.anchor.blockId);\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * HighlightPlugin: registers a highlight (background-color) mark with attrs,\n * toolbar button with a color picker popup, and removeHighlight command.\n */\n\nimport { isMarkOfType } from '../../model/AttrRegistry.js';\nimport { getBlockMarksAtOffset, hasMark } from '../../model/Document.js';\nimport { isCollapsed, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\thighlight: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HighlightConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\t/** When true, a separator is rendered after the highlight toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: HighlightConfig = {};\n\n// --- Color Validation ---\n\nconst HEX_COLOR_PATTERN: RegExp = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nfunction isValidHexColor(value: string): boolean {\n\treturn HEX_COLOR_PATTERN.test(value);\n}\n\n/**\n * Validates, deduplicates, and normalizes the user-supplied color list.\n * Returns the default palette when no custom colors are provided.\n *\n * @throws {Error} if any value is not a valid hex color code.\n */\nfunction resolveColors(colors: readonly string[] | undefined): readonly string[] {\n\tif (!colors || colors.length === 0) return HIGHLIGHT_PALETTE;\n\n\tconst invalid: string[] = colors.filter((c) => !isValidHexColor(c));\n\tif (invalid.length > 0) {\n\t\tthrow new Error(\n\t\t\t`HighlightPlugin: invalid hex color(s): ${invalid.join(', ')}. Expected format: #RGB or #RRGGBB.`,\n\t\t);\n\t}\n\n\tconst seen: Set<string> = new Set();\n\tconst unique: string[] = [];\n\tfor (const color of colors) {\n\t\tconst normalized: string = color.toLowerCase();\n\t\tif (!seen.has(normalized)) {\n\t\t\tseen.add(normalized);\n\t\t\tunique.push(normalized);\n\t\t}\n\t}\n\treturn unique;\n}\n\n// --- Color Palette (Highlight-optimized: 10 columns x 5 rows) ---\n\nconst HIGHLIGHT_PALETTE: readonly string[] = [\n\t// Row 1 — Classic highlighter colors (bright, vivid)\n\t'#fff176',\n\t'#aed581',\n\t'#4dd0e1',\n\t'#64b5f6',\n\t'#ce93d8',\n\t'#f48fb1',\n\t'#ffab91',\n\t'#ff8a65',\n\t'#e6ee9c',\n\t'#80cbc4',\n\n\t// Row 2 — Light pastels\n\t'#fff9c4',\n\t'#dcedc8',\n\t'#e0f7fa',\n\t'#e3f2fd',\n\t'#f3e5f5',\n\t'#fce4ec',\n\t'#fff3e0',\n\t'#fbe9e7',\n\t'#f9fbe7',\n\t'#e0f2f1',\n\n\t// Row 3 — Medium pastels\n\t'#fff59d',\n\t'#c5e1a5',\n\t'#80deea',\n\t'#90caf9',\n\t'#e1bee7',\n\t'#f8bbd0',\n\t'#ffcc80',\n\t'#ffab91',\n\t'#e6ee9c',\n\t'#a5d6a7',\n\n\t// Row 4 — Bold pastels\n\t'#ffee58',\n\t'#9ccc65',\n\t'#26c6da',\n\t'#42a5f5',\n\t'#ab47bc',\n\t'#ec407a',\n\t'#ffa726',\n\t'#ff7043',\n\t'#d4e157',\n\t'#66bb6a',\n\n\t// Row 5 — Grays and neutral highlights\n\t'#ffffff',\n\t'#fafafa',\n\t'#f5f5f5',\n\t'#eeeeee',\n\t'#e0e0e0',\n\t'#bdbdbd',\n\t'#e8eaf6',\n\t'#efebe9',\n\t'#eceff1',\n\t'#fafafa',\n];\n\n// --- Plugin ---\n\nexport class HighlightPlugin implements Plugin {\n\treadonly id = 'highlight';\n\treadonly name = 'Highlight';\n\treadonly priority = 24;\n\n\tprivate readonly config: HighlightConfig;\n\tprivate readonly colors: readonly string[];\n\n\tconstructor(config?: Partial<HighlightConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t\tthis.colors = resolveColors(config?.colors);\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'highlight',\n\t\t\trank: 4,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tspan.style.backgroundColor = color;\n\t\t\t\treturn span;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeHighlight', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.removeHighlight(context, state);\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"17\" width=\"18\" height=\"6\"',\n\t\t\t' rx=\"0.5\" fill=\"#fff176\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'highlight',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: 'Highlight',\n\t\t\ttooltip: 'Highlight Color',\n\t\t\tcommand: 'removeHighlight',\n\t\t\tpriority: 46,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderHighlightPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isHighlightActive(state),\n\t\t});\n\t}\n\n\t// --- State Queries ---\n\n\tprivate isHighlightActive(state: EditorState): boolean {\n\t\treturn this.getActiveColor(state) !== null;\n\t}\n\n\tprivate getActiveColor(state: EditorState): string | null {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tif (state.storedMarks) {\n\t\t\t\tconst mark = state.storedMarks.find((m) => m.type === 'highlight');\n\t\t\t\treturn mark && isMarkOfType(mark, 'highlight') ? (mark.attrs.color ?? null) : null;\n\t\t\t}\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return null;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\tconst mark = marks.find((m) => m.type === 'highlight');\n\t\t\treturn mark && isMarkOfType(mark, 'highlight') ? (mark.attrs.color ?? null) : null;\n\t\t}\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return null;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\tconst mark = marks.find((m) => m.type === 'highlight');\n\t\treturn mark && isMarkOfType(mark, 'highlight') ? (mark.attrs.color ?? null) : null;\n\t}\n\n\t// --- Highlight Application ---\n\n\tprivate applyHighlight(context: PluginContext, state: EditorState, color: string): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tconst withoutHighlight = currentMarks.filter((m) => m.type !== 'highlight');\n\t\t\tconst newMarks = [...withoutHighlight, { type: markType('highlight'), attrs: { color } }];\n\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\tconst mark = { type: markType('highlight'), attrs: { color } };\n\n\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.removeMark(blockId, from, to, {\n\t\t\t\t\ttype: markType('highlight'),\n\t\t\t\t});\n\t\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeHighlight(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst anchorBlock = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!anchorBlock) return false;\n\t\t\tconst currentMarks =\n\t\t\t\tstate.storedMarks ?? getBlockMarksAtOffset(anchorBlock, sel.anchor.offset);\n\t\t\tif (!hasMark(currentMarks, markType('highlight'))) return false;\n\n\t\t\tconst newMarks = currentMarks.filter((m) => m.type !== 'highlight');\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setStoredMarks(newMarks, state.storedMarks)\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = selectionRange(sel, blockOrder);\n\t\tconst builder = state.transaction('command');\n\n\t\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\t\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\t\tfor (let i = fromIdx; i <= toIdx; i++) {\n\t\t\tconst blockId = blockOrder[i];\n\t\t\tif (!blockId) continue;\n\t\t\tconst block = state.getBlock(blockId);\n\t\t\tif (!block) continue;\n\t\t\tconst blockLen = block.children.reduce(\n\t\t\t\t(sum, c) => sum + ('text' in c ? c.text.length : 0),\n\t\t\t\t0,\n\t\t\t);\n\n\t\t\tconst from = i === fromIdx ? range.from.offset : 0;\n\t\t\tconst to = i === toIdx ? range.to.offset : blockLen;\n\n\t\t\tif (from !== to) {\n\t\t\t\tbuilder.removeMark(blockId, from, to, {\n\t\t\t\t\ttype: markType('highlight'),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t// --- Popup Rendering ---\n\n\tprivate renderHighlightPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.classList.add('notectl-color-picker');\n\n\t\tconst state = context.getState();\n\t\tconst activeColor = this.getActiveColor(state);\n\n\t\tconst defaultBtn = document.createElement('button');\n\t\tdefaultBtn.type = 'button';\n\t\tdefaultBtn.className = 'notectl-color-picker__default';\n\t\tdefaultBtn.textContent = 'None';\n\t\tdefaultBtn.addEventListener('mousedown', (e) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tcontext.executeCommand('removeHighlight');\n\t\t});\n\t\tcontainer.appendChild(defaultBtn);\n\n\t\tconst grid = document.createElement('div');\n\t\tgrid.className = 'notectl-color-picker__grid';\n\n\t\tfor (const color of this.colors) {\n\t\t\tconst swatch = document.createElement('button');\n\t\t\tswatch.type = 'button';\n\t\t\tswatch.className = 'notectl-color-picker__swatch';\n\t\t\tif (activeColor && activeColor.toLowerCase() === color.toLowerCase()) {\n\t\t\t\tswatch.classList.add('notectl-color-picker__swatch--active');\n\t\t\t}\n\t\t\tswatch.style.backgroundColor = color;\n\t\t\tif (color === '#ffffff') {\n\t\t\t\tswatch.style.border = '1px solid #d0d0d0';\n\t\t\t}\n\t\t\tswatch.title = color;\n\n\t\t\tswatch.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tthis.applyHighlight(context, context.getState(), color);\n\t\t\t});\n\n\t\t\tgrid.appendChild(swatch);\n\t\t}\n\n\t\tcontainer.appendChild(grid);\n\t}\n}\n","/**\n * SuperSubPlugin: registers superscript and subscript inline marks with\n * MarkSpecs, toggle commands, keyboard shortcuts, toolbar buttons, and\n * a middleware that enforces mutual exclusivity between the two marks.\n *\n * Data-driven — each mark type is defined declaratively and all\n * registrations are derived from the same definition table.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport type { Mark } from '../../model/Document.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { RemoveMarkStep, Step } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tsuperscript: Record<string, never>;\n\t\tsubscript: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface SuperSubToolbarConfig {\n\treadonly superscript?: boolean;\n\treadonly subscript?: boolean;\n}\n\n/** Controls which marks are enabled and which toolbar buttons are shown. */\nexport interface SuperSubConfig {\n\treadonly superscript: boolean;\n\treadonly subscript: boolean;\n\treadonly toolbar?: SuperSubToolbarConfig;\n\t/** When true, a separator is rendered after the last toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: SuperSubConfig = {\n\tsuperscript: true,\n\tsubscript: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: 'superscript' | 'subscript';\n\treadonly opposite: 'superscript' | 'subscript';\n\treadonly configKey: keyof Omit<SuperSubConfig, 'toolbar' | 'separatorAfter'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toolbarPriority: number;\n}\n\nconst SUPERSCRIPT_ICON: string = [\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">',\n\t'<path d=\"M16 7.41L11.41 12 16 16.59 14.59 18l-6-6 6-6z\"',\n\t' fill=\"none\"/>',\n\t'<path d=\"M9.64 7.64c.23-.5.36-1.05.36-1.64',\n\t' 0-2.21-1.79-4-4-4H2v14h4.36c2.34 0 4.24-1.9',\n\t' 4.24-4.24 0-1.6-.89-2.99-2.2-3.71zM4.5 4.5H6c.83',\n\t' 0 1.5.67 1.5 1.5S6.83 7.5 6 7.5H4.5v-3zm2 9H4.5v-3H6.5c.83',\n\t' 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\" fill=\"none\"/>',\n\t'<path d=\"M15.97 3.84c0-.47.19-.91.53-1.21.34-.31.8-.49',\n\t' 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02',\n\t'-.96-.43-1.83-1.13-2.42C19.36.77 18.45.44 17.5.44c-.88',\n\t' 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34',\n\t' 1.47.93 1.97.59.49 1.41.84 2.32 1.15.7.24 1.26.5 1.62.8.35.3.53.64.53',\n\t' 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54',\n\t'-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96',\n\t' 2.67.96.92 0 1.81-.3 2.46-.84.67-.56 1.04-1.33 1.04-2.18 0-.81-.36-1.56',\n\t'-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46',\n\t'-.59-.46-.94z\"/>',\n\t'<path d=\"M5.88 20h2.66l3.4-5.42L15.3 20h2.67l-4.73-7.38',\n\t' 4.37-6.62h-2.6l-3.07 4.98L8.92 6h-2.6l4.26 6.58z\"/>',\n\t'</svg>',\n].join('');\n\nconst SUBSCRIPT_ICON: string = [\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">',\n\t'<path d=\"M15.97 16.84c0-.47.19-.91.53-1.21.34-.31.8-.49',\n\t' 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02',\n\t'-.96-.43-1.83-1.13-2.42-.7-.58-1.61-.91-2.56-.91-.88',\n\t' 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34',\n\t' 1.47.93 1.97.59.49 1.41.84 2.32 1.15.7.24 1.26.5 1.62.8.35.3.53.64.53',\n\t' 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54',\n\t'-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96',\n\t' 2.67.96.92 0 1.81-.3 2.46-.84.67-.56 1.04-1.33 1.04-2.18 0-.81-.36-1.56',\n\t'-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46',\n\t'-.59-.46-.94z\"/>',\n\t'<path d=\"M5.88 18h2.66l3.4-5.42L15.3 18h2.67l-4.73-7.38',\n\t' 4.37-6.62h-2.6l-3.07 4.98L8.92 4h-2.6l4.26 6.58z\"/>',\n\t'</svg>',\n].join('');\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'superscript',\n\t\topposite: 'subscript',\n\t\tconfigKey: 'superscript',\n\t\trank: 4,\n\t\ttag: 'sup',\n\t\tlabel: 'Superscript',\n\t\ticon: SUPERSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-.',\n\t\ttoolbarPriority: 50,\n\t},\n\t{\n\t\ttype: 'subscript',\n\t\topposite: 'superscript',\n\t\tconfigKey: 'subscript',\n\t\trank: 4,\n\t\ttag: 'sub',\n\t\tlabel: 'Subscript',\n\t\ticon: SUBSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-,',\n\t\ttoolbarPriority: 51,\n\t},\n];\n\n// --- Plugin ---\n\nexport class SuperSubPlugin implements Plugin {\n\treadonly id = 'super-sub';\n\treadonly name = 'Superscript & Subscript';\n\treadonly priority = 23;\n\n\tprivate readonly config: SuperSubConfig;\n\n\tconstructor(config?: Partial<SuperSubConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tconst enabledMarks: MarkDefinition[] = MARK_DEFINITIONS.filter(\n\t\t\t(def) => this.config[def.configKey],\n\t\t);\n\n\t\tconst visibleToolbarMarks: MarkDefinition[] = enabledMarks.filter((def) =>\n\t\t\tthis.isToolbarVisible(def.configKey),\n\t\t);\n\t\tconst lastVisibleMark: MarkDefinition | undefined = visibleToolbarMarks.at(-1);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tconst isSeparatorTarget: boolean = !!this.config.separatorAfter && def === lastVisibleMark;\n\t\t\tthis.registerMark(context, def, isSeparatorTarget);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\t\tthis.registerExclusivityMiddleware(context, enabledMarks);\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(context: PluginContext, def: MarkDefinition, separatorAfter: boolean): void {\n\t\tconst commandName: string = toCommandName(def.type);\n\t\tconst toolbarVisible: boolean = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel: def.label,\n\t\t\t\ttooltip: `${def.label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tpriority: def.toolbarPriority,\n\t\t\t\tseparatorAfter,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName: string = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Ensures superscript and subscript are mutually exclusive.\n\t * When an addMark step for one type is found, a removeMark step\n\t * for the opposite type is injected. For stored marks, the opposite\n\t * mark is filtered out.\n\t */\n\tprivate registerExclusivityMiddleware(\n\t\tcontext: PluginContext,\n\t\tenabledMarks: readonly MarkDefinition[],\n\t): void {\n\t\tconst bothEnabled: boolean =\n\t\t\tenabledMarks.some((d) => d.type === 'superscript') &&\n\t\t\tenabledMarks.some((d) => d.type === 'subscript');\n\n\t\tif (!bothEnabled) return;\n\n\t\tcontext.registerMiddleware((tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\t// Handle addMark steps: inject removeMark for the opposite type\n\t\t\tconst patchedSteps: Step[] = [];\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type !== 'addMark') {\n\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst markName: string = step.mark.type;\n\t\t\t\tconst def: MarkDefinition | undefined = MARK_DEFINITIONS.find((d) => d.type === markName);\n\t\t\t\tif (!def) {\n\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tpatched = true;\n\t\t\t\tconst removeStep: RemoveMarkStep = {\n\t\t\t\t\ttype: 'removeMark',\n\t\t\t\t\tblockId: step.blockId,\n\t\t\t\t\tfrom: step.from,\n\t\t\t\t\tto: step.to,\n\t\t\t\t\tmark: { type: mkType(def.opposite) },\n\t\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t\t};\n\t\t\t\tpatchedSteps.push(removeStep, step);\n\t\t\t}\n\n\t\t\t// Handle stored marks: remove the opposite mark\n\t\t\tlet storedMarksAfter: readonly Mark[] | null = tr.storedMarksAfter;\n\t\t\tif (storedMarksAfter) {\n\t\t\t\tconst hasSup: boolean = storedMarksAfter.some((m) => m.type === 'superscript');\n\t\t\t\tconst hasSub: boolean = storedMarksAfter.some((m) => m.type === 'subscript');\n\n\t\t\t\tif (hasSup && hasSub) {\n\t\t\t\t\t// Keep the one that was most recently added (last in array)\n\t\t\t\t\tconst lastSupIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t(m) => m.type === 'superscript',\n\t\t\t\t\t);\n\t\t\t\t\tconst lastSubIdx: number = storedMarksAfter.findLastIndex((m) => m.type === 'subscript');\n\t\t\t\t\tconst removeType: string = lastSupIdx > lastSubIdx ? 'subscript' : 'superscript';\n\n\t\t\t\t\tstoredMarksAfter = storedMarksAfter.filter((m) => m.type !== removeType);\n\t\t\t\t\tpatched = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps, storedMarksAfter } : tr);\n\t\t});\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled: boolean = this.config[def.configKey];\n\t\t\tconst toolbarVisible: boolean = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: def.label,\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tpriority: def.toolbarPriority,\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<SuperSubConfig, 'toolbar' | 'separatorAfter'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'superscript' → 'toggleSuperscript'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n","/**\n * Input handler: intercepts all beforeinput events, maps them to transactions.\n * After text insertion, checks registered InputRules for pattern matches.\n */\n\nimport {\n\tdeleteBackward,\n\tdeleteForward,\n\tdeleteSoftLineBackward,\n\tdeleteSoftLineForward,\n\tdeleteWordBackward,\n\tdeleteWordForward,\n\tinsertTextCommand,\n\tsplitBlockCommand,\n} from '../commands/Commands.js';\nimport { getBlockText } from '../model/Document.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { Transaction } from '../state/Transaction.js';\n\nimport type { EditorState } from '../state/EditorState.js';\n\nexport type DispatchFn = (tr: Transaction) => void;\nexport type GetStateFn = () => EditorState;\nexport type UndoFn = () => void;\nexport type RedoFn = () => void;\n\nexport type SyncSelectionFn = () => void;\n\nexport interface InputHandlerOptions {\n\tgetState: GetStateFn;\n\tdispatch: DispatchFn;\n\tsyncSelection: SyncSelectionFn;\n\tschemaRegistry?: SchemaRegistry;\n}\n\nexport class InputHandler {\n\tprivate readonly getState: GetStateFn;\n\tprivate readonly dispatch: DispatchFn;\n\tprivate readonly syncSelection: SyncSelectionFn;\n\tprivate readonly schemaRegistry?: SchemaRegistry;\n\tprivate composing = false;\n\n\tprivate readonly handleBeforeInput: (e: InputEvent) => void;\n\tprivate readonly handleCompositionStart: (e: CompositionEvent) => void;\n\tprivate readonly handleCompositionEnd: (e: CompositionEvent) => void;\n\n\tconstructor(\n\t\tprivate readonly element: HTMLElement,\n\t\toptions: InputHandlerOptions,\n\t) {\n\t\tthis.getState = options.getState;\n\t\tthis.dispatch = options.dispatch;\n\t\tthis.syncSelection = options.syncSelection;\n\t\tthis.schemaRegistry = options.schemaRegistry;\n\n\t\tthis.handleBeforeInput = this.onBeforeInput.bind(this);\n\t\tthis.handleCompositionStart = this.onCompositionStart.bind(this);\n\t\tthis.handleCompositionEnd = this.onCompositionEnd.bind(this);\n\n\t\telement.addEventListener('beforeinput', this.handleBeforeInput);\n\t\telement.addEventListener('compositionstart', this.handleCompositionStart);\n\t\telement.addEventListener('compositionend', this.handleCompositionEnd);\n\t}\n\n\tprivate onBeforeInput(e: InputEvent): void {\n\t\t// During composition, let the browser handle it\n\t\tif (this.composing && e.inputType === 'insertCompositionText') {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\n\t\t// Sync selection from DOM before processing non-insert operations\n\t\t// (handles arrow key / mouse navigation that doesn't go through our state)\n\t\tconst needsSelectionSync =\n\t\t\te.inputType !== 'insertText' && e.inputType !== 'insertCompositionText';\n\t\tif (needsSelectionSync) {\n\t\t\tthis.syncSelection();\n\t\t}\n\n\t\tconst state = this.getState();\n\t\tlet tr: Transaction | null = null;\n\n\t\tswitch (e.inputType) {\n\t\t\tcase 'insertText':\n\t\t\t\tif (e.data) {\n\t\t\t\t\ttr = insertTextCommand(state, e.data, 'input');\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'insertParagraph':\n\t\t\tcase 'insertLineBreak':\n\t\t\t\ttr = splitBlockCommand(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteContentBackward':\n\t\t\t\ttr = deleteBackward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteContentForward':\n\t\t\t\ttr = deleteForward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteWordBackward':\n\t\t\t\ttr = deleteWordBackward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteWordForward':\n\t\t\t\ttr = deleteWordForward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteSoftLineBackward':\n\t\t\t\ttr = deleteSoftLineBackward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteSoftLineForward':\n\t\t\t\ttr = deleteSoftLineForward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'deleteByCut':\n\t\t\t\ttr = deleteBackward(state);\n\t\t\t\tbreak;\n\n\t\t\tcase 'insertFromPaste':\n\t\t\t\t// Handled by PasteHandler\n\t\t\t\tbreak;\n\n\t\t\tcase 'insertFromDrop':\n\t\t\t\t// Handled by PasteHandler\n\t\t\t\tbreak;\n\n\t\t\tcase 'formatBold':\n\t\t\tcase 'formatItalic':\n\t\t\tcase 'formatUnderline':\n\t\t\tcase 'historyUndo':\n\t\t\tcase 'historyRedo':\n\t\t\t\t// Handled by KeyboardHandler — just prevent default\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (tr) {\n\t\t\tthis.dispatch(tr);\n\n\t\t\t// Check input rules after text insertion\n\t\t\tif (e.inputType === 'insertText') {\n\t\t\t\tthis.checkInputRules();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onCompositionStart(_e: CompositionEvent): void {\n\t\tthis.composing = true;\n\t}\n\n\tprivate onCompositionEnd(e: CompositionEvent): void {\n\t\tthis.composing = false;\n\t\tconst composedText = e.data;\n\t\tif (!composedText) return;\n\n\t\tconst state = this.getState();\n\t\tconst tr = insertTextCommand(state, composedText, 'input');\n\t\tthis.dispatch(tr);\n\t}\n\n\tprivate checkInputRules(): void {\n\t\tif (!this.schemaRegistry) return;\n\t\tconst rules = this.schemaRegistry.getInputRules();\n\t\tif (rules.length === 0) return;\n\n\t\tconst state = this.getState();\n\t\tconst { anchor } = state.selection;\n\t\tconst block = state.getBlock(anchor.blockId);\n\t\tif (!block) return;\n\n\t\tconst text = getBlockText(block);\n\t\tconst textBefore = text.slice(0, anchor.offset);\n\n\t\tfor (const rule of rules) {\n\t\t\tconst match = rule.pattern.exec(textBefore);\n\t\t\tif (match) {\n\t\t\t\tconst start = match.index;\n\t\t\t\tconst end = start + match[0].length;\n\t\t\t\tconst tr = rule.handler(state, match, start, end);\n\t\t\t\tif (tr) {\n\t\t\t\t\tthis.dispatch(tr);\n\t\t\t\t\treturn; // Only first matching rule fires\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.element.removeEventListener('beforeinput', this.handleBeforeInput);\n\t\tthis.element.removeEventListener('compositionstart', this.handleCompositionStart);\n\t\tthis.element.removeEventListener('compositionend', this.handleCompositionEnd);\n\t}\n}\n","/**\n * Paste handler: intercepts paste events and converts clipboard content to transactions.\n */\n\nimport DOMPurify from 'dompurify';\nimport { insertTextCommand } from '../commands/Commands.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { DispatchFn, GetStateFn } from './InputHandler.js';\n\nexport interface PasteHandlerOptions {\n\tgetState: GetStateFn;\n\tdispatch: DispatchFn;\n\tschemaRegistry?: SchemaRegistry;\n}\n\nexport class PasteHandler {\n\tprivate readonly getState: GetStateFn;\n\tprivate readonly dispatch: DispatchFn;\n\tprivate readonly handlePaste: (e: ClipboardEvent) => void;\n\n\tconstructor(\n\t\tprivate readonly element: HTMLElement,\n\t\toptions: PasteHandlerOptions,\n\t) {\n\t\tthis.getState = options.getState;\n\t\tthis.dispatch = options.dispatch;\n\n\t\tthis.handlePaste = this.onPaste.bind(this);\n\t\telement.addEventListener('paste', this.handlePaste);\n\t}\n\n\tprivate onPaste(e: ClipboardEvent): void {\n\t\te.preventDefault();\n\n\t\tconst clipboardData = e.clipboardData;\n\t\tif (!clipboardData) return;\n\n\t\tconst state = this.getState();\n\n\t\t// Try HTML first, fall back to plain text\n\t\tconst html = clipboardData.getData('text/html');\n\t\tif (html) {\n\t\t\tconst sanitized = DOMPurify.sanitize(html, {\n\t\t\t\tALLOWED_TAGS: ['strong', 'em', 'u', 'b', 'i', 'p', 'br', 'div', 'span'],\n\t\t\t\tALLOWED_ATTR: [],\n\t\t\t});\n\n\t\t\t// TODO: Rich-text paste not yet supported — extract plain text for now\n\t\t\tconst text = this.extractTextFromHTML(sanitized);\n\t\t\tif (text) {\n\t\t\t\tconst tr = insertTextCommand(state, text, 'paste');\n\t\t\t\tthis.dispatch(tr);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst text = clipboardData.getData('text/plain');\n\t\tif (text) {\n\t\t\tconst tr = insertTextCommand(state, text, 'paste');\n\t\t\tthis.dispatch(tr);\n\t\t}\n\t}\n\n\tprivate extractTextFromHTML(html: string): string {\n\t\tconst template = document.createElement('template');\n\t\ttemplate.innerHTML = html;\n\t\treturn template.content.textContent ?? '';\n\t}\n\n\tdestroy(): void {\n\t\tthis.element.removeEventListener('paste', this.handlePaste);\n\t}\n}\n","/**\n * Selection synchronization between editor state and DOM.\n */\n\nimport type { Position, Selection } from '../model/Selection.js';\nimport { createPosition, createSelection } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport { blockId as toBlockId } from '../model/TypeBrands.js';\n\ninterface DOMPosition {\n\tnode: Node;\n\toffset: number;\n}\n\n/** Gets the selection object, preferring shadow root's selection for Shadow DOM. */\nfunction getSelection(container: HTMLElement): globalThis.Selection | null {\n\tconst root = container.getRootNode();\n\tif (root instanceof ShadowRoot && 'getSelection' in root) {\n\t\treturn (root as ShadowRoot & { getSelection(): globalThis.Selection | null }).getSelection();\n\t}\n\treturn window.getSelection();\n}\n\n/** Syncs the editor state selection to the DOM. */\nexport function syncSelectionToDOM(container: HTMLElement, selection: Selection): void {\n\tconst domSel = getSelection(container);\n\tif (!domSel) return;\n\n\tconst anchorPos = statePositionToDOM(container, selection.anchor);\n\tconst headPos = statePositionToDOM(container, selection.head);\n\n\tif (!anchorPos || !headPos) return;\n\n\ttry {\n\t\tdomSel.setBaseAndExtent(anchorPos.node, anchorPos.offset, headPos.node, headPos.offset);\n\t} catch {\n\t\t// Selection may fail if DOM is not yet rendered\n\t}\n}\n\n/** Reads the current DOM selection and converts it to a state selection. */\nexport function readSelectionFromDOM(container: HTMLElement): Selection | null {\n\tconst domSel = getSelection(container);\n\tif (!domSel || domSel.rangeCount === 0) return null;\n\n\tconst anchorNode = domSel.anchorNode;\n\tconst focusNode = domSel.focusNode;\n\n\tif (!anchorNode || !focusNode) return null;\n\tif (!container.contains(anchorNode) || !container.contains(focusNode)) return null;\n\n\tconst anchor = domPositionToState(container, anchorNode, domSel.anchorOffset);\n\tconst head = domPositionToState(container, focusNode, domSel.focusOffset);\n\n\tif (!anchor || !head) return null;\n\n\treturn createSelection(anchor, head);\n}\n\n/** Converts a state position (blockId + offset) to a DOM position (node + offset). */\nfunction statePositionToDOM(container: HTMLElement, pos: Position): DOMPosition | null {\n\t// If path is available, navigate directly to the leaf block\n\tlet blockEl: Element | null = null;\n\tif (pos.path && pos.path.length > 0) {\n\t\tlet current: Element = container;\n\t\tfor (const id of pos.path) {\n\t\t\tconst found = current.querySelector(`:scope [data-block-id=\"${id}\"]`);\n\t\t\tif (!found) break;\n\t\t\tcurrent = found;\n\t\t}\n\t\tif (current !== container && current.getAttribute('data-block-id') === pos.blockId) {\n\t\t\tblockEl = current;\n\t\t}\n\t}\n\tblockEl ??= container.querySelector(`[data-block-id=\"${pos.blockId}\"]`);\n\tif (!blockEl) return null;\n\n\t// Handle empty paragraphs with <br>\n\tif (blockEl.childNodes.length === 1 && blockEl.firstChild?.nodeName === 'BR') {\n\t\treturn { node: blockEl, offset: 0 };\n\t}\n\n\t// Walk through text nodes and inline elements to find the correct position\n\tlet remaining = pos.offset;\n\tconst walker = createInlineContentWalker(blockEl);\n\n\tlet current = walker.nextNode();\n\twhile (current) {\n\t\tif (current.nodeType === Node.TEXT_NODE) {\n\t\t\tconst len = current.textContent?.length ?? 0;\n\t\t\tif (remaining <= len) {\n\t\t\t\treturn { node: current, offset: remaining };\n\t\t\t}\n\t\t\tremaining -= len;\n\t\t} else if (\n\t\t\tcurrent instanceof HTMLElement &&\n\t\t\tcurrent.getAttribute('contenteditable') === 'false'\n\t\t) {\n\t\t\t// InlineNode element — width 1 in state offset space\n\t\t\tif (remaining === 0) {\n\t\t\t\t// Position before this inline element\n\t\t\t\tconst parent = current.parentNode;\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst childIndex = childIndexOf(parent, current);\n\t\t\t\t\treturn { node: parent, offset: childIndex };\n\t\t\t\t}\n\t\t\t}\n\t\t\tremaining -= 1;\n\t\t}\n\t\tcurrent = walker.nextNode();\n\t}\n\n\t// Fallback: position at end of block\n\tconst lastChild = blockEl.lastChild;\n\tif (lastChild) {\n\t\tif (lastChild.nodeType === Node.TEXT_NODE) {\n\t\t\treturn { node: lastChild, offset: lastChild.textContent?.length ?? 0 };\n\t\t}\n\t\treturn { node: blockEl, offset: blockEl.childNodes.length };\n\t}\n\n\treturn { node: blockEl, offset: 0 };\n}\n\n/** Converts a DOM position to a state position, including nested path. */\nfunction domPositionToState(\n\tcontainer: HTMLElement,\n\tnode: Node,\n\tdomOffset: number,\n): Position | null {\n\t// Find the innermost block element\n\tconst blockEl = findBlockElement(container, node);\n\tif (!blockEl) return null;\n\n\tconst rawBlockId = blockEl.getAttribute('data-block-id');\n\tif (!rawBlockId) return null;\n\tconst bid = toBlockId(rawBlockId);\n\n\t// Build path by collecting all data-block-id ancestors from leaf to root\n\tconst path = buildBlockPath(container, blockEl);\n\n\t// Handle clicks on the block element itself (e.g. empty paragraph with <br>)\n\tif (node === blockEl) {\n\t\tlet childOffset = 0;\n\t\tlet childIdx = 0;\n\t\tfor (const child of Array.from(blockEl.childNodes)) {\n\t\t\tif (childIdx >= domOffset) break;\n\t\t\tchildOffset += inlineContentWidth(child);\n\t\t\tchildIdx++;\n\t\t}\n\t\treturn createPosition(bid, childOffset, path.length > 1 ? path : undefined);\n\t}\n\n\t// Calculate offset by walking text nodes and inline elements\n\tlet offset = 0;\n\tconst walker = createInlineContentWalker(blockEl);\n\n\tlet walkerNode = walker.nextNode();\n\twhile (walkerNode) {\n\t\tif (walkerNode === node) {\n\t\t\tif (walkerNode.nodeType === Node.TEXT_NODE) {\n\t\t\t\treturn createPosition(bid, offset + domOffset, path.length > 1 ? path : undefined);\n\t\t\t}\n\t\t\t// Node is an inline element — return offset at its start\n\t\t\treturn createPosition(bid, offset, path.length > 1 ? path : undefined);\n\t\t}\n\t\tif (walkerNode.nodeType === Node.TEXT_NODE) {\n\t\t\toffset += walkerNode.textContent?.length ?? 0;\n\t\t} else if (\n\t\t\twalkerNode instanceof HTMLElement &&\n\t\t\twalkerNode.getAttribute('contenteditable') === 'false'\n\t\t) {\n\t\t\toffset += 1;\n\t\t}\n\t\twalkerNode = walker.nextNode();\n\t}\n\n\t// If the node is not a text node, try to find the offset from element context\n\tif (node.nodeType === Node.ELEMENT_NODE) {\n\t\tlet childOffset = 0;\n\t\tlet childIdx = 0;\n\n\t\tfor (const child of Array.from(node.childNodes)) {\n\t\t\tif (childIdx >= domOffset) break;\n\t\t\tchildOffset += inlineContentWidth(child);\n\t\t\tchildIdx++;\n\t\t}\n\n\t\treturn createPosition(bid, childOffset, path.length > 1 ? path : undefined);\n\t}\n\n\treturn createPosition(bid, 0, path.length > 1 ? path : undefined);\n}\n\n/** Builds an array of block IDs from root to leaf by walking up from a block element. */\nfunction buildBlockPath(container: HTMLElement, leafBlockEl: HTMLElement): BlockId[] {\n\tconst path: BlockId[] = [];\n\tlet current: HTMLElement | null = leafBlockEl;\n\n\twhile (current && current !== container) {\n\t\tif (current.hasAttribute('data-block-id')) {\n\t\t\tpath.unshift(toBlockId(current.getAttribute('data-block-id') ?? ''));\n\t\t}\n\t\tcurrent = current.parentElement;\n\t}\n\n\treturn path;\n}\n\n/** Finds the closest block element ancestor. */\nfunction findBlockElement(container: HTMLElement, node: Node): HTMLElement | null {\n\tlet current: Node | null = node;\n\twhile (current && current !== container) {\n\t\tif (current instanceof HTMLElement && current.hasAttribute('data-block-id')) {\n\t\t\treturn current;\n\t\t}\n\t\tcurrent = current.parentNode;\n\t}\n\treturn null;\n}\n\n/** Checks if a node is inside a contentEditable=\"false\" inline element. */\nfunction isInsideInlineElement(node: Node, root: Element): boolean {\n\tlet parent: Node | null = node.parentNode;\n\twhile (parent && parent !== root) {\n\t\tif (parent instanceof HTMLElement && parent.getAttribute('contenteditable') === 'false') {\n\t\t\treturn true;\n\t\t}\n\t\tparent = parent.parentNode;\n\t}\n\treturn false;\n}\n\n/**\n * Creates a TreeWalker that visits text nodes and contentEditable=\"false\"\n * inline elements within a block, skipping mark wrappers and nested blocks.\n */\nfunction createInlineContentWalker(blockEl: Element): TreeWalker {\n\treturn document.createTreeWalker(blockEl, NodeFilter.SHOW_ALL, {\n\t\tacceptNode: (n: Node) => {\n\t\t\t// Skip anything inside an inline element (contentEditable=\"false\")\n\t\t\tif (isInsideInlineElement(n, blockEl)) return NodeFilter.FILTER_REJECT;\n\t\t\t// Skip nested block elements and their descendants\n\t\t\tif (n instanceof HTMLElement && n.hasAttribute('data-block-id') && n !== blockEl) {\n\t\t\t\treturn NodeFilter.FILTER_REJECT;\n\t\t\t}\n\t\t\t// Accept text nodes\n\t\t\tif (n.nodeType === Node.TEXT_NODE) return NodeFilter.FILTER_ACCEPT;\n\t\t\t// Accept inline elements (contentEditable=\"false\")\n\t\t\tif (n instanceof HTMLElement && n.getAttribute('contenteditable') === 'false') {\n\t\t\t\treturn NodeFilter.FILTER_ACCEPT;\n\t\t\t}\n\t\t\t// Skip other elements (mark wrappers, decoration wrappers) — descend\n\t\t\treturn NodeFilter.FILTER_SKIP;\n\t\t},\n\t});\n}\n\n/** Returns the child index of a node within its parent. */\nfunction childIndexOf(parent: Node, child: Node): number {\n\tlet idx = 0;\n\tfor (const c of Array.from(parent.childNodes)) {\n\t\tif (c === child) return idx;\n\t\tidx++;\n\t}\n\treturn idx;\n}\n\n/** Counts the inline content width of a DOM node (text length + 1 per inline element). */\nfunction inlineContentWidth(node: Node): number {\n\tif (node.nodeType === Node.TEXT_NODE) {\n\t\treturn node.textContent?.length ?? 0;\n\t}\n\tif (node instanceof HTMLElement && node.getAttribute('contenteditable') === 'false') {\n\t\treturn 1;\n\t}\n\t// Mark wrapper or other element — sum children\n\tlet width = 0;\n\tfor (const child of Array.from(node.childNodes)) {\n\t\twidth += inlineContentWidth(child);\n\t}\n\treturn width;\n}\n","/**\n * EditorView: orchestrates input handling, reconciliation, and selection sync.\n */\n\nimport { DecorationSet } from '../decorations/Decoration.js';\nimport { InputHandler } from '../input/InputHandler.js';\nimport { KeyboardHandler } from '../input/KeyboardHandler.js';\nimport { PasteHandler } from '../input/PasteHandler.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport { HistoryManager } from '../state/History.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { NodeView } from './NodeView.js';\nimport { reconcile } from './Reconciler.js';\nimport { readSelectionFromDOM, syncSelectionToDOM } from './SelectionSync.js';\n\nexport type StateChangeCallback = (\n\toldState: EditorState,\n\tnewState: EditorState,\n\ttr: Transaction,\n) => void;\n\nexport interface EditorViewOptions {\n\tstate: EditorState;\n\tschemaRegistry?: SchemaRegistry;\n\tmaxHistoryDepth?: number;\n\tonStateChange?: StateChangeCallback;\n\tgetDecorations?: (state: EditorState, tr?: Transaction) => DecorationSet;\n}\n\nexport class EditorView {\n\tprivate state: EditorState;\n\tprivate readonly contentElement: HTMLElement;\n\tprivate readonly inputHandler: InputHandler;\n\tprivate readonly keyboardHandler: KeyboardHandler;\n\tprivate readonly pasteHandler: PasteHandler;\n\treadonly history: HistoryManager;\n\tprivate readonly stateChangeCallbacks: StateChangeCallback[] = [];\n\tprivate readonly handleSelectionChange: () => void;\n\tprivate isUpdating = false;\n\tprivate readonly schemaRegistry?: SchemaRegistry;\n\tprivate readonly nodeViews = new Map<string, NodeView>();\n\tprivate decorations: DecorationSet = DecorationSet.empty;\n\tprivate readonly getDecorations?: (state: EditorState, tr?: Transaction) => DecorationSet;\n\n\tconstructor(contentElement: HTMLElement, options: EditorViewOptions) {\n\t\tthis.state = options.state;\n\t\tthis.contentElement = contentElement;\n\t\tthis.schemaRegistry = options.schemaRegistry;\n\t\tthis.getDecorations = options.getDecorations;\n\n\t\tthis.history = new HistoryManager({\n\t\t\tmaxDepth: options.maxHistoryDepth ?? 100,\n\t\t});\n\n\t\tif (options.onStateChange) {\n\t\t\tthis.stateChangeCallbacks.push(options.onStateChange);\n\t\t}\n\n\t\tthis.inputHandler = new InputHandler(contentElement, {\n\t\t\tgetState: () => this.state,\n\t\t\tdispatch: (tr: Transaction) => this.dispatch(tr),\n\t\t\tsyncSelection: () => this.syncSelectionFromDOM(),\n\t\t\tschemaRegistry: this.schemaRegistry,\n\t\t});\n\t\tthis.keyboardHandler = new KeyboardHandler(contentElement, {\n\t\t\tgetState: () => this.state,\n\t\t\tdispatch: (tr: Transaction) => this.dispatch(tr),\n\t\t\tundo: () => this.undo(),\n\t\t\tredo: () => this.redo(),\n\t\t\tschemaRegistry: this.schemaRegistry,\n\t\t});\n\t\tthis.pasteHandler = new PasteHandler(contentElement, {\n\t\t\tgetState: () => this.state,\n\t\t\tdispatch: (tr: Transaction) => this.dispatch(tr),\n\t\t\tschemaRegistry: this.schemaRegistry,\n\t\t});\n\n\t\tthis.handleSelectionChange = this.onSelectionChange.bind(this);\n\t\tdocument.addEventListener('selectionchange', this.handleSelectionChange);\n\n\t\t// Initial render\n\t\tthis.decorations = this.getDecorations?.(this.state) ?? DecorationSet.empty;\n\t\treconcile(contentElement, null, this.state, {\n\t\t\t...this.reconcileOptions(),\n\t\t\tdecorations: this.decorations,\n\t\t});\n\t\tsyncSelectionToDOM(contentElement, this.state.selection);\n\t}\n\n\t/** Returns the current editor state. */\n\tgetState(): EditorState {\n\t\treturn this.state;\n\t}\n\n\t/**\n\t * Central update cycle: sets state, collects decorations, reconciles DOM,\n\t * syncs selection, and notifies listeners. Guarded against re-entrancy.\n\t */\n\tprivate applyUpdate(\n\t\tnewState: EditorState,\n\t\ttr: Transaction,\n\t\toptions?: { readonly pushHistory?: boolean },\n\t): void {\n\t\tif (this.isUpdating) return;\n\t\tthis.isUpdating = true;\n\t\ttry {\n\t\t\tconst oldState = this.state;\n\t\t\tthis.state = newState;\n\n\t\t\tif (options?.pushHistory && tr.metadata.origin !== 'history') {\n\t\t\t\tthis.history.push(tr);\n\t\t\t}\n\n\t\t\tconst oldDecorations = this.decorations;\n\t\t\tconst newDecorations = this.getDecorations?.(newState, tr) ?? DecorationSet.empty;\n\t\t\tthis.decorations = newDecorations;\n\n\t\t\treconcile(this.contentElement, oldState, newState, {\n\t\t\t\t...this.reconcileOptions(),\n\t\t\t\tdecorations: newDecorations,\n\t\t\t\toldDecorations,\n\t\t\t});\n\t\t\tsyncSelectionToDOM(this.contentElement, newState.selection);\n\n\t\t\tfor (const cb of this.stateChangeCallbacks) {\n\t\t\t\tcb(oldState, newState, tr);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.isUpdating = false;\n\t\t}\n\t}\n\n\t/** Dispatches a transaction, updates state, reconciles DOM, syncs selection. */\n\tdispatch(tr: Transaction): void {\n\t\tconst newState = this.state.apply(tr);\n\t\tthis.applyUpdate(newState, tr, { pushHistory: true });\n\t}\n\n\t/** Performs undo. */\n\tundo(): void {\n\t\t// Guard needed here: history.undo() mutates stacks before applyUpdate runs\n\t\tif (this.isUpdating) return;\n\t\tconst result = this.history.undo(this.state);\n\t\tif (!result) return;\n\t\tthis.applyUpdate(result.state, result.transaction);\n\t}\n\n\t/** Performs redo. */\n\tredo(): void {\n\t\t// Guard needed here: history.redo() mutates stacks before applyUpdate runs\n\t\tif (this.isUpdating) return;\n\t\tconst result = this.history.redo(this.state);\n\t\tif (!result) return;\n\t\tthis.applyUpdate(result.state, result.transaction);\n\t}\n\n\t/** Registers a state change callback. */\n\tonStateChange(callback: StateChangeCallback): () => void {\n\t\tthis.stateChangeCallbacks.push(callback);\n\t\treturn () => {\n\t\t\tconst idx = this.stateChangeCallbacks.indexOf(callback);\n\t\t\tif (idx !== -1) this.stateChangeCallbacks.splice(idx, 1);\n\t\t};\n\t}\n\n\t/** Replaces the editor state without destroying handlers or history. */\n\treplaceState(newState: EditorState): void {\n\t\tif (this.isUpdating) return;\n\t\tthis.isUpdating = true;\n\t\ttry {\n\t\t\tconst oldState = this.state;\n\t\t\tthis.state = newState;\n\t\t\tthis.history.clear();\n\n\t\t\tconst oldDecorations = this.decorations;\n\t\t\tconst newDecorations = this.getDecorations?.(newState) ?? DecorationSet.empty;\n\t\t\tthis.decorations = newDecorations;\n\n\t\t\treconcile(this.contentElement, oldState, newState, {\n\t\t\t\t...this.reconcileOptions(),\n\t\t\t\tdecorations: newDecorations,\n\t\t\t\toldDecorations,\n\t\t\t});\n\t\t\tsyncSelectionToDOM(this.contentElement, newState.selection);\n\t\t} finally {\n\t\t\tthis.isUpdating = false;\n\t\t}\n\t}\n\n\t/** Syncs the DOM selection to the editor state. */\n\tprivate syncSelectionFromDOM(): void {\n\t\tconst sel = readSelectionFromDOM(this.contentElement);\n\t\tif (!sel) return;\n\n\t\t// Check if selection actually changed\n\t\tconst currentSel = this.state.selection;\n\t\tif (\n\t\t\tsel.anchor.blockId === currentSel.anchor.blockId &&\n\t\t\tsel.anchor.offset === currentSel.anchor.offset &&\n\t\t\tsel.head.blockId === currentSel.head.blockId &&\n\t\t\tsel.head.offset === currentSel.head.offset\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Update state with new selection (clear stored marks on selection change)\n\t\tconst tr = this.state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(sel)\n\t\t\t.setStoredMarks(null, this.state.storedMarks)\n\t\t\t.build();\n\n\t\tconst newState = this.state.apply(tr);\n\t\tthis.applyUpdate(newState, tr);\n\t}\n\n\t/** Handles DOM selection changes (clicks, arrow keys). */\n\tprivate onSelectionChange(): void {\n\t\tif (this.isUpdating) return;\n\n\t\t// Only process if our content element is focused\n\t\tconst shadowRoot = this.contentElement.getRootNode() as ShadowRoot | Document;\n\t\tconst activeEl =\n\t\t\t'activeElement' in shadowRoot ? shadowRoot.activeElement : document.activeElement;\n\t\tif (!this.contentElement.contains(activeEl) && activeEl !== this.contentElement) return;\n\n\t\tthis.syncSelectionFromDOM();\n\t}\n\n\tprivate reconcileOptions() {\n\t\treturn {\n\t\t\tregistry: this.schemaRegistry,\n\t\t\tnodeViews: this.nodeViews,\n\t\t\tgetState: () => this.state,\n\t\t\tdispatch: (tr: Transaction) => this.dispatch(tr),\n\t\t};\n\t}\n\n\t/** Cleans up all event listeners and handlers. */\n\tdestroy(): void {\n\t\tthis.inputHandler.destroy();\n\t\tthis.keyboardHandler.destroy();\n\t\tthis.pasteHandler.destroy();\n\t\tdocument.removeEventListener('selectionchange', this.handleSelectionChange);\n\t\t// Destroy all NodeViews\n\t\tfor (const nv of this.nodeViews.values()) {\n\t\t\tnv.destroy?.();\n\t\t}\n\t\tthis.nodeViews.clear();\n\t}\n}\n","/**\n * Editor styles using Adopted Stylesheets for Shadow DOM.\n */\n\nconst EDITOR_CSS = `\n:host {\n\tdisplay: block;\n\tfont-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n\tfont-size: 16px;\n\tline-height: 1.6;\n\tcolor: #1a1a1a;\n}\n\n.notectl-editor {\n\tdisplay: flex;\n\tflex-direction: column;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 6px;\n\toverflow: hidden;\n\tbackground: #fff;\n}\n\n.notectl-editor:focus-within {\n\tborder-color: #4a90d9;\n\tbox-shadow: 0 0 0 2px rgba(74, 144, 217, 0.2);\n}\n\n/* Toolbar */\n.notectl-plugin-container--top {\n\tdisplay: flex;\n\talign-items: center;\n\tborder-bottom: 1px solid #e0e0e0;\n\tbackground: #f8f8f8;\n\tmin-height: 40px;\n}\n\n.notectl-toolbar {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 2px;\n\tpadding: 4px 8px;\n}\n\n.notectl-toolbar-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: #444;\n\tfont-size: 14px;\n\tline-height: 1;\n\tpadding: 0;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n.notectl-toolbar-btn:hover {\n\tbackground: #e8e8e8;\n\tborder-color: #d0d0d0;\n}\n\n.notectl-toolbar-btn--active {\n\tbackground: #d0e0f0;\n\tborder-color: #a0c0e0;\n\tcolor: #1a5fa0;\n}\n\n.notectl-toolbar-btn:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n.notectl-toolbar-btn:disabled:hover {\n\tbackground: transparent;\n\tborder-color: transparent;\n}\n\n.notectl-toolbar-btn__icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpointer-events: none;\n}\n\n.notectl-toolbar-btn__icon svg {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 18px;\n\tfill: currentColor;\n}\n\n/* Tooltip (rendered as fixed-position element in shadow root) */\n.notectl-toolbar-tooltip {\n\tposition: fixed;\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground: #1a1a1a;\n\tcolor: #fff;\n\tfont-size: 11px;\n\tfont-weight: 500;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 10001;\n\tline-height: 1.4;\n\tletter-spacing: 0.01em;\n\tfont-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.notectl-toolbar-separator {\n\tdisplay: inline-block;\n\twidth: 1px;\n\theight: 20px;\n\tbackground: #d0d0d0;\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\n/* Toolbar Popups */\n.notectl-toolbar-popup {\n\tbackground: #fff;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n\toverflow: hidden;\n}\n\n/* Dropdown */\n.notectl-dropdown {\n\tmin-width: 160px;\n\tpadding: 4px 0;\n}\n\n.notectl-dropdown__item {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: left;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: #333;\n\tline-height: 1.4;\n\tfont-family: inherit;\n\twhite-space: nowrap;\n}\n\n.notectl-dropdown__item:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-dropdown__item-icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tfont-weight: 600;\n\tcolor: #555;\n\tflex-shrink: 0;\n}\n\n.notectl-dropdown__item-label {\n\tflex: 1;\n}\n\n/* Content Area */\n.notectl-content {\n\tflex: 1;\n\tpadding: 12px 16px;\n\toutline: none;\n\tmin-height: var(--notectl-content-min-height, 400px);\n\tcursor: text;\n\tposition: relative;\n}\n\n.notectl-content p {\n\tmargin: 0;\n\tpadding: 2px 0;\n\tmin-height: 1.6em;\n}\n\n.notectl-content p + p {\n\tmargin-top: 0;\n}\n\n/* List Items */\n.notectl-list-item {\n\tmargin: 0;\n\tpadding: 2px 0 2px 24px;\n\tmin-height: 1.6em;\n\tposition: relative;\n}\n\n.notectl-list-item::before {\n\tposition: absolute;\n\tleft: 0;\n\tdisplay: inline-block;\n\twidth: 24px;\n\ttext-align: center;\n}\n\n/* Bullet List */\n.notectl-list-item--bullet::before {\n\tcontent: '\\\\2022';\n\tcolor: #444;\n}\n\n/* Ordered List — uses CSS counters to auto-number */\n.notectl-content {\n\tcounter-reset: notectl-ordered;\n}\n\n.notectl-list-item--ordered {\n\tcounter-increment: notectl-ordered;\n}\n\n/* Reset counter when a non-ordered item breaks the sequence */\n.notectl-list-item:not(.notectl-list-item--ordered) + .notectl-list-item--ordered {\n\tcounter-reset: notectl-ordered;\n\tcounter-increment: notectl-ordered;\n}\n\n:not(.notectl-list-item--ordered) + .notectl-list-item--ordered,\n.notectl-content > .notectl-list-item--ordered:first-child {\n\tcounter-reset: notectl-ordered;\n\tcounter-increment: notectl-ordered;\n}\n\n.notectl-list-item--ordered::before {\n\tcontent: counter(notectl-ordered) '.';\n\tcolor: #444;\n\tfont-size: 14px;\n}\n\n/* Checklist */\n.notectl-list-item--checklist::before {\n\tcontent: '\\\\2610';\n\tfont-size: 16px;\n\tcolor: #666;\n\tcursor: pointer;\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"]::before {\n\tcontent: '\\\\2611';\n\tcolor: #1a8c1a;\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] {\n\tcolor: #888;\n\ttext-decoration: line-through;\n}\n\n/* Horizontal Rule */\n.notectl-content hr {\n\tborder: none;\n\tborder-top: 1px solid #d0d0d0;\n\tmargin: 8px 0;\n\tpadding: 0;\n\tcursor: default;\n\tuser-select: none;\n}\n\n/* Placeholder */\n.notectl-content.notectl-content--empty::before {\n\tcontent: attr(data-placeholder);\n\tcolor: #999;\n\tpointer-events: none;\n\tposition: absolute;\n\ttop: 12px;\n\tleft: 16px;\n}\n\n/* Plugin container bottom */\n.notectl-plugin-container--bottom {\n\tborder-top: 1px solid #e0e0e0;\n}\n\n/* Color Picker Popup */\n.notectl-color-picker {\n\tpadding: 8px;\n\tmin-width: 240px;\n}\n\n.notectl-color-picker__default {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding: 6px 12px;\n\tmargin-bottom: 8px;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 4px;\n\tbackground: #fff;\n\tcursor: pointer;\n\tfont-size: 13px;\n\tcolor: #333;\n\ttext-align: center;\n}\n\n.notectl-color-picker__default:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-color-picker__grid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(10, 1fr);\n\tgap: 3px;\n}\n\n.notectl-color-picker__swatch {\n\twidth: 22px;\n\theight: 22px;\n\tborder: 1px solid transparent;\n\tborder-radius: 3px;\n\tpadding: 0;\n\tcursor: pointer;\n\ttransition: transform 0.1s;\n}\n\n.notectl-color-picker__swatch:hover {\n\ttransform: scale(1.25);\n\tz-index: 1;\n}\n\n.notectl-color-picker__swatch--active {\n\tborder: 2px solid #1a5fa0;\n\tborder-radius: 3px;\n}\n\n.notectl-toolbar-btn--textColor .notectl-toolbar-btn__color-indicator {\n\tdisplay: block;\n\twidth: 16px;\n\theight: 3px;\n\tmargin-top: 1px;\n\tborder-radius: 1px;\n}\n\n/* Font Select — Combobox-style toolbar button */\n.notectl-toolbar-btn--font {\n\twidth: auto;\n\tmin-width: 100px;\n\tmax-width: 160px;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 4px;\n\tbackground: #fff;\n}\n\n.notectl-toolbar-btn--font:hover {\n\tbackground: #f5f5f5;\n\tborder-color: #b0b0b0;\n}\n\n.notectl-toolbar-btn--font.notectl-toolbar-btn--active {\n\tbackground: #fff;\n\tborder-color: #a0c0e0;\n}\n\n.notectl-toolbar-btn--font .notectl-toolbar-btn__icon {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 4px;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.notectl-toolbar-btn--font .notectl-toolbar-btn__icon svg {\n\tdisplay: none;\n}\n\n.notectl-font-select__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: #333;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: left;\n\tline-height: 30px;\n}\n\n.notectl-font-select__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: #888;\n\tline-height: 30px;\n}\n\n/* Font Picker Popup */\n.notectl-font-picker {\n\tmin-width: 200px;\n\tmax-height: 320px;\n\toverflow-y: auto;\n}\n\n.notectl-font-picker__list {\n\tpadding: 4px 0;\n}\n\n.notectl-font-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: #333;\n\tline-height: 1.4;\n\ttext-align: left;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n}\n\n.notectl-font-picker__item:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-font-picker__item--active {\n\tbackground: #e8f0fb;\n\tcolor: #1a5fa0;\n}\n\n.notectl-font-picker__item--active:hover {\n\tbackground: #d0e0f0;\n}\n\n.notectl-font-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: #1a5fa0;\n}\n\n.notectl-font-picker__label {\n\tflex: 1;\n}\n\n.notectl-font-picker__separator {\n\theight: 1px;\n\tbackground: #e0e0e0;\n\tmargin: 4px 8px;\n}\n\n/* Heading Select — Combobox-style toolbar button */\n.notectl-toolbar-btn--heading {\n\twidth: auto;\n\tmin-width: 100px;\n\tmax-width: 160px;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 4px;\n\tbackground: #fff;\n}\n\n.notectl-toolbar-btn--heading:hover {\n\tbackground: #f5f5f5;\n\tborder-color: #b0b0b0;\n}\n\n.notectl-toolbar-btn--heading.notectl-toolbar-btn--active {\n\tbackground: #fff;\n\tborder-color: #a0c0e0;\n}\n\n.notectl-toolbar-btn--heading .notectl-toolbar-btn__icon {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 4px;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.notectl-toolbar-btn--heading .notectl-toolbar-btn__icon svg {\n\tdisplay: none;\n}\n\n.notectl-heading-select__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: #333;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: left;\n\tline-height: 30px;\n}\n\n.notectl-heading-select__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: #888;\n\tline-height: 30px;\n}\n\n/* Heading Picker Popup */\n.notectl-heading-picker {\n\tmin-width: 200px;\n\tmax-height: 320px;\n\toverflow-y: auto;\n}\n\n.notectl-heading-picker__list {\n\tpadding: 4px 0;\n}\n\n.notectl-heading-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: #333;\n\ttext-align: left;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n}\n\n.notectl-heading-picker__item:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-heading-picker__item--active {\n\tbackground: #e8f0fb;\n\tcolor: #1a5fa0;\n}\n\n.notectl-heading-picker__item--active:hover {\n\tbackground: #d0e0f0;\n}\n\n.notectl-heading-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: #1a5fa0;\n}\n\n.notectl-heading-picker__label {\n\tflex: 1;\n}\n\n/* Screen reader announcements */\n.notectl-sr-only {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\tmargin: -1px;\n\tpadding: 0;\n\toverflow: hidden;\n\tclip: rect(0, 0, 0, 0);\n\twhite-space: nowrap;\n\tborder: 0;\n}\n\n/* Table */\n.notectl-table-wrapper {\n\tmargin: 8px 0;\n\toverflow-x: auto;\n\tposition: relative;\n}\n\n.notectl-table {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n}\n\n.notectl-table td {\n\tborder: 1px solid #d0d0d0;\n\tpadding: 8px 12px;\n\tmin-width: 60px;\n\tvertical-align: top;\n\tmin-height: 1.6em;\n}\n\n.notectl-table td:focus-within {\n\toutline: 2px solid #4a90d9;\n\toutline-offset: -2px;\n}\n\n.notectl-table-cell--selected {\n\tbackground: rgba(74, 144, 217, 0.15);\n}\n\n/* Table Context Menu */\n.notectl-table-context-menu {\n\tposition: fixed;\n\tbackground: #fff;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n\tpadding: 4px 0;\n\tmin-width: 180px;\n\tz-index: 10000;\n}\n\n.notectl-table-context-menu button {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: left;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: #333;\n\tfont-family: inherit;\n}\n\n.notectl-table-context-menu button:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-table-context-menu hr {\n\tborder: none;\n\tborder-top: 1px solid #e0e0e0;\n\tmargin: 4px 0;\n}\n\n/* === Table Controls === */\n\n/* Outer container for table + controls */\n.ntbl-container {\n\tposition: relative;\n\tmargin: 8px 0;\n\tpadding: 24px 0 0 24px;\n}\n\n.ntbl-container .notectl-table-wrapper {\n\tmargin: 0;\n}\n\n/* --- Column Handle Bar --- */\n.ntbl-col-bar {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 24px;\n\theight: 20px;\n\tdisplay: flex;\n\topacity: 0;\n\ttransition: opacity 0.2s ease;\n\tz-index: 3;\n\tpointer-events: none;\n}\n\n.ntbl-container:hover .ntbl-col-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n/* --- Row Handle Bar --- */\n.ntbl-row-bar {\n\tposition: absolute;\n\ttop: 24px;\n\tleft: 0;\n\twidth: 20px;\n\tdisplay: flex;\n\tflex-direction: column;\n\topacity: 0;\n\ttransition: opacity 0.2s ease;\n\tz-index: 3;\n\tpointer-events: none;\n}\n\n.ntbl-container:hover .ntbl-row-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n/* --- Handle (shared base) --- */\n.ntbl-handle {\n\tposition: absolute;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tcursor: pointer;\n\ttransition: background 0.15s ease;\n\tborder-radius: 3px;\n}\n\n.ntbl-col-handle {\n\theight: 100%;\n\tbackground: #edf0f4;\n\tborder-radius: 4px 4px 0 0;\n}\n\n.ntbl-col-handle:hover {\n\tbackground: #dce3ed;\n}\n\n.ntbl-row-handle {\n\twidth: 100%;\n\tbackground: #edf0f4;\n\tborder-radius: 4px 0 0 4px;\n}\n\n.ntbl-row-handle:hover {\n\tbackground: #dce3ed;\n}\n\n/* --- Handle Delete Button --- */\n.ntbl-handle-delete {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\theight: 16px;\n\tborder: none;\n\tbackground: transparent;\n\tcolor: #999;\n\tcursor: pointer;\n\tborder-radius: 3px;\n\tpadding: 0;\n\topacity: 0;\n\ttransform: scale(0.7);\n\ttransition: opacity 0.15s, transform 0.15s,\n\t\tbackground 0.15s, color 0.15s;\n}\n\n.ntbl-handle:hover .ntbl-handle-delete {\n\topacity: 1;\n\ttransform: scale(1);\n}\n\n.ntbl-handle-delete:hover {\n\tbackground: #fee2e2;\n\tcolor: #dc2626;\n}\n\n/* --- Insert Lines --- */\n.ntbl-insert-line {\n\tposition: absolute;\n\tpointer-events: none;\n\topacity: 0;\n\ttransition: opacity 0.15s ease;\n\tz-index: 6;\n}\n\n.ntbl-insert-line--visible {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.ntbl-insert-line--horizontal {\n\theight: 2px;\n\tbackground: linear-gradient(\n\t\t90deg,\n\t\ttransparent,\n\t\t#4a90d9 8%,\n\t\t#4a90d9 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px rgba(74, 144, 217, 0.35);\n}\n\n.ntbl-insert-line--vertical {\n\twidth: 2px;\n\tbackground: linear-gradient(\n\t\t180deg,\n\t\ttransparent,\n\t\t#4a90d9 8%,\n\t\t#4a90d9 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px rgba(74, 144, 217, 0.35);\n}\n\n/* --- Insert Button on Line --- */\n.ntbl-insert-btn {\n\tposition: absolute;\n\twidth: 20px;\n\theight: 20px;\n\tborder-radius: 50%;\n\tbackground: #fff;\n\tborder: 2px solid #4a90d9;\n\tcolor: #4a90d9;\n\tcursor: pointer;\n\tpointer-events: all;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 0;\n\tbox-shadow: 0 2px 8px rgba(74, 144, 217, 0.25);\n\ttransition: background 0.15s, color 0.15s,\n\t\ttransform 0.15s, box-shadow 0.15s;\n}\n\n.ntbl-insert-line--horizontal .ntbl-insert-btn {\n\tleft: 50%;\n\ttop: -9px;\n\ttransform: translateX(-50%);\n}\n\n.ntbl-insert-line--vertical .ntbl-insert-btn {\n\ttop: 50%;\n\tleft: -9px;\n\ttransform: translateY(-50%);\n}\n\n.ntbl-insert-btn:hover {\n\tbackground: #4a90d9;\n\tcolor: #fff;\n\tbox-shadow: 0 2px 12px rgba(74, 144, 217, 0.45);\n}\n\n.ntbl-insert-line--horizontal .ntbl-insert-btn:hover {\n\ttransform: translateX(-50%) scale(1.2);\n}\n\n.ntbl-insert-line--vertical .ntbl-insert-btn:hover {\n\ttransform: translateY(-50%) scale(1.2);\n}\n\n/* --- Add Row / Add Column Zones --- */\n.ntbl-add-zone {\n\tposition: absolute;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tcursor: pointer;\n\tuser-select: none;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.2s ease,\n\t\tborder-color 0.2s ease;\n}\n\n.ntbl-container:hover .ntbl-add-zone {\n\topacity: 1;\n}\n\n.ntbl-add-row {\n\tbottom: 0;\n\theight: 24px;\n\tborder: 1px dashed #d0d0d0;\n\tborder-radius: 0 0 6px 6px;\n\tborder-top: none;\n\tcolor: #aaa;\n\ttransform: translateY(100%);\n}\n\n.ntbl-add-row:hover {\n\tbackground: #f0f6ff;\n\tborder-color: #4a90d9;\n\tcolor: #4a90d9;\n}\n\n.ntbl-add-col {\n\tright: 0;\n\ttop: 24px;\n\twidth: 24px;\n\tborder: 1px dashed #d0d0d0;\n\tborder-radius: 0 6px 6px 0;\n\tborder-left: none;\n\tcolor: #aaa;\n\ttransform: translateX(100%);\n}\n\n.ntbl-add-col:hover {\n\tbackground: #f0f6ff;\n\tborder-color: #4a90d9;\n\tcolor: #4a90d9;\n}\n\n.ntbl-add-icon {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\ttransition: transform 0.2s ease;\n}\n\n.ntbl-add-zone:hover .ntbl-add-icon {\n\ttransform: scale(1.15);\n}\n\n/* Font Size Select — Combobox-style toolbar button */\n.notectl-toolbar-btn--fontSize {\n\twidth: auto;\n\tmin-width: 60px;\n\tmax-width: 80px;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 4px;\n\tbackground: #fff;\n}\n\n.notectl-toolbar-btn--fontSize:hover {\n\tbackground: #f5f5f5;\n\tborder-color: #b0b0b0;\n}\n\n.notectl-toolbar-btn--fontSize.notectl-toolbar-btn--active {\n\tbackground: #fff;\n\tborder-color: #a0c0e0;\n}\n\n.notectl-toolbar-btn--fontSize .notectl-toolbar-btn__icon {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 4px;\n\twidth: 100%;\n\toverflow: hidden;\n}\n\n.notectl-toolbar-btn--fontSize .notectl-toolbar-btn__icon svg {\n\tdisplay: none;\n}\n\n.notectl-font-size-select__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: #333;\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: left;\n\tline-height: 30px;\n}\n\n.notectl-font-size-select__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: #888;\n\tline-height: 30px;\n}\n\n/* Font Size Picker Popup */\n.notectl-font-size-picker {\n\tmin-width: 140px;\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.notectl-font-size-picker__input-wrapper {\n\tpadding: 8px 8px 4px;\n}\n\n.notectl-font-size-picker__input {\n\twidth: 100%;\n\tpadding: 6px 8px;\n\tborder: 1px solid #d0d0d0;\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tfont-family: inherit;\n\tcolor: #333;\n\toutline: none;\n\tbox-sizing: border-box;\n\t-moz-appearance: textfield;\n}\n\n.notectl-font-size-picker__input::-webkit-inner-spin-button,\n.notectl-font-size-picker__input::-webkit-outer-spin-button {\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n.notectl-font-size-picker__input:focus {\n\tborder-color: #4a90d9;\n\tbox-shadow: 0 0 0 2px rgba(74, 144, 217, 0.2);\n}\n\n.notectl-font-size-picker__list {\n\tmax-height: 280px;\n\toverflow-y: auto;\n\tpadding: 4px 0;\n}\n\n.notectl-font-size-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: #333;\n\tline-height: 1.4;\n\ttext-align: left;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n\toutline: none;\n}\n\n.notectl-font-size-picker__item:hover {\n\tbackground: #f0f0f0;\n}\n\n.notectl-font-size-picker__item--active {\n\tbackground: #e8f0fb;\n\tcolor: #1a5fa0;\n}\n\n.notectl-font-size-picker__item--active:hover {\n\tbackground: #d0e0f0;\n}\n\n.notectl-font-size-picker__item--focused {\n\toutline: 2px solid #4a90d9;\n\toutline-offset: -2px;\n}\n\n.notectl-font-size-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: #1a5fa0;\n}\n\n.notectl-font-size-picker__label {\n\tflex: 1;\n}\n`;\n\nlet cachedStyleSheet: CSSStyleSheet | null = null;\n\n/** Returns the shared editor stylesheet. */\nexport function getEditorStyleSheet(): CSSStyleSheet {\n\tif (!cachedStyleSheet) {\n\t\tcachedStyleSheet = new CSSStyleSheet();\n\t\tcachedStyleSheet.replaceSync(EDITOR_CSS);\n\t}\n\treturn cachedStyleSheet;\n}\n","/**\n * NotectlEditor Web Component — the public-facing editor element.\n */\n\nimport DOMPurify from 'dompurify';\nimport { isMarkActive, selectAll } from '../commands/Commands.js';\nimport { DecorationSet } from '../decorations/Decoration.js';\nimport { isMarkOfType, isNodeOfType } from '../model/AttrRegistry.js';\nimport { registerBuiltinSpecs } from '../model/BuiltinSpecs.js';\nimport {\n\ttype BlockNode,\n\ttype Document,\n\ttype Mark,\n\ttype TextNode,\n\tcreateBlockNode,\n\tcreateDocument,\n\tcreateTextNode,\n\tgetBlockText,\n\tgetTextChildren,\n} from '../model/Document.js';\nimport { schemaFromRegistry } from '../model/Schema.js';\nimport { isMarkAllowed } from '../model/Schema.js';\nimport { createCollapsedSelection } from '../model/Selection.js';\nimport { blockId, nodeType, markType as toMarkType } from '../model/TypeBrands.js';\nimport type { Plugin, PluginConfig } from '../plugins/Plugin.js';\nimport { PluginManager } from '../plugins/PluginManager.js';\nimport { TextFormattingPlugin } from '../plugins/text-formatting/TextFormattingPlugin.js';\nimport type { TextFormattingConfig } from '../plugins/text-formatting/TextFormattingPlugin.js';\nimport { ToolbarPlugin } from '../plugins/toolbar/ToolbarPlugin.js';\nimport type { ToolbarLayoutConfig } from '../plugins/toolbar/ToolbarPlugin.js';\nimport { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { EditorView } from '../view/EditorView.js';\nimport { getEditorStyleSheet } from './styles.js';\n\n// --- Config Types ---\n\nexport interface NotectlEditorConfig {\n\t/** Controls which inline marks are enabled. Used to auto-configure TextFormattingPlugin. */\n\tfeatures?: Partial<TextFormattingConfig>;\n\tplugins?: Plugin[];\n\t/**\n\t * Declarative toolbar layout. Each inner array is a visual group;\n\t * separators are rendered between groups. Order = array order.\n\t * When set, a ToolbarPlugin is created internally — do not add one to `plugins`.\n\t */\n\ttoolbar?: ReadonlyArray<ReadonlyArray<Plugin>>;\n\tplaceholder?: string;\n\treadonly?: boolean;\n\tautofocus?: boolean;\n\tmaxHistoryDepth?: number;\n}\n\n// --- Event Types ---\n\nexport interface StateChangeEvent {\n\toldState: EditorState;\n\tnewState: EditorState;\n\ttransaction: Transaction;\n}\n\ntype EventMap = {\n\tstateChange: StateChangeEvent;\n\tselectionChange: { selection: import('../model/Selection.js').Selection };\n\tfocus: undefined;\n\tblur: undefined;\n\tready: undefined;\n};\n\ntype EventCallback<T> = (payload: T) => void;\n\n// --- Web Component ---\n\nexport class NotectlEditor extends HTMLElement {\n\tprivate view: EditorView | null = null;\n\tprivate pluginManager: PluginManager | null = null;\n\tprivate contentElement: HTMLElement | null = null;\n\tprivate editorWrapper: HTMLElement | null = null;\n\tprivate topPluginContainer: HTMLElement | null = null;\n\tprivate bottomPluginContainer: HTMLElement | null = null;\n\tprivate announcer: HTMLElement | null = null;\n\tprivate config: NotectlEditorConfig = {};\n\tprivate eventListeners: Map<string, Set<EventCallback<unknown>>> = new Map();\n\tprivate readyPromiseResolve: (() => void) | null = null;\n\tprivate readonly readyPromise: Promise<void>;\n\tprivate initialized = false;\n\tprivate preInitPlugins: Plugin[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.readyPromise = new Promise((resolve) => {\n\t\t\tthis.readyPromiseResolve = resolve;\n\t\t});\n\t\tthis.attachShadow({ mode: 'open' });\n\t}\n\n\tstatic get observedAttributes(): string[] {\n\t\treturn ['placeholder', 'readonly'];\n\t}\n\n\tconnectedCallback(): void {\n\t\tif (this.initialized) return;\n\t\tthis.init();\n\t}\n\n\tdisconnectedCallback(): void {\n\t\tthis.destroy();\n\t}\n\n\tattributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void {\n\t\tif (name === 'placeholder' && this.contentElement) {\n\t\t\tthis.contentElement.setAttribute('data-placeholder', newValue ?? '');\n\t\t}\n\t\tif (name === 'readonly' && this.contentElement) {\n\t\t\tthis.contentElement.contentEditable = newValue === null ? 'true' : 'false';\n\t\t}\n\t}\n\n\t/** Registers a plugin before initialization. */\n\tregisterPlugin(plugin: Plugin): void {\n\t\tif (this.initialized) {\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot register plugins after initialization. Register before calling init() or adding to DOM.',\n\t\t\t);\n\t\t}\n\t\tthis.preInitPlugins.push(plugin);\n\t}\n\n\t/** Initializes the editor with the given config. */\n\tasync init(config?: NotectlEditorConfig): Promise<void> {\n\t\tif (this.initialized) return;\n\t\tthis.initialized = true;\n\n\t\tif (config) this.config = config;\n\n\t\tconst shadow = this.shadowRoot;\n\t\tif (!shadow) return;\n\t\tshadow.adoptedStyleSheets = [getEditorStyleSheet()];\n\n\t\t// 1. Build DOM structure\n\t\tthis.editorWrapper = document.createElement('div');\n\t\tthis.editorWrapper.className = 'notectl-editor';\n\n\t\tthis.topPluginContainer = document.createElement('div');\n\t\tthis.topPluginContainer.className = 'notectl-plugin-container--top';\n\n\t\tthis.contentElement = document.createElement('div');\n\t\tthis.contentElement.className = 'notectl-content';\n\t\tthis.contentElement.contentEditable = this.config.readonly ? 'false' : 'true';\n\t\tthis.contentElement.setAttribute('role', 'textbox');\n\t\tthis.contentElement.setAttribute('aria-multiline', 'true');\n\t\tthis.contentElement.setAttribute('aria-label', 'Rich text editor');\n\t\tthis.contentElement.setAttribute(\n\t\t\t'data-placeholder',\n\t\t\tthis.config.placeholder ?? 'Start typing...',\n\t\t);\n\n\t\tthis.bottomPluginContainer = document.createElement('div');\n\t\tthis.bottomPluginContainer.className = 'notectl-plugin-container--bottom';\n\n\t\t// Screen reader announcer\n\t\tthis.announcer = document.createElement('div');\n\t\tthis.announcer.className = 'notectl-sr-only';\n\t\tthis.announcer.setAttribute('aria-live', 'polite');\n\t\tthis.announcer.setAttribute('aria-atomic', 'true');\n\n\t\tthis.editorWrapper.appendChild(this.topPluginContainer);\n\t\tthis.editorWrapper.appendChild(this.contentElement);\n\t\tthis.editorWrapper.appendChild(this.bottomPluginContainer);\n\t\tthis.editorWrapper.appendChild(this.announcer);\n\n\t\tshadow.appendChild(this.editorWrapper);\n\n\t\t// 2. Create PluginManager (SchemaRegistry is available)\n\t\tthis.pluginManager = new PluginManager();\n\n\t\t// 3. Register built-in specs on the registry\n\t\tregisterBuiltinSpecs(this.pluginManager.schemaRegistry);\n\n\t\t// Process declarative toolbar config (registers ToolbarPlugin + toolbar plugins)\n\t\tthis.processToolbarConfig();\n\n\t\t// Register plugins from config\n\t\tfor (const plugin of this.config.plugins ?? []) {\n\t\t\tthis.pluginManager.register(plugin);\n\t\t}\n\n\t\t// Register plugins from registerPlugin() calls\n\t\tfor (const plugin of this.preInitPlugins) {\n\t\t\tthis.pluginManager.register(plugin);\n\t\t}\n\t\tthis.preInitPlugins = [];\n\n\t\t// Auto-register TextFormattingPlugin if none was explicitly provided\n\t\tthis.ensureTextFormattingPlugin();\n\n\t\t// Set up DOM events before plugin init\n\t\tthis.contentElement.addEventListener('focus', () => this.emit('focus', undefined));\n\t\tthis.contentElement.addEventListener('blur', () => this.emit('blur', undefined));\n\n\t\t// 4. Initialize plugins — specs are registered during init().\n\t\t// onBeforeReady fires after all init() but before onReady(),\n\t\t// so the schema is complete and the view renders once.\n\t\tconst contentEl = this.contentElement;\n\t\tconst pluginMgr = this.pluginManager;\n\t\tconst topContainer = this.topPluginContainer;\n\t\tconst bottomContainer = this.bottomPluginContainer;\n\t\tif (!contentEl || !pluginMgr || !topContainer || !bottomContainer) return;\n\n\t\tawait pluginMgr.init({\n\t\t\tgetState: () => {\n\t\t\t\tif (!this.view) throw new Error('View not initialized');\n\t\t\t\treturn this.view.getState();\n\t\t\t},\n\t\t\tdispatch: (tr) => this.dispatch(tr),\n\t\t\tgetContainer: () => contentEl,\n\t\t\tgetPluginContainer: (position) => (position === 'top' ? topContainer : bottomContainer),\n\t\t\tonBeforeReady: () => {\n\t\t\t\tconst schema = schemaFromRegistry(pluginMgr.schemaRegistry);\n\t\t\t\tconst state = EditorState.create({ schema });\n\t\t\t\tthis.view = new EditorView(contentEl, {\n\t\t\t\t\tstate,\n\t\t\t\t\tschemaRegistry: pluginMgr.schemaRegistry,\n\t\t\t\t\tmaxHistoryDepth: this.config.maxHistoryDepth,\n\t\t\t\t\tgetDecorations: (s, tr) =>\n\t\t\t\t\t\tthis.pluginManager?.collectDecorations(s, tr) ?? DecorationSet.empty,\n\t\t\t\t\tonStateChange: (oldState, newState, tr) => {\n\t\t\t\t\t\tthis.onStateChange(oldState, newState, tr);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tthis.updateEmptyState();\n\t\t\t},\n\t\t});\n\n\t\tif (this.config.autofocus) {\n\t\t\trequestAnimationFrame(() => this.contentElement?.focus());\n\t\t}\n\n\t\tthis.readyPromiseResolve?.();\n\t\tthis.emit('ready', undefined);\n\t}\n\n\t// --- Content API ---\n\n\t/** Returns the document as JSON. */\n\tgetJSON(): Document {\n\t\tif (!this.view) throw new Error('Editor not initialized');\n\t\treturn this.view.getState().doc;\n\t}\n\n\t/** Sets the document from JSON. */\n\tsetJSON(doc: Document): void {\n\t\tconst schema = this.pluginManager\n\t\t\t? schemaFromRegistry(this.pluginManager.schemaRegistry)\n\t\t\t: undefined;\n\t\tconst state = EditorState.create({\n\t\t\tdoc,\n\t\t\tschema,\n\t\t\tselection: createCollapsedSelection(doc.children[0]?.id ?? blockId(''), 0),\n\t\t});\n\t\tthis.replaceState(state);\n\t}\n\n\t/** Returns sanitized HTML representation of the document. */\n\tgetHTML(): string {\n\t\tif (!this.view) throw new Error('Editor not initialized');\n\t\tconst doc = this.view.getState().doc;\n\t\tconst parts: string[] = [];\n\t\tlet currentListTag: string | null = null;\n\n\t\tfor (const block of doc.children) {\n\t\t\tif (isNodeOfType(block, 'list_item')) {\n\t\t\t\tconst listType = block.attrs.listType;\n\t\t\t\tconst tag = listType === 'ordered' ? 'ol' : 'ul';\n\n\t\t\t\tif (currentListTag !== tag) {\n\t\t\t\t\tif (currentListTag) parts.push(`</${currentListTag}>`);\n\t\t\t\t\tparts.push(`<${tag}>`);\n\t\t\t\t\tcurrentListTag = tag;\n\t\t\t\t}\n\n\t\t\t\tconst inner = getTextChildren(block)\n\t\t\t\t\t.map((c) => this.textNodeToHTML(c))\n\t\t\t\t\t.join('');\n\t\t\t\tparts.push(`<li>${inner || '<br>'}</li>`);\n\t\t\t} else {\n\t\t\t\tif (currentListTag) {\n\t\t\t\t\tparts.push(`</${currentListTag}>`);\n\t\t\t\t\tcurrentListTag = null;\n\t\t\t\t}\n\t\t\t\tparts.push(this.blockToHTML(block));\n\t\t\t}\n\t\t}\n\n\t\tif (currentListTag) parts.push(`</${currentListTag}>`);\n\n\t\treturn DOMPurify.sanitize(parts.join(''), {\n\t\t\tALLOWED_TAGS: [\n\t\t\t\t'p',\n\t\t\t\t'strong',\n\t\t\t\t'em',\n\t\t\t\t'u',\n\t\t\t\t'b',\n\t\t\t\t'i',\n\t\t\t\t'br',\n\t\t\t\t'div',\n\t\t\t\t'hr',\n\t\t\t\t'h1',\n\t\t\t\t'h2',\n\t\t\t\t'h3',\n\t\t\t\t'h4',\n\t\t\t\t'h5',\n\t\t\t\t'h6',\n\t\t\t\t'ul',\n\t\t\t\t'ol',\n\t\t\t\t'li',\n\t\t\t\t'a',\n\t\t\t\t's',\n\t\t\t\t'span',\n\t\t\t\t'blockquote',\n\t\t\t],\n\t\t\tALLOWED_ATTR: ['href', 'target', 'rel', 'style'],\n\t\t});\n\t}\n\n\t/** Sets content from HTML (sanitized). */\n\tsetHTML(html: string): void {\n\t\tconst sanitized = DOMPurify.sanitize(html, {\n\t\t\tALLOWED_TAGS: [\n\t\t\t\t'p',\n\t\t\t\t'strong',\n\t\t\t\t'em',\n\t\t\t\t'u',\n\t\t\t\t'b',\n\t\t\t\t'i',\n\t\t\t\t'br',\n\t\t\t\t'div',\n\t\t\t\t'hr',\n\t\t\t\t'h1',\n\t\t\t\t'h2',\n\t\t\t\t'h3',\n\t\t\t\t'h4',\n\t\t\t\t'h5',\n\t\t\t\t'h6',\n\t\t\t\t'ul',\n\t\t\t\t'ol',\n\t\t\t\t'li',\n\t\t\t\t'a',\n\t\t\t\t's',\n\t\t\t\t'span',\n\t\t\t\t'blockquote',\n\t\t\t],\n\t\t\tALLOWED_ATTR: ['href', 'target', 'rel', 'style'],\n\t\t});\n\n\t\tconst doc = this.parseHTMLToDocument(sanitized);\n\t\tthis.setJSON(doc);\n\t}\n\n\t/** Returns plain text content. */\n\tgetText(): string {\n\t\tif (!this.view) throw new Error('Editor not initialized');\n\t\tconst doc = this.view.getState().doc;\n\t\treturn doc.children.map((b) => getBlockText(b)).join('\\n');\n\t}\n\n\t/** Returns true if the editor is empty (single empty paragraph). */\n\tisEmpty(): boolean {\n\t\tif (!this.view) return true;\n\t\tconst doc = this.view.getState().doc;\n\t\tif (doc.children.length === 0) return true;\n\t\tif (doc.children.length > 1) return false;\n\t\tconst block = doc.children[0];\n\t\tif (!block) return true;\n\t\treturn block.type === 'paragraph' && getBlockText(block) === '';\n\t}\n\n\t// --- Command API ---\n\n\treadonly commands = {\n\t\ttoggleBold: () => this.executeCommand('toggleBold'),\n\t\ttoggleItalic: () => this.executeCommand('toggleItalic'),\n\t\ttoggleUnderline: () => this.executeCommand('toggleUnderline'),\n\t\tundo: () => this.view?.undo(),\n\t\tredo: () => this.view?.redo(),\n\t\tselectAll: () => {\n\t\t\tif (!this.view) return;\n\t\t\tconst tr = selectAll(this.view.getState());\n\t\t\tthis.dispatch(tr);\n\t\t},\n\t};\n\n\t/** Checks whether a command can be executed. */\n\tcan(): {\n\t\ttoggleBold: () => boolean;\n\t\ttoggleItalic: () => boolean;\n\t\ttoggleUnderline: () => boolean;\n\t\tundo: () => boolean;\n\t\tredo: () => boolean;\n\t} {\n\t\tconst schema = this.view?.getState().schema;\n\t\treturn {\n\t\t\ttoggleBold: () => (schema ? isMarkAllowed(schema, 'bold') : false),\n\t\t\ttoggleItalic: () => (schema ? isMarkAllowed(schema, 'italic') : false),\n\t\t\ttoggleUnderline: () => (schema ? isMarkAllowed(schema, 'underline') : false),\n\t\t\tundo: () => this.view?.history.canUndo() ?? false,\n\t\t\tredo: () => this.view?.history.canRedo() ?? false,\n\t\t};\n\t}\n\n\t/** Executes a named command registered by a plugin. */\n\texecuteCommand(name: string): boolean {\n\t\treturn this.pluginManager?.executeCommand(name) ?? false;\n\t}\n\n\t/** Configures a plugin at runtime. */\n\tconfigurePlugin(pluginId: string, config: PluginConfig): void {\n\t\tthis.pluginManager?.configurePlugin(pluginId, config);\n\t}\n\n\t// --- State API ---\n\n\t/** Returns the current editor state. */\n\tgetState(): EditorState {\n\t\tif (!this.view) throw new Error('Editor not initialized');\n\t\treturn this.view.getState();\n\t}\n\n\t/** Dispatches a transaction (routed through middleware if any). */\n\tdispatch(tr: Transaction): void {\n\t\tif (!this.view || !this.pluginManager) return;\n\t\tthis.pluginManager.dispatchWithMiddleware(tr, this.view.getState(), (finalTr) =>\n\t\t\tthis.view?.dispatch(finalTr),\n\t\t);\n\t}\n\n\t// --- Event API ---\n\n\t/** Registers an event listener. */\n\ton<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): void {\n\t\tif (!this.eventListeners.has(event)) {\n\t\t\tthis.eventListeners.set(event, new Set());\n\t\t}\n\t\tthis.eventListeners.get(event)?.add(callback as EventCallback<unknown>);\n\t}\n\n\t/** Removes an event listener. */\n\toff<K extends keyof EventMap>(event: K, callback: EventCallback<EventMap[K]>): void {\n\t\tthis.eventListeners.get(event)?.delete(callback as EventCallback<unknown>);\n\t}\n\n\t// --- Lifecycle ---\n\n\t/** Waits for the editor to be ready. */\n\twhenReady(): Promise<void> {\n\t\treturn this.readyPromise;\n\t}\n\n\t/** Updates configuration at runtime. */\n\tconfigure(config: Partial<NotectlEditorConfig>): void {\n\t\tif (config.placeholder !== undefined && this.contentElement) {\n\t\t\tthis.contentElement.setAttribute('data-placeholder', config.placeholder);\n\t\t}\n\n\t\tif (config.readonly !== undefined && this.contentElement) {\n\t\t\tthis.contentElement.contentEditable = config.readonly ? 'false' : 'true';\n\t\t}\n\n\t\tthis.config = { ...this.config, ...config };\n\t}\n\n\t/** Cleans up the editor. Awaiting ensures async plugin teardown completes. */\n\tdestroy(): Promise<void> {\n\t\tthis.view?.destroy();\n\t\tconst pluginTeardown = this.pluginManager?.destroy() ?? Promise.resolve();\n\t\tthis.view = null;\n\t\tthis.pluginManager = null;\n\t\tthis.initialized = false;\n\t\treturn pluginTeardown;\n\t}\n\n\t// --- Private ---\n\n\t/**\n\t * Processes the declarative `toolbar` config: registers a ToolbarPlugin\n\t * with layout groups, then registers all plugins from the toolbar groups.\n\t */\n\tprivate processToolbarConfig(): void {\n\t\tif (!this.pluginManager || !this.config.toolbar) return;\n\n\t\tconst groups: string[][] = [];\n\t\tfor (const group of this.config.toolbar) {\n\t\t\tconst pluginIds: string[] = [];\n\t\t\tfor (const plugin of group) {\n\t\t\t\tpluginIds.push(plugin.id);\n\t\t\t\tthis.pluginManager.register(plugin);\n\t\t\t}\n\t\t\tgroups.push(pluginIds);\n\t\t}\n\n\t\tconst layoutConfig: ToolbarLayoutConfig = { groups };\n\t\tthis.pluginManager.register(new ToolbarPlugin(layoutConfig));\n\t}\n\n\t/**\n\t * Auto-registers TextFormattingPlugin if no plugin with id 'text-formatting'\n\t * was explicitly registered. Uses the `features` config to determine which marks to enable.\n\t */\n\tprivate ensureTextFormattingPlugin(): void {\n\t\tif (!this.pluginManager) return;\n\n\t\tconst hasTextFormatting = this.pluginManager.get('text-formatting') !== undefined;\n\t\tif (hasTextFormatting) return;\n\n\t\tconst features: TextFormattingConfig = {\n\t\t\tbold: this.config.features?.bold ?? true,\n\t\t\titalic: this.config.features?.italic ?? true,\n\t\t\tunderline: this.config.features?.underline ?? true,\n\t\t};\n\n\t\tthis.pluginManager.register(new TextFormattingPlugin(features));\n\t}\n\n\tprivate emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n\t\tconst listeners = this.eventListeners.get(event);\n\t\tif (listeners) {\n\t\t\tfor (const cb of listeners) {\n\t\t\t\t(cb as EventCallback<EventMap[K]>)(payload);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onStateChange(oldState: EditorState, newState: EditorState, tr: Transaction): void {\n\t\t// Notify plugins (with transaction)\n\t\tthis.pluginManager?.notifyStateChange(oldState, newState, tr);\n\n\t\t// Update empty state\n\t\tthis.updateEmptyState();\n\n\t\t// Emit events\n\t\tthis.emit('stateChange', { oldState, newState, transaction: tr });\n\n\t\tif (\n\t\t\toldState.selection.anchor.blockId !== newState.selection.anchor.blockId ||\n\t\t\toldState.selection.anchor.offset !== newState.selection.anchor.offset ||\n\t\t\toldState.selection.head.blockId !== newState.selection.head.blockId ||\n\t\t\toldState.selection.head.offset !== newState.selection.head.offset\n\t\t) {\n\t\t\tthis.emit('selectionChange', { selection: newState.selection });\n\t\t}\n\n\t\t// Announce formatting changes for screen readers\n\t\tthis.announceFormatChange(oldState, newState);\n\t}\n\n\tprivate updateEmptyState(): void {\n\t\tif (!this.contentElement) return;\n\t\tthis.contentElement.classList.toggle('notectl-content--empty', this.isEmpty());\n\t}\n\n\tprivate announceFormatChange(oldState: EditorState, newState: EditorState): void {\n\t\tif (!this.announcer) return;\n\n\t\t// Announce changes for all mark types in the schema\n\t\tconst markTypes = newState.schema.markTypes;\n\t\tfor (const mt of markTypes) {\n\t\t\tconst branded = toMarkType(mt);\n\t\t\tconst wasActive = isMarkActive(oldState, branded);\n\t\t\tconst nowActive = isMarkActive(newState, branded);\n\t\t\tif (wasActive !== nowActive) {\n\t\t\t\tthis.announcer.textContent = `${mt} ${nowActive ? 'on' : 'off'}`;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate replaceState(newState: EditorState): void {\n\t\tif (!this.view) return;\n\n\t\tthis.view.replaceState(newState);\n\t\tthis.updateEmptyState();\n\t}\n\n\tprivate blockToHTML(block: BlockNode): string {\n\t\tif (block.type === 'horizontal_rule') {\n\t\t\treturn '<hr>';\n\t\t}\n\n\t\tconst inner = getTextChildren(block)\n\t\t\t.map((child) => this.textNodeToHTML(child))\n\t\t\t.join('');\n\t\tconst content = inner || '<br>';\n\n\t\tconst align: string | undefined = (block.attrs as Record<string, unknown>)?.textAlign as\n\t\t\t| string\n\t\t\t| undefined;\n\t\tconst style: string = align && align !== 'left' ? ` style=\"text-align: ${align}\"` : '';\n\n\t\tif (isNodeOfType(block, 'heading')) {\n\t\t\tconst level = block.attrs.level;\n\t\t\tconst tag: string = `h${Math.max(1, Math.min(6, level))}`;\n\t\t\treturn `<${tag}${style}>${content}</${tag}>`;\n\t\t}\n\n\t\tif (block.type === 'blockquote') {\n\t\t\treturn `<blockquote${style}>${content}</blockquote>`;\n\t\t}\n\n\t\treturn `<p${style}>${content}</p>`;\n\t}\n\n\tprivate textNodeToHTML(node: TextNode): string {\n\t\tif (node.text === '') return '';\n\n\t\tlet html = this.escapeHTML(node.text);\n\n\t\t// Sort marks by MarkSpec.rank from the schema registry (lower = closer to text)\n\t\tconst markOrder = this.getMarkOrder();\n\t\tconst sortedMarks = [...node.marks].sort(\n\t\t\t(a, b) => (markOrder.get(a.type) ?? 99) - (markOrder.get(b.type) ?? 99),\n\t\t);\n\n\t\tfor (const mark of sortedMarks) {\n\t\t\tif (isMarkOfType(mark, 'bold')) {\n\t\t\t\thtml = `<strong>${html}</strong>`;\n\t\t\t} else if (isMarkOfType(mark, 'italic')) {\n\t\t\t\thtml = `<em>${html}</em>`;\n\t\t\t} else if (isMarkOfType(mark, 'underline')) {\n\t\t\t\thtml = `<u>${html}</u>`;\n\t\t\t} else if (isMarkOfType(mark, 'strikethrough')) {\n\t\t\t\thtml = `<s>${html}</s>`;\n\t\t\t} else if (isMarkOfType(mark, 'textColor')) {\n\t\t\t\tconst color = this.escapeHTML(mark.attrs.color);\n\t\t\t\thtml = `<span style=\"color: ${color}\">${html}</span>`;\n\t\t\t} else if (isMarkOfType(mark, 'font')) {\n\t\t\t\tconst family: string = mark.attrs?.family ?? '';\n\t\t\t\tif (family) {\n\t\t\t\t\thtml = `<span style=\"font-family: ${this.escapeHTML(family)}\">${html}</span>`;\n\t\t\t\t}\n\t\t\t} else if (isMarkOfType(mark, 'link')) {\n\t\t\t\tconst href = this.escapeHTML(mark.attrs.href);\n\t\t\t\thtml = `<a href=\"${href}\">${html}</a>`;\n\t\t\t}\n\t\t}\n\n\t\treturn html;\n\t}\n\n\tprivate getMarkOrder(): Map<string, number> {\n\t\tconst registry = this.pluginManager?.schemaRegistry;\n\t\tif (!registry) return new Map();\n\t\tconst types = registry.getMarkTypes();\n\t\tconst order = new Map<string, number>();\n\t\tfor (const t of types) {\n\t\t\tconst spec = registry.getMarkSpec(t);\n\t\t\tif (spec) order.set(t, spec.rank ?? 99);\n\t\t}\n\t\treturn order;\n\t}\n\n\tprivate escapeHTML(text: string): string {\n\t\treturn text\n\t\t\t.replace(/&/g, '&')\n\t\t\t.replace(/</g, '<')\n\t\t\t.replace(/>/g, '>')\n\t\t\t.replace(/\"/g, '"');\n\t}\n\n\tprivate parseHTMLToDocument(html: string): Document {\n\t\tconst template = document.createElement('template');\n\t\ttemplate.innerHTML = DOMPurify.sanitize(html);\n\t\tconst root = template.content;\n\n\t\tconst blocks: BlockNode[] = [];\n\n\t\tfor (const child of Array.from(root.childNodes)) {\n\t\t\tif (child.nodeType === Node.ELEMENT_NODE) {\n\t\t\t\tconst el = child as HTMLElement;\n\t\t\t\tconst tag = el.tagName.toLowerCase();\n\n\t\t\t\t// Headings\n\t\t\t\tconst headingMatch = /^h([1-6])$/.exec(tag);\n\t\t\t\tif (headingMatch) {\n\t\t\t\t\tconst level = Number(headingMatch[1]);\n\t\t\t\t\tconst textNodes = this.parseElementToTextNodes(el);\n\t\t\t\t\tblocks.push(createBlockNode(nodeType('heading'), textNodes, undefined, { level }));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Horizontal Rule\n\t\t\t\tif (tag === 'hr') {\n\t\t\t\t\tblocks.push(createBlockNode(nodeType('horizontal_rule')));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Lists\n\t\t\t\tif (tag === 'ul' || tag === 'ol') {\n\t\t\t\t\tconst listType = tag === 'ol' ? 'ordered' : 'bullet';\n\t\t\t\t\tfor (const li of Array.from(el.querySelectorAll('li'))) {\n\t\t\t\t\t\tconst textNodes = this.parseElementToTextNodes(li as HTMLElement);\n\t\t\t\t\t\tblocks.push(\n\t\t\t\t\t\t\tcreateBlockNode(nodeType('list_item'), textNodes, undefined, {\n\t\t\t\t\t\t\t\tlistType,\n\t\t\t\t\t\t\t\tindent: 0,\n\t\t\t\t\t\t\t\tchecked: false,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Regular blocks (p, div, etc.)\n\t\t\t\tconst textNodes = this.parseElementToTextNodes(el);\n\t\t\t\tblocks.push(createBlockNode(nodeType('paragraph'), textNodes));\n\t\t\t} else if (child.nodeType === Node.TEXT_NODE && child.textContent?.trim()) {\n\t\t\t\tblocks.push(\n\t\t\t\t\tcreateBlockNode(nodeType('paragraph'), [createTextNode(child.textContent.trim())]),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (blocks.length === 0) {\n\t\t\treturn createDocument();\n\t\t}\n\n\t\treturn createDocument(blocks);\n\t}\n\n\tprivate parseElementToTextNodes(el: HTMLElement): TextNode[] {\n\t\tconst result: TextNode[] = [];\n\t\tthis.walkElement(el, [], result);\n\t\treturn result.length > 0 ? result : [createTextNode('')];\n\t}\n\n\tprivate walkElement(node: Node, currentMarks: Mark[], result: TextNode[]): void {\n\t\tif (node.nodeType === Node.TEXT_NODE) {\n\t\t\tconst text = node.textContent ?? '';\n\t\t\tif (text) {\n\t\t\t\tresult.push(createTextNode(text, [...currentMarks]));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (node.nodeType !== Node.ELEMENT_NODE) return;\n\n\t\tconst el = node as HTMLElement;\n\t\tconst tag = el.tagName.toLowerCase();\n\n\t\tconst marks = [...currentMarks];\n\t\tif (tag === 'strong' || tag === 'b') {\n\t\t\tif (!marks.some((m) => m.type === 'bold')) marks.push({ type: toMarkType('bold') });\n\t\t}\n\t\tif (tag === 'em' || tag === 'i') {\n\t\t\tif (!marks.some((m) => m.type === 'italic')) marks.push({ type: toMarkType('italic') });\n\t\t}\n\t\tif (tag === 'u') {\n\t\t\tif (!marks.some((m) => m.type === 'underline')) marks.push({ type: toMarkType('underline') });\n\t\t}\n\t\tif (tag === 's') {\n\t\t\tif (!marks.some((m) => m.type === 'strikethrough'))\n\t\t\t\tmarks.push({ type: toMarkType('strikethrough') });\n\t\t}\n\t\tif (tag === 'span') {\n\t\t\tconst color = el.style.color;\n\t\t\tif (color && !marks.some((m) => m.type === 'textColor')) {\n\t\t\t\tmarks.push({ type: toMarkType('textColor'), attrs: { color } });\n\t\t\t}\n\t\t\tconst fontFamily = el.style.fontFamily;\n\t\t\tif (fontFamily && !marks.some((m) => m.type === 'font')) {\n\t\t\t\tmarks.push({ type: toMarkType('font'), attrs: { family: fontFamily } });\n\t\t\t}\n\t\t}\n\t\tif (tag === 'a') {\n\t\t\tconst href = (el as HTMLAnchorElement).getAttribute('href') ?? '';\n\t\t\tif (!marks.some((m) => m.type === 'link'))\n\t\t\t\tmarks.push({ type: toMarkType('link'), attrs: { href } });\n\t\t}\n\n\t\tfor (const child of Array.from(el.childNodes)) {\n\t\t\tthis.walkElement(child, marks, result);\n\t\t}\n\t}\n}\n\n// Register custom element\nif (!customElements.get('notectl-editor')) {\n\tcustomElements.define('notectl-editor', NotectlEditor);\n}\n\n/** Factory function to create and configure a NotectlEditor instance. */\nexport async function createEditor(config?: NotectlEditorConfig): Promise<NotectlEditor> {\n\tconst editor = document.createElement('notectl-editor') as NotectlEditor;\n\tawait editor.init(config);\n\treturn editor;\n}\n"],"names":["getBlockSegmentsInRange","block","from","to","inlineChildren","getInlineChildren","segments","pos","child","childWidth","isInlineNode","childEnd","sliceFrom","sliceTo","text","isTextNode","node","isBlockNode","isLeafBlock","c","getTextChildren","getBlockChildren","generateBlockId","createDocument","children","createBlockNode","type","id","attrs","createTextNode","marks","createInlineNode","inlineType","getBlockText","getBlockLength","len","getBlockMarksAtOffset","offset","end","i","marksEqual","a","b","aAttrs","bAttrs","aKeys","bKeys","key","markSetsEqual","markA","markB","hasMark","markType","m","addMarkToSet","mark","removeMarkFromSet","normalizeTextNodes","nodes","result","prev","normalizeInlineContent","cleaned","next","walkInlineContent","width","getContentAtOffset","localOffset","createPosition","blockId","path","createSelection","anchor","head","createCollapsedSelection","isCollapsed","sel","isForward","blockOrder","anchorIdx","headIdx","selectionRange","defaultSchema","schemaFromRegistry","registry","isMarkAllowed","schema","nodeType","name","pluginId","commandName","isNodeOfType","isMarkOfType","isInlineNodeOfType","inlineNodeType","createBlockElement","tag","el","SchemaRegistry","__publicField","spec","factory","keymap","existing","idx","rule","item","ids","items","resolveNodeByPath","doc","current","childId","resolveParentByPath","index","parentPath","parent","findNodePath","nodeId","subPath","findNodePathInBlock","walkNodes","callback","walkNodeRecursive","findNode","found","findNodeInBlock","findNodeWithPath","canContain","parentType","childType","parentSpec","childSpec","childGroup","allowed","validateContent","childTypes","min","max","blockChildTypes","t","registerBuiltinSpecs","applyStep","step","applyInsertText","applyDeleteText","applySplitBlock","applyMergeBlocks","applyAddMark","applyRemoveMark","applySetBlockType","applyInsertNode","applyRemoveNode","applySetNodeAttr","applyInsertInlineNode","applyRemoveInlineNode","applySetInlineNodeAttr","mapBlock","newChildren","insertSegmentsIntoInlineContent","insertTextIntoInlineContent","replaceInlineChildren","deleteFromInlineContent","blockIndex","nodesBeforeSplit","sliceInlineContent","nodesAfterSplit","updatedBlock","newBlock","splitBlockRecursive","changed","mapped","targetIndex","sourceIndex","target","source","targetInline","sourceInline","mergedChildren","mergedBlock","mergeBlocksRecursive","targetIdx","sourceIdx","applyMarkToInlineContent","insertInlineNodeAtOffset","removeInlineNodeAtOffset","setInlineNodeAttrsAtOffset","fn","mapBlockInChildren","mappedChildren","original","newInlineChildren","blockChildren","inserted","nodeEnd","before","after","seg","deleteFrom","deleteTo","remaining","add","newMarks","overlapStart","overlapEnd","beforeText","insideText","afterText","inlineNode","mapNodeByPath","rootId","mapNodeByPathRecursive","depth","targetId","invertStep","invertTransaction","tr","TransactionBuilder","currentSelection","currentStoredMarks","origin","deletedText","deletedMarks","deletedSegments","newBlockId","targetBlockId","sourceBlockId","targetLengthBefore","targetBlock","removedNode","resolveRemovedNode","content","selection","previousMarks","EditorState","storedMarks","options","firstBlock","validateSelection","buildBlockMap","buildBlockOrder","parentId","json","validatePosition","length","map","walk","blocks","order","DEFAULT_GROUP_TIMEOUT_MS","DEFAULT_MAX_DEPTH","HistoryManager","now","lastGroup","state","group","currentState","allSteps","inverted","transaction","incoming","lastTr","lastStepType","_a","incomingStepType","_b","defaultFeatures","toggleMark","features","isFeatureGated","anchorBlock","currentMarks","range","builder","fromIdx","toIdx","shouldRemove","isMarkActiveInRange","blockLen","isMarkActiveInBlock","toggleBold","toggleItalic","toggleUnderline","insertTextCommand","resolveActiveMarks","addDeleteSelectionSteps","insertBlockId","insertOffset","deleteSelectionCommand","deleteBackward","mergeBlockBackward","deleteForward","mergeBlockForward","deleteWordBackward","wordStart","findWordBoundaryBackward","deleteWordForward","wordEnd","findWordBoundaryForward","deleteSoftLineBackward","deleteSoftLineForward","splitBlockCommand","sharesParent","blockIdA","blockIdB","pathA","pathB","isInsideIsolating","getNodeSpec","ancestorId","ancestor","blockIdx","prevBlockId","prevBlock","prevLen","nextBlockId","selectAll","lastBlock","lastBlockLen","isMarkActive","firstLen","midBlockId","midBlock","midLen","KeyboardHandler","element","e","descriptor","normalizeKeyDescriptor","keymaps","handler","parts","EventKey","ServiceKey","EventBus","payload","set","listener","err","mapDecorationThroughStep","deco","mapInline","mapWidget","mapNode","mapInlineInsert","mapInlineDelete","mapInlineSplit","mapInlineMerge","removeIfBlockDeleted","mapWidgetInsert","mapWidgetDelete","mapWidgetSplit","mapWidgetMerge","mapNodeMerge","newFrom","newTo","delLen","clampAndShift","left","right","delFrom","delTo","inline","widget","toDOM","_DecorationSet","byBlock","decorations","decos","d","bid","predicate","filtered","other","otherDecos","decorationArraysEqual","r","DecorationSet","ai","bi","decorationsEqual","attrsEqual","bn","bw","DEFAULT_PRIORITY","PluginManager","plugin","context","oldState","newState","finalDispatch","sorted","dispatched","currentTr","entry","called","guardedNext","config","reversed","reg","serviceId","unsub","itemId","pluginEventBus","middleware","priority","service","dep","inDegree","dependents","deps","depList","queue","deg","pa","pb","newDeg","missing","ToolbarServiceKey","ToolbarPlugin","layoutConfig","_oldState","_tr","value","button","root","rect","container","btn","sep","firstGroup","groupPluginIds","groupItems","pId","groups","list","span","popup","grid","label","cell","cells","otherR","otherC","iconSpan","labelSpan","active","enabled","_d","_c","formatShortcut","binding","DEFAULT_CONFIG","BOLD_ICON","ITALIC_ICON","UNDERLINE_ICON","MARK_DEFINITIONS","TextFormattingPlugin","enabledMarks","def","lastVisibleMark","isSeparatorTarget","separatorAfter","toCommandName","toolbarVisible","featureEnabled","configKey","HEADING_TAGS","HEADING_LABELS","TITLE_LABEL","SUBTITLE_LABEL","PARAGRAPH_LABEL","HeadingPlugin","level","hashes","pattern","_match","start","_end","icon","ctx","currentType","activeLevel","addItem","command","style","isActive","check","LinkPlugin","openInNewTab","href","sum","textChildren","cursorIdx","cursorEntry","startIdx","endIdx","startEntry","endEntry","linkStart","linkEnd","removeBtn","input","applyBtn","BULLET_LIST_ICON","NUMBERED_LIST_ICON","CHECKLIST_ICON","LIST_TYPE_DEFINITIONS","ListPlugin","listType","indent","checked","li","enabledTypes","match","matchStr","matchLen","lastType","BlockquotePlugin","StrikethroughPlugin","HEX_COLOR_PATTERN","isValidHexColor","resolveColors","colors","COLOR_PALETTE","invalid","seen","unique","color","normalized","TextColorPlugin","activeColor","defaultBtn","swatch","HorizontalRulePlugin","_start","newParagraph","hrBlock","ALIGNMENT_LABELS","ALIGNMENT_ICONS","TextAlignmentPlugin","originalToDOM","applyAlignment","alignment","capitalize","bindings","dropdownItems","_state","patched","patchedSteps","prevAlign","newAttrs","align","s","FontPlugin","family","f","first","activeFamily","displayName","fontMark","rules","font","face","declarations","activeFont","defaultFamily","isDefault","DEFAULT_FONT_SIZES","DEFAULT_FONT_SIZE","MIN_CUSTOM_SIZE","MAX_CUSTOM_SIZE","FontSizePlugin","resolveSizes","resolveDefaultSize","size","activeSize","raw","parsed","direction","currentSize","focusedIndex","inputWrapper","activeIdx","activeItem","setFocusedIndex","focused","val","selectedSize","sizes","n","FIRA_CODE_WOFF2_DATA","FIRA_SANS_WOFF2_DATA","FIRA_CODE","FIRA_SANS","STARTER_FONTS","createTable","rows","cols","tableId","rowNodes","cellNodes","createTableRow","createTableCell","findTableContext","tableNode","tableIndex","cellId","rowId","rowIndex","rowNode","colIndex","totalCols","totalRows","getCellAt","table","row","isInsideTable","insertTable","currentBlockId","rootIndex","rootBlock","paragraphAfter","insertIndex","firstRow","firstCell","addRowAbove","tableCtx","newRow","addRowBelow","addColumnLeft","addColumn","addColumnRight","side","insertColIndex","newCell","deleteRow","deleteTable","targetRowIndex","targetCellId","deleteColumn","targetColIndex","blockAfterIndex","blockBeforeIndex","afterBlock","beforeBlock","registerTableCommands","registerTableKeymaps","handleTab","handleShiftTab","handleEnter","handleBackspace","handleDelete","handleArrowDown","handleArrowUp","handleArrowRight","handleArrowLeft","handleEscape","moveToCellAndSelect","moveToCellAtEnd","nextIndex","nextBlock","cellLen","reconcile","oldBlocks","newBlocks","nodeViews","oldBlockMap","newBlockIds","nv","oldBlockById","previousSibling","existingEl","oldBlock","oldDecos","newDecos","blockChanged","existingNv","_e","newEl","renderBlock","oldAttrs","oldKeys","newKeys","oldChild","newChild","inlineAttrsEqual","oldArr","newArr","inlineDecos","contentDOM","childEl","applyNodeDecorations","renderBlockContent","renderParagraphFallback","renderTextNode","renderInlineNode","renderDecoratedContent","p","preserveSpaces","textNode","sortedMarks","markOrder","createMarkElement","globalOffset","textFrom","textTo","splitSet","dFrom","dTo","splits","localFrom","localTo","activeDecos","j","createDecorationElement","tagName","cls","nodeDecos","PLUS_SVG","DELETE_SVG","BORDER_THRESHOLD","insertRowAtIndex","getState","dispatch","numCols","insertColumnAtIndex","deleteRowAtIndex","deleteEntireTable","targetRow","deleteColumnAtIndex","targetCol","createButton","className","innerHTML","title","buildInsertLine","orientation","line","buildAddButton","buildHandleBar","bar","buildHandle","onDelete","handle","deleteBtn","createTableControls","tableEl","initialNode","numRows","countRows","countCols","colBar","rowBar","insertLineH","insertLineV","addRowZone","addColZone","activeRowIndex","activeColIndex","rebuildColHandles","rebuildRowHandles","insertBtnH","insertBtnV","onMouseMove","onMouseLeave","observer","positionControls","getTableOffset","top","measureRowBorders","trs","tableTop","borders","measureColBorders","colWidth","positionColHandles","positionRowHandles","positionAddButtons","handles","tableWidth","h","totalHeight","height","tableHeight","tableRect","x","y","hideInsertLines","rowBorders","nearestRowDist","nearestRowBorder","border","dist","colBorders","nearestColDist","nearestColBorder","showHorizontalLine","hideVerticalLine","showVerticalLine","hideHorizontalLine","newRows","newCols","createTableNodeViewFactory","_registry","wrapper","tbody","liveRegion","controls","updatedNode","updatedRows","newTotalRows","newTotalCols","createTableRowNodeViewFactory","_getState","_dispatch","createTableCellNodeViewFactory","td","colspan","rowspan","newColspan","newRowspan","TableSelectionServiceKey","createTableSelectionService","selectedRange","cachedCellIds","cachedCellIdSet","updateCache","minRow","maxRow","minCol","maxCol","updateCellHighlights","selectedIds","installMouseSelection","anchorCell","isDragging","handleMouseDown","cellEl","handleMouseMove","handleMouseUp","TABLE_ICON","TablePlugin","maxRows","maxCols","HIGHLIGHT_PALETTE","HighlightPlugin","SUPERSCRIPT_ICON","SUBSCRIPT_ICON","SuperSubPlugin","markName","removeStep","storedMarksAfter","hasSup","hasSub","lastSupIdx","lastSubIdx","removeType","InputHandler","composedText","textBefore","PasteHandler","clipboardData","html","sanitized","DOMPurify","template","getSelection","syncSelectionToDOM","domSel","anchorPos","statePositionToDOM","headPos","readSelectionFromDOM","anchorNode","focusNode","domPositionToState","blockEl","walker","createInlineContentWalker","childIndex","childIndexOf","lastChild","domOffset","findBlockElement","rawBlockId","buildBlockPath","childOffset","childIdx","inlineContentWidth","walkerNode","leafBlockEl","isInsideInlineElement","EditorView","contentElement","oldDecorations","newDecorations","cb","currentSel","shadowRoot","activeEl","EDITOR_CSS","cachedStyleSheet","getEditorStyleSheet","NotectlEditor","resolve","_oldValue","newValue","shadow","contentEl","pluginMgr","topContainer","bottomContainer","position","currentListTag","inner","finalTr","event","pluginTeardown","pluginIds","listeners","markTypes","mt","branded","wasActive","nowActive","types","headingMatch","textNodes","fontFamily","createEditor","editor"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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"}
|