@notectl/core 2.2.2 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +12 -0
  2. package/dist/chunks/AlignmentPlugin-BCHxo16v.mjs +2 -0
  3. package/dist/chunks/AlignmentPlugin-BCHxo16v.mjs.map +1 -0
  4. package/dist/chunks/{BidiIsolationPlugin-Bm3h9J15.mjs → BidiIsolationPlugin-BddRbDCN.mjs} +2 -2
  5. package/dist/chunks/{BidiIsolationPlugin-Bm3h9J15.mjs.map → BidiIsolationPlugin-BddRbDCN.mjs.map} +1 -1
  6. package/dist/chunks/{BlockquotePlugin-CxrCA0vY.mjs → BlockquotePlugin-4V7KV_Sb.mjs} +2 -2
  7. package/dist/chunks/{BlockquotePlugin-CxrCA0vY.mjs.map → BlockquotePlugin-4V7KV_Sb.mjs.map} +1 -1
  8. package/dist/chunks/{CaretNavigationPlugin-Bb7W_FMg.mjs → CaretNavigationPlugin-C6XBwp0N.mjs} +2 -2
  9. package/dist/chunks/{CaretNavigationPlugin-Bb7W_FMg.mjs.map → CaretNavigationPlugin-C6XBwp0N.mjs.map} +1 -1
  10. package/dist/chunks/{CodeBlockPlugin-Uv6EXaH1.mjs → CodeBlockPlugin-DC0-BnNy.mjs} +2 -2
  11. package/dist/chunks/{CodeBlockPlugin-Uv6EXaH1.mjs.map → CodeBlockPlugin-DC0-BnNy.mjs.map} +1 -1
  12. package/dist/chunks/{Commands-CyT1Li7_.mjs → Commands-BIIpx_Zd.mjs} +2 -2
  13. package/dist/chunks/Commands-BIIpx_Zd.mjs.map +1 -0
  14. package/dist/chunks/FontPlugin-DB1_bgam.mjs +2 -0
  15. package/dist/chunks/{FontPlugin-1VYDwETg.mjs.map → FontPlugin-DB1_bgam.mjs.map} +1 -1
  16. package/dist/chunks/{FontSizePlugin-L1uDVsKY.mjs → FontSizePlugin-DFvp7Ki9.mjs} +2 -2
  17. package/dist/chunks/{FontSizePlugin-L1uDVsKY.mjs.map → FontSizePlugin-DFvp7Ki9.mjs.map} +1 -1
  18. package/dist/chunks/{FormulaPlugin-UA-9tRpY.mjs → FormulaPlugin-BLEcyazj.mjs} +2 -2
  19. package/dist/chunks/{FormulaPlugin-UA-9tRpY.mjs.map → FormulaPlugin-BLEcyazj.mjs.map} +1 -1
  20. package/dist/chunks/GapCursorPlugin-Zvxjnr82.mjs +2 -0
  21. package/dist/chunks/{GapCursorPlugin-B29ieXel.mjs.map → GapCursorPlugin-Zvxjnr82.mjs.map} +1 -1
  22. package/dist/chunks/{HardBreakPlugin-BkgoJkjC.mjs → HardBreakPlugin-9DOyCyyM.mjs} +2 -2
  23. package/dist/chunks/{HardBreakPlugin-BkgoJkjC.mjs.map → HardBreakPlugin-9DOyCyyM.mjs.map} +1 -1
  24. package/dist/chunks/{HeadingPlugin-SICF6Tm0.mjs → HeadingPlugin-D9yvG2Aw.mjs} +2 -2
  25. package/dist/chunks/{HeadingPlugin-SICF6Tm0.mjs.map → HeadingPlugin-D9yvG2Aw.mjs.map} +1 -1
  26. package/dist/chunks/{HighlightPlugin-B3b_qe68.mjs → HighlightPlugin-D4gh4RP7.mjs} +2 -2
  27. package/dist/chunks/{HighlightPlugin-B3b_qe68.mjs.map → HighlightPlugin-D4gh4RP7.mjs.map} +1 -1
  28. package/dist/chunks/HorizontalRulePlugin-0FjHPZuA.mjs +2 -0
  29. package/dist/chunks/{HorizontalRulePlugin-BrFlrpmb.mjs.map → HorizontalRulePlugin-0FjHPZuA.mjs.map} +1 -1
  30. package/dist/chunks/{ImagePlugin-eRVtFFou.mjs → ImagePlugin-Cp_RINtc.mjs} +2 -2
  31. package/dist/chunks/{ImagePlugin-eRVtFFou.mjs.map → ImagePlugin-Cp_RINtc.mjs.map} +1 -1
  32. package/dist/chunks/{InlineCodePlugin-D3QulApr.mjs → InlineCodePlugin-DMr4O7c7.mjs} +2 -2
  33. package/dist/chunks/{InlineCodePlugin-D3QulApr.mjs.map → InlineCodePlugin-DMr4O7c7.mjs.map} +1 -1
  34. package/dist/chunks/LinkPlugin-DvZ3MPgL.mjs +2 -0
  35. package/dist/chunks/{LinkPlugin-B_ysjORS.mjs.map → LinkPlugin-DvZ3MPgL.mjs.map} +1 -1
  36. package/dist/chunks/{ListPlugin-C0BV8CnQ.mjs → ListPlugin-CVId2dE0.mjs} +2 -2
  37. package/dist/chunks/{ListPlugin-C0BV8CnQ.mjs.map → ListPlugin-CVId2dE0.mjs.map} +1 -1
  38. package/dist/chunks/PluginHelpers-KDuTlmXm.mjs +2 -0
  39. package/dist/chunks/{PluginHelpers-D4quRJ5a.mjs.map → PluginHelpers-KDuTlmXm.mjs.map} +1 -1
  40. package/dist/chunks/{PrintPlugin-CXDFFzWB.mjs → PrintPlugin-C6gOJT6d.mjs} +2 -2
  41. package/dist/chunks/{PrintPlugin-CXDFFzWB.mjs.map → PrintPlugin-C6gOJT6d.mjs.map} +1 -1
  42. package/dist/chunks/{SimpleMark-Db8ir_z2.mjs → SimpleMark-CaQtFAau.mjs} +2 -2
  43. package/dist/chunks/{SimpleMark-Db8ir_z2.mjs.map → SimpleMark-CaQtFAau.mjs.map} +1 -1
  44. package/dist/chunks/{SmartPastePlugin-Db1RcNJf.mjs → SmartPastePlugin-Bi_wpTCV.mjs} +2 -2
  45. package/dist/chunks/{SmartPastePlugin-Db1RcNJf.mjs.map → SmartPastePlugin-Bi_wpTCV.mjs.map} +1 -1
  46. package/dist/chunks/StrikethroughPlugin-BLKDRWtf.mjs +2 -0
  47. package/dist/chunks/{StrikethroughPlugin-Bsg7Ma4I.mjs.map → StrikethroughPlugin-BLKDRWtf.mjs.map} +1 -1
  48. package/dist/chunks/{SuperSubPlugin-ChEga-b_.mjs → SuperSubPlugin-DVP7VnIz.mjs} +2 -2
  49. package/dist/chunks/{SuperSubPlugin-ChEga-b_.mjs.map → SuperSubPlugin-DVP7VnIz.mjs.map} +1 -1
  50. package/dist/chunks/{TablePlugin-CRp4qSZE.mjs → TablePlugin-D93RR5xH.mjs} +2 -2
  51. package/dist/chunks/{TablePlugin-CRp4qSZE.mjs.map → TablePlugin-D93RR5xH.mjs.map} +1 -1
  52. package/dist/chunks/TextColorPlugin-C1qpzEOa.mjs +2 -0
  53. package/dist/chunks/{TextColorPlugin-CViEiYZk.mjs.map → TextColorPlugin-C1qpzEOa.mjs.map} +1 -1
  54. package/dist/chunks/TextDirectionPlugin-DHB88HKf.mjs +2 -0
  55. package/dist/chunks/TextDirectionPlugin-DHB88HKf.mjs.map +1 -0
  56. package/dist/chunks/{TextFormattingPlugin-Db5SCNOF.mjs → TextFormattingPlugin-Cubp3e7f.mjs} +2 -2
  57. package/dist/chunks/{TextFormattingPlugin-Db5SCNOF.mjs.map → TextFormattingPlugin-Cubp3e7f.mjs.map} +1 -1
  58. package/dist/chunks/{ToolbarPlugin-B5UUc6dY.mjs → ToolbarPlugin-CLz2wa2c.mjs} +2 -2
  59. package/dist/chunks/{ToolbarPlugin-B5UUc6dY.mjs.map → ToolbarPlugin-CLz2wa2c.mjs.map} +1 -1
  60. package/dist/chunks/{VideoPlugin-mXIDODzC.mjs → VideoPlugin-D9rQZol6.mjs} +2 -2
  61. package/dist/chunks/{VideoPlugin-mXIDODzC.mjs.map → VideoPlugin-D9rQZol6.mjs.map} +1 -1
  62. package/dist/chunks/full-Cah3qjCT.mjs +2 -0
  63. package/dist/chunks/{full--GEBZ2xU.mjs.map → full-Cah3qjCT.mjs.map} +1 -1
  64. package/dist/chunks/minimal-DqATlnAL.mjs +2 -0
  65. package/dist/chunks/{minimal-D5v-raei.mjs.map → minimal-DqATlnAL.mjs.map} +1 -1
  66. package/dist/chunks/{src-C5Lblp2i.mjs → src-YY6n2SmV.mjs} +2 -2
  67. package/dist/chunks/{src-C5Lblp2i.mjs.map → src-YY6n2SmV.mjs.map} +1 -1
  68. package/dist/commands/Commands.d.ts.map +1 -1
  69. package/dist/full.mjs +1 -1
  70. package/dist/notectl-core.mjs +1 -1
  71. package/dist/notectl-core.umd.js +1 -1
  72. package/dist/notectl-core.umd.js.map +1 -1
  73. package/dist/plugins/alignment/AlignmentPlugin.d.ts +5 -0
  74. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  75. package/dist/plugins/alignment.mjs +1 -1
  76. package/dist/plugins/bidi-isolation.mjs +1 -1
  77. package/dist/plugins/blockquote.mjs +1 -1
  78. package/dist/plugins/caret-navigation.mjs +1 -1
  79. package/dist/plugins/code-block.mjs +1 -1
  80. package/dist/plugins/font-size.mjs +1 -1
  81. package/dist/plugins/font.mjs +1 -1
  82. package/dist/plugins/formula.mjs +1 -1
  83. package/dist/plugins/gap-cursor.mjs +1 -1
  84. package/dist/plugins/hard-break.mjs +1 -1
  85. package/dist/plugins/heading.mjs +1 -1
  86. package/dist/plugins/highlight.mjs +1 -1
  87. package/dist/plugins/horizontal-rule.mjs +1 -1
  88. package/dist/plugins/image.mjs +1 -1
  89. package/dist/plugins/inline-code.mjs +1 -1
  90. package/dist/plugins/link.mjs +1 -1
  91. package/dist/plugins/list.mjs +1 -1
  92. package/dist/plugins/print.mjs +1 -1
  93. package/dist/plugins/shared/PluginHelpers.d.ts +8 -0
  94. package/dist/plugins/shared/PluginHelpers.d.ts.map +1 -1
  95. package/dist/plugins/shared.mjs +1 -1
  96. package/dist/plugins/smart-paste.mjs +1 -1
  97. package/dist/plugins/strikethrough.mjs +1 -1
  98. package/dist/plugins/super-sub.mjs +1 -1
  99. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  100. package/dist/plugins/table.mjs +1 -1
  101. package/dist/plugins/text-color.mjs +1 -1
  102. package/dist/plugins/text-direction/TextDirectionPlugin.d.ts +0 -1
  103. package/dist/plugins/text-direction/TextDirectionPlugin.d.ts.map +1 -1
  104. package/dist/plugins/text-direction.mjs +1 -1
  105. package/dist/plugins/text-formatting.mjs +1 -1
  106. package/dist/plugins/toolbar.mjs +1 -1
  107. package/dist/plugins/video.mjs +1 -1
  108. package/dist/presets/full.mjs +1 -1
  109. package/dist/presets/minimal.mjs +1 -1
  110. package/dist/presets.mjs +1 -1
  111. package/package.json +415 -423
  112. package/dist/chunks/AlignmentPlugin-h6sx-yIf.mjs +0 -2
  113. package/dist/chunks/AlignmentPlugin-h6sx-yIf.mjs.map +0 -1
  114. package/dist/chunks/Commands-CyT1Li7_.mjs.map +0 -1
  115. package/dist/chunks/FontPlugin-1VYDwETg.mjs +0 -2
  116. package/dist/chunks/GapCursorPlugin-B29ieXel.mjs +0 -2
  117. package/dist/chunks/HorizontalRulePlugin-BrFlrpmb.mjs +0 -2
  118. package/dist/chunks/LinkPlugin-B_ysjORS.mjs +0 -2
  119. package/dist/chunks/PluginHelpers-D4quRJ5a.mjs +0 -2
  120. package/dist/chunks/StrikethroughPlugin-Bsg7Ma4I.mjs +0 -2
  121. package/dist/chunks/TextColorPlugin-CViEiYZk.mjs +0 -2
  122. package/dist/chunks/TextDirectionPlugin-CQGkaS2s.mjs +0 -2
  123. package/dist/chunks/TextDirectionPlugin-CQGkaS2s.mjs.map +0 -1
  124. package/dist/chunks/full--GEBZ2xU.mjs +0 -2
  125. package/dist/chunks/minimal-D5v-raei.mjs +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"SmartPastePlugin-Db1RcNJf.mjs","names":[],"sources":["../../src/plugins/smart-paste/ContentSplitter.ts","../../src/plugins/smart-paste/SmartPasteLocale.ts","../../src/plugins/smart-paste/SmartPasteTypes.ts","../../src/plugins/smart-paste/SmartPastePlugin.ts"],"sourcesContent":["/**\n * Splits pasted text at blank-line boundaries and classifies each segment\n * using content detectors. Adjacent segments of the same type are merged.\n */\n\nimport type { ContentDetector, DetectionResult, PasteSegment } from './SmartPasteTypes.js';\n\n/** Pattern matching one or more consecutive blank lines (may contain whitespace). */\nconst BLANK_LINE_SPLIT: RegExp = /\\n(?:[ \\t]*\\n)+/;\n\n/**\n * Splits text at blank-line boundaries and classifies each segment\n * using the provided detectors. Returns null if no code is detected\n * in any segment (the paste should fall through to default handling).\n */\nexport function splitAndClassify(\n\ttext: string,\n\tdetectors: readonly ContentDetector[],\n): readonly PasteSegment[] | null {\n\tconst rawSegments: readonly string[] = text.split(BLANK_LINE_SPLIT);\n\tconst trimmed: readonly string[] = rawSegments\n\t\t.map((s: string) => s.trim())\n\t\t.filter((s: string) => s.length > 0);\n\n\tif (trimmed.length === 0) return null;\n\n\tlet hasCode = false;\n\tconst segments: PasteSegment[] = trimmed.map((segmentText: string): PasteSegment => {\n\t\tconst detection: DetectionResult | null = detectBest(segmentText, detectors);\n\t\tif (detection) hasCode = true;\n\t\treturn { text: segmentText, detection };\n\t});\n\n\tif (!hasCode) return null;\n\n\treturn mergeAdjacentSegments(segments);\n}\n\n/**\n * Merges adjacent segments that share the same classification:\n * consecutive text segments become one paragraph, consecutive code\n * segments of the same language become one code block.\n */\nexport function mergeAdjacentSegments(segments: readonly PasteSegment[]): readonly PasteSegment[] {\n\tif (segments.length <= 1) return segments;\n\n\tconst merged: PasteSegment[] = [segments[0] as PasteSegment];\n\n\tfor (let i = 1; i < segments.length; i++) {\n\t\tconst current: PasteSegment = segments[i] as PasteSegment;\n\t\tconst previous: PasteSegment = merged[merged.length - 1] as PasteSegment;\n\n\t\tif (canMerge(previous, current)) {\n\t\t\tmerged[merged.length - 1] = merge(previous, current);\n\t\t} else {\n\t\t\tmerged.push(current);\n\t\t}\n\t}\n\n\treturn merged;\n}\n\n/**\n * Picks the highest-confidence detection result from all detectors.\n * Ties are broken deterministically by lexicographic language id so the\n * outcome does not depend on detector registration order.\n */\nfunction detectBest(text: string, detectors: readonly ContentDetector[]): DetectionResult | null {\n\tlet best: DetectionResult | null = null;\n\n\tfor (const detector of detectors) {\n\t\tconst result: DetectionResult | null = detector.detect(text);\n\t\tif (!result) continue;\n\t\tif (\n\t\t\tbest === null ||\n\t\t\tresult.confidence > best.confidence ||\n\t\t\t(result.confidence === best.confidence && result.language < best.language)\n\t\t) {\n\t\t\tbest = result;\n\t\t}\n\t}\n\n\treturn best;\n}\n\n/** Two segments can merge if both are text or both are code of the same language. */\nfunction canMerge(a: PasteSegment, b: PasteSegment): boolean {\n\tif (!a.detection && !b.detection) return true;\n\tif (a.detection && b.detection) return a.detection.language === b.detection.language;\n\treturn false;\n}\n\n/** Merges two compatible segments into one. */\nfunction merge(a: PasteSegment, b: PasteSegment): PasteSegment {\n\tconst joinedText: string = `${a.text}\\n\\n${b.text}`;\n\n\tif (!a.detection && !b.detection) {\n\t\treturn { text: joinedText, detection: null };\n\t}\n\n\tconst detA: DetectionResult = a.detection as DetectionResult;\n\tconst detB: DetectionResult = b.detection as DetectionResult;\n\n\treturn {\n\t\ttext: joinedText,\n\t\tdetection: {\n\t\t\tlanguage: detA.language,\n\t\t\tformattedText: `${detA.formattedText}\\n\\n${detB.formattedText}`,\n\t\t\tconfidence: Math.max(detA.confidence, detB.confidence),\n\t\t},\n\t};\n}\n","/** Locale interface and default English locale for the SmartPastePlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\nexport interface SmartPasteLocale {\n\treadonly detectedAsCodeBlock: (language: string) => string;\n\treadonly detectedMixedContent: (\n\t\ttextCount: number,\n\t\tcodeCount: number,\n\t\tlanguages: readonly string[],\n\t) => string;\n}\n\nexport const SMART_PASTE_LOCALE_EN: SmartPasteLocale = {\n\tdetectedAsCodeBlock: (language: string) =>\n\t\t`Pasted as ${language} code block with syntax highlighting.`,\n\tdetectedMixedContent: (textCount: number, codeCount: number, languages: readonly string[]) => {\n\t\tconst parts: string[] = [];\n\t\tif (textCount > 0) {\n\t\t\tparts.push(`${textCount} paragraph${textCount > 1 ? 's' : ''}`);\n\t\t}\n\t\tif (codeCount > 0) {\n\t\t\tconst langList: string = languages.join(', ');\n\t\t\tparts.push(`${codeCount} code block${codeCount > 1 ? 's' : ''} (${langList})`);\n\t\t}\n\t\treturn `Pasted as ${parts.join(' and ')}.`;\n\t},\n};\n\nconst localeModules: LocaleModuleMap<SmartPasteLocale> = import.meta.glob<{\n\tdefault: SmartPasteLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadSmartPasteLocale(lang: string): Promise<SmartPasteLocale> {\n\treturn loadLocaleModule(localeModules, lang, SMART_PASTE_LOCALE_EN);\n}\n","/**\n * Types for the smart paste plugin — content detection and formatting.\n */\n\nimport { ServiceKey } from '../Plugin.js';\nimport type { SmartPasteLocale } from './SmartPasteLocale.js';\n\n/** Result of detecting structured content in pasted text. */\nexport interface DetectionResult {\n\treadonly language: string;\n\treadonly formattedText: string;\n\treadonly confidence: number;\n}\n\n/** A classified segment of pasted text — either plain text or detected code. */\nexport interface PasteSegment {\n\treadonly text: string;\n\treadonly detection: DetectionResult | null;\n}\n\n/** Interface for content detectors that identify and format pasted text. */\nexport interface ContentDetector {\n\treadonly id: string;\n\tdetect(text: string): DetectionResult | null;\n}\n\n/** Configuration for the SmartPastePlugin. */\nexport interface SmartPasteConfig {\n\treadonly detectors?: readonly ContentDetector[];\n\treadonly locale?: SmartPasteLocale;\n}\n\n/** Public service for registering additional content detectors at runtime. */\nexport interface SmartPasteService {\n\tregisterDetector(detector: ContentDetector): void;\n}\n\nexport const SMART_PASTE_SERVICE_KEY = new ServiceKey<SmartPasteService>('smartPaste');\n","/**\n * SmartPastePlugin: detects structured content in clipboard text\n * and inserts it as formatted code blocks with syntax highlighting.\n * Mixed content (text + code) is split into separate blocks.\n */\n\nimport {\n\ttype InsertionContext,\n\tfindTableCellAncestor,\n\tinsertBlockAfterAnchor,\n\tresolveAnchorBlockId,\n\tresolveCellInsertionContext,\n\tresolveRootInsertionContext,\n} from '../../commands/BlockInsertion.js';\nimport { addDeleteSelectionSteps } from '../../commands/Commands.js';\nimport {\n\ttype BlockNode,\n\tcreateBlockNode,\n\tcreateTextNode,\n\tgenerateBlockId,\n} from '../../model/Document.js';\nimport {\n\tcreateCollapsedSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisTextSelection,\n} from '../../model/Selection.js';\nimport type { BlockId, NodeTypeName } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { PasteInterceptor, Plugin, PluginContext } from '../Plugin.js';\nimport { LANGUAGE_REGISTRY_SERVICE_KEY } from '../language/LanguageTypes.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { splitAndClassify } from './ContentSplitter.js';\nimport {\n\tSMART_PASTE_LOCALE_EN,\n\ttype SmartPasteLocale,\n\tloadSmartPasteLocale,\n} from './SmartPasteLocale.js';\nimport type {\n\tContentDetector,\n\tDetectionResult,\n\tPasteSegment,\n\tSmartPasteConfig,\n} from './SmartPasteTypes.js';\nimport { SMART_PASTE_SERVICE_KEY } from './SmartPasteTypes.js';\n\nexport class SmartPastePlugin implements Plugin {\n\treadonly id = 'smart-paste';\n\treadonly name = 'Smart Paste';\n\treadonly dependencies = ['code-block'] as const;\n\n\tprivate readonly config: SmartPasteConfig;\n\tprivate readonly detectors: ContentDetector[] = [];\n\tprivate context: PluginContext | null = null;\n\tprivate locale: SmartPasteLocale = SMART_PASTE_LOCALE_EN;\n\n\tconstructor(config?: Partial<SmartPasteConfig>) {\n\t\tthis.config = { ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.context = context;\n\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSMART_PASTE_LOCALE_EN,\n\t\t\tloadSmartPasteLocale,\n\t\t);\n\n\t\t// Subscribe to language registry for detectors (replay provides built-ins)\n\t\tconst registry = context.getService(LANGUAGE_REGISTRY_SERVICE_KEY);\n\t\tif (registry) {\n\t\t\tregistry.onRegister((support) => {\n\t\t\t\tif (support.detection) {\n\t\t\t\t\tthis.detectors.push(support.detection);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Register config-provided detectors\n\t\tif (this.config.detectors) {\n\t\t\tfor (const detector of this.config.detectors) {\n\t\t\t\tthis.detectors.push(detector);\n\t\t\t}\n\t\t}\n\n\t\t// Register paste interceptor\n\t\tcontext.registerPasteInterceptor(this.handlePaste, { name: 'smart-paste', priority: 50 });\n\n\t\t// Register service for external detector registration\n\t\tcontext.registerService(SMART_PASTE_SERVICE_KEY, {\n\t\t\tregisterDetector: (detector: ContentDetector) => {\n\t\t\t\tthis.detectors.push(detector);\n\t\t\t},\n\t\t});\n\t}\n\n\tdestroy(): void {\n\t\tthis.context = null;\n\t\tthis.detectors.length = 0;\n\t}\n\n\t// --- Paste Interceptor ---\n\n\tprivate readonly handlePaste: PasteInterceptor = (\n\t\tplainText: string,\n\t\t_html: string,\n\t\tstate: EditorState,\n\t): Transaction | null => {\n\t\tif (this.isCursorInCodeBlock(state)) return null;\n\n\t\tconst segments: readonly PasteSegment[] | null = splitAndClassify(plainText, this.detectors);\n\t\tif (!segments) return null;\n\n\t\t// Single code-only segment: use existing fast path\n\t\tif (segments.length === 1 && segments[0]?.detection) {\n\t\t\treturn this.handleSingleCodeBlock(state, segments[0].detection);\n\t\t}\n\n\t\t// Mixed content: create multiple blocks\n\t\treturn this.handleMixedContent(state, segments);\n\t};\n\n\tprivate isCursorInCodeBlock(state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (!isTextSelection(sel)) return false;\n\n\t\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\t\treturn block?.type === 'code_block';\n\t}\n\n\t// --- Single Code Block (existing behavior) ---\n\n\tprivate handleSingleCodeBlock(\n\t\tstate: EditorState,\n\t\tdetection: DetectionResult,\n\t): Transaction | null {\n\t\tconst tr: Transaction | null = this.buildCodeBlockTransaction(state, detection);\n\t\tif (tr && this.context) {\n\t\t\tthis.context.announce(this.locale.detectedAsCodeBlock(detection.language));\n\t\t}\n\t\treturn tr;\n\t}\n\n\tprivate buildCodeBlockTransaction(\n\t\tstate: EditorState,\n\t\tdetection: DetectionResult,\n\t): Transaction | null {\n\t\tconst sel = state.selection;\n\t\tconst builder = state.transaction('paste');\n\n\t\t// Delete selection if range-selected\n\t\tlet anchorBlockId: BlockId;\n\t\tif (isTextSelection(sel) && !isCollapsed(sel)) {\n\t\t\tconst landingId: BlockId | undefined = addDeleteSelectionSteps(state, builder);\n\t\t\tanchorBlockId = landingId ?? sel.anchor.blockId;\n\t\t} else {\n\t\t\tanchorBlockId = resolveAnchorBlockId(sel);\n\t\t}\n\n\t\t// Create the code block node\n\t\tconst newBlockId: BlockId = generateBlockId();\n\t\tconst codeBlock: BlockNode = createBlockNode(\n\t\t\tnodeType('code_block') as NodeTypeName,\n\t\t\t[createTextNode(detection.formattedText)],\n\t\t\tnewBlockId,\n\t\t\t{ language: detection.language, backgroundColor: '' },\n\t\t);\n\n\t\t// Insert at cursor (handles cell vs root, empty anchor removal)\n\t\tconst inserted: boolean = insertBlockAfterAnchor(\n\t\t\tstate,\n\t\t\tbuilder,\n\t\t\tanchorBlockId,\n\t\t\tcodeBlock,\n\t\t\tsel,\n\t\t\tthis.context?.getSchemaRegistry(),\n\t\t);\n\t\tif (!inserted) return null;\n\n\t\tbuilder.setSelection(createCollapsedSelection(newBlockId, detection.formattedText.length));\n\n\t\treturn builder.build();\n\t}\n\n\t// --- Mixed Content (multiple blocks) ---\n\n\tprivate handleMixedContent(\n\t\tstate: EditorState,\n\t\tsegments: readonly PasteSegment[],\n\t): Transaction | null {\n\t\tconst tr: Transaction | null = this.buildMultiBlockTransaction(state, segments);\n\t\tif (tr && this.context) {\n\t\t\tthis.announceMixedContent(segments);\n\t\t}\n\t\treturn tr;\n\t}\n\n\tprivate buildMultiBlockTransaction(\n\t\tstate: EditorState,\n\t\tsegments: readonly PasteSegment[],\n\t): Transaction | null {\n\t\tconst sel = state.selection;\n\t\tconst builder = state.transaction('paste');\n\n\t\tlet anchorBlockId: BlockId;\n\t\tif (isTextSelection(sel) && !isCollapsed(sel)) {\n\t\t\tconst landingId: BlockId | undefined = addDeleteSelectionSteps(state, builder);\n\t\t\tanchorBlockId = landingId ?? sel.anchor.blockId;\n\t\t} else {\n\t\t\tanchorBlockId = resolveAnchorBlockId(sel);\n\t\t}\n\n\t\tconst cellId: BlockId | undefined = findTableCellAncestor(state, anchorBlockId);\n\t\tconst schemaRegistry = this.context?.getSchemaRegistry();\n\n\t\tconst ctx: InsertionContext | undefined = cellId\n\t\t\t? resolveCellInsertionContext(state, anchorBlockId, cellId, schemaRegistry)\n\t\t\t: resolveRootInsertionContext(state, anchorBlockId, schemaRegistry);\n\t\tif (!ctx) return null;\n\n\t\tconst insertOffset: number = !cellId && isGapCursor(sel) && sel.side === 'before' ? 0 : 1;\n\t\tlet insertIndex: number = ctx.anchorIndex + insertOffset;\n\t\tlet lastBlockId: BlockId | undefined;\n\t\tlet lastBlockTextLen = 0;\n\n\t\tfor (const segment of segments) {\n\t\t\tconst block: BlockNode = segment.detection\n\t\t\t\t? this.createCodeBlockNode(segment.detection)\n\t\t\t\t: this.createParagraphNode(segment.text);\n\n\t\t\tbuilder.insertNode(ctx.parentPath, insertIndex, block);\n\t\t\tinsertIndex++;\n\t\t\tlastBlockId = block.id;\n\t\t\tlastBlockTextLen = segment.detection\n\t\t\t\t? segment.detection.formattedText.length\n\t\t\t\t: segment.text.length;\n\t\t}\n\n\t\tconst shouldRemoveAnchor: boolean = cellId\n\t\t\t? ctx.isAnchorEmpty && ctx.anchorIndex >= 0\n\t\t\t: ctx.isAnchorEmpty && !isGapCursor(sel);\n\n\t\tif (shouldRemoveAnchor) {\n\t\t\tbuilder.removeNode(ctx.parentPath, ctx.anchorIndex);\n\t\t}\n\n\t\tif (lastBlockId) {\n\t\t\tbuilder.setSelection(createCollapsedSelection(lastBlockId, lastBlockTextLen));\n\t\t}\n\n\t\treturn builder.build();\n\t}\n\n\tprivate createCodeBlockNode(detection: DetectionResult): BlockNode {\n\t\treturn createBlockNode(\n\t\t\tnodeType('code_block') as NodeTypeName,\n\t\t\t[createTextNode(detection.formattedText)],\n\t\t\tgenerateBlockId(),\n\t\t\t{ language: detection.language, backgroundColor: '' },\n\t\t);\n\t}\n\n\tprivate createParagraphNode(text: string): BlockNode {\n\t\treturn createBlockNode(\n\t\t\tnodeType('paragraph') as NodeTypeName,\n\t\t\t[createTextNode(text)],\n\t\t\tgenerateBlockId(),\n\t\t);\n\t}\n\n\tprivate announceMixedContent(segments: readonly PasteSegment[]): void {\n\t\tlet textCount = 0;\n\t\tlet codeCount = 0;\n\t\tconst languages: string[] = [];\n\n\t\tfor (const segment of segments) {\n\t\t\tif (segment.detection) {\n\t\t\t\tcodeCount++;\n\t\t\t\tif (!languages.includes(segment.detection.language)) {\n\t\t\t\t\tlanguages.push(segment.detection.language);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttextCount++;\n\t\t\t}\n\t\t}\n\n\t\tthis.context?.announce(this.locale.detectedMixedContent(textCount, codeCount, languages));\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SmartPastePlugin-Bi_wpTCV.mjs","names":[],"sources":["../../src/plugins/smart-paste/ContentSplitter.ts","../../src/plugins/smart-paste/SmartPasteLocale.ts","../../src/plugins/smart-paste/SmartPasteTypes.ts","../../src/plugins/smart-paste/SmartPastePlugin.ts"],"sourcesContent":["/**\n * Splits pasted text at blank-line boundaries and classifies each segment\n * using content detectors. Adjacent segments of the same type are merged.\n */\n\nimport type { ContentDetector, DetectionResult, PasteSegment } from './SmartPasteTypes.js';\n\n/** Pattern matching one or more consecutive blank lines (may contain whitespace). */\nconst BLANK_LINE_SPLIT: RegExp = /\\n(?:[ \\t]*\\n)+/;\n\n/**\n * Splits text at blank-line boundaries and classifies each segment\n * using the provided detectors. Returns null if no code is detected\n * in any segment (the paste should fall through to default handling).\n */\nexport function splitAndClassify(\n\ttext: string,\n\tdetectors: readonly ContentDetector[],\n): readonly PasteSegment[] | null {\n\tconst rawSegments: readonly string[] = text.split(BLANK_LINE_SPLIT);\n\tconst trimmed: readonly string[] = rawSegments\n\t\t.map((s: string) => s.trim())\n\t\t.filter((s: string) => s.length > 0);\n\n\tif (trimmed.length === 0) return null;\n\n\tlet hasCode = false;\n\tconst segments: PasteSegment[] = trimmed.map((segmentText: string): PasteSegment => {\n\t\tconst detection: DetectionResult | null = detectBest(segmentText, detectors);\n\t\tif (detection) hasCode = true;\n\t\treturn { text: segmentText, detection };\n\t});\n\n\tif (!hasCode) return null;\n\n\treturn mergeAdjacentSegments(segments);\n}\n\n/**\n * Merges adjacent segments that share the same classification:\n * consecutive text segments become one paragraph, consecutive code\n * segments of the same language become one code block.\n */\nexport function mergeAdjacentSegments(segments: readonly PasteSegment[]): readonly PasteSegment[] {\n\tif (segments.length <= 1) return segments;\n\n\tconst merged: PasteSegment[] = [segments[0] as PasteSegment];\n\n\tfor (let i = 1; i < segments.length; i++) {\n\t\tconst current: PasteSegment = segments[i] as PasteSegment;\n\t\tconst previous: PasteSegment = merged[merged.length - 1] as PasteSegment;\n\n\t\tif (canMerge(previous, current)) {\n\t\t\tmerged[merged.length - 1] = merge(previous, current);\n\t\t} else {\n\t\t\tmerged.push(current);\n\t\t}\n\t}\n\n\treturn merged;\n}\n\n/**\n * Picks the highest-confidence detection result from all detectors.\n * Ties are broken deterministically by lexicographic language id so the\n * outcome does not depend on detector registration order.\n */\nfunction detectBest(text: string, detectors: readonly ContentDetector[]): DetectionResult | null {\n\tlet best: DetectionResult | null = null;\n\n\tfor (const detector of detectors) {\n\t\tconst result: DetectionResult | null = detector.detect(text);\n\t\tif (!result) continue;\n\t\tif (\n\t\t\tbest === null ||\n\t\t\tresult.confidence > best.confidence ||\n\t\t\t(result.confidence === best.confidence && result.language < best.language)\n\t\t) {\n\t\t\tbest = result;\n\t\t}\n\t}\n\n\treturn best;\n}\n\n/** Two segments can merge if both are text or both are code of the same language. */\nfunction canMerge(a: PasteSegment, b: PasteSegment): boolean {\n\tif (!a.detection && !b.detection) return true;\n\tif (a.detection && b.detection) return a.detection.language === b.detection.language;\n\treturn false;\n}\n\n/** Merges two compatible segments into one. */\nfunction merge(a: PasteSegment, b: PasteSegment): PasteSegment {\n\tconst joinedText: string = `${a.text}\\n\\n${b.text}`;\n\n\tif (!a.detection && !b.detection) {\n\t\treturn { text: joinedText, detection: null };\n\t}\n\n\tconst detA: DetectionResult = a.detection as DetectionResult;\n\tconst detB: DetectionResult = b.detection as DetectionResult;\n\n\treturn {\n\t\ttext: joinedText,\n\t\tdetection: {\n\t\t\tlanguage: detA.language,\n\t\t\tformattedText: `${detA.formattedText}\\n\\n${detB.formattedText}`,\n\t\t\tconfidence: Math.max(detA.confidence, detB.confidence),\n\t\t},\n\t};\n}\n","/** Locale interface and default English locale for the SmartPastePlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\nexport interface SmartPasteLocale {\n\treadonly detectedAsCodeBlock: (language: string) => string;\n\treadonly detectedMixedContent: (\n\t\ttextCount: number,\n\t\tcodeCount: number,\n\t\tlanguages: readonly string[],\n\t) => string;\n}\n\nexport const SMART_PASTE_LOCALE_EN: SmartPasteLocale = {\n\tdetectedAsCodeBlock: (language: string) =>\n\t\t`Pasted as ${language} code block with syntax highlighting.`,\n\tdetectedMixedContent: (textCount: number, codeCount: number, languages: readonly string[]) => {\n\t\tconst parts: string[] = [];\n\t\tif (textCount > 0) {\n\t\t\tparts.push(`${textCount} paragraph${textCount > 1 ? 's' : ''}`);\n\t\t}\n\t\tif (codeCount > 0) {\n\t\t\tconst langList: string = languages.join(', ');\n\t\t\tparts.push(`${codeCount} code block${codeCount > 1 ? 's' : ''} (${langList})`);\n\t\t}\n\t\treturn `Pasted as ${parts.join(' and ')}.`;\n\t},\n};\n\nconst localeModules: LocaleModuleMap<SmartPasteLocale> = import.meta.glob<{\n\tdefault: SmartPasteLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadSmartPasteLocale(lang: string): Promise<SmartPasteLocale> {\n\treturn loadLocaleModule(localeModules, lang, SMART_PASTE_LOCALE_EN);\n}\n","/**\n * Types for the smart paste plugin — content detection and formatting.\n */\n\nimport { ServiceKey } from '../Plugin.js';\nimport type { SmartPasteLocale } from './SmartPasteLocale.js';\n\n/** Result of detecting structured content in pasted text. */\nexport interface DetectionResult {\n\treadonly language: string;\n\treadonly formattedText: string;\n\treadonly confidence: number;\n}\n\n/** A classified segment of pasted text — either plain text or detected code. */\nexport interface PasteSegment {\n\treadonly text: string;\n\treadonly detection: DetectionResult | null;\n}\n\n/** Interface for content detectors that identify and format pasted text. */\nexport interface ContentDetector {\n\treadonly id: string;\n\tdetect(text: string): DetectionResult | null;\n}\n\n/** Configuration for the SmartPastePlugin. */\nexport interface SmartPasteConfig {\n\treadonly detectors?: readonly ContentDetector[];\n\treadonly locale?: SmartPasteLocale;\n}\n\n/** Public service for registering additional content detectors at runtime. */\nexport interface SmartPasteService {\n\tregisterDetector(detector: ContentDetector): void;\n}\n\nexport const SMART_PASTE_SERVICE_KEY = new ServiceKey<SmartPasteService>('smartPaste');\n","/**\n * SmartPastePlugin: detects structured content in clipboard text\n * and inserts it as formatted code blocks with syntax highlighting.\n * Mixed content (text + code) is split into separate blocks.\n */\n\nimport {\n\ttype InsertionContext,\n\tfindTableCellAncestor,\n\tinsertBlockAfterAnchor,\n\tresolveAnchorBlockId,\n\tresolveCellInsertionContext,\n\tresolveRootInsertionContext,\n} from '../../commands/BlockInsertion.js';\nimport { addDeleteSelectionSteps } from '../../commands/Commands.js';\nimport {\n\ttype BlockNode,\n\tcreateBlockNode,\n\tcreateTextNode,\n\tgenerateBlockId,\n} from '../../model/Document.js';\nimport {\n\tcreateCollapsedSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisTextSelection,\n} from '../../model/Selection.js';\nimport type { BlockId, NodeTypeName } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport type { PasteInterceptor, Plugin, PluginContext } from '../Plugin.js';\nimport { LANGUAGE_REGISTRY_SERVICE_KEY } from '../language/LanguageTypes.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { splitAndClassify } from './ContentSplitter.js';\nimport {\n\tSMART_PASTE_LOCALE_EN,\n\ttype SmartPasteLocale,\n\tloadSmartPasteLocale,\n} from './SmartPasteLocale.js';\nimport type {\n\tContentDetector,\n\tDetectionResult,\n\tPasteSegment,\n\tSmartPasteConfig,\n} from './SmartPasteTypes.js';\nimport { SMART_PASTE_SERVICE_KEY } from './SmartPasteTypes.js';\n\nexport class SmartPastePlugin implements Plugin {\n\treadonly id = 'smart-paste';\n\treadonly name = 'Smart Paste';\n\treadonly dependencies = ['code-block'] as const;\n\n\tprivate readonly config: SmartPasteConfig;\n\tprivate readonly detectors: ContentDetector[] = [];\n\tprivate context: PluginContext | null = null;\n\tprivate locale: SmartPasteLocale = SMART_PASTE_LOCALE_EN;\n\n\tconstructor(config?: Partial<SmartPasteConfig>) {\n\t\tthis.config = { ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.context = context;\n\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSMART_PASTE_LOCALE_EN,\n\t\t\tloadSmartPasteLocale,\n\t\t);\n\n\t\t// Subscribe to language registry for detectors (replay provides built-ins)\n\t\tconst registry = context.getService(LANGUAGE_REGISTRY_SERVICE_KEY);\n\t\tif (registry) {\n\t\t\tregistry.onRegister((support) => {\n\t\t\t\tif (support.detection) {\n\t\t\t\t\tthis.detectors.push(support.detection);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// Register config-provided detectors\n\t\tif (this.config.detectors) {\n\t\t\tfor (const detector of this.config.detectors) {\n\t\t\t\tthis.detectors.push(detector);\n\t\t\t}\n\t\t}\n\n\t\t// Register paste interceptor\n\t\tcontext.registerPasteInterceptor(this.handlePaste, { name: 'smart-paste', priority: 50 });\n\n\t\t// Register service for external detector registration\n\t\tcontext.registerService(SMART_PASTE_SERVICE_KEY, {\n\t\t\tregisterDetector: (detector: ContentDetector) => {\n\t\t\t\tthis.detectors.push(detector);\n\t\t\t},\n\t\t});\n\t}\n\n\tdestroy(): void {\n\t\tthis.context = null;\n\t\tthis.detectors.length = 0;\n\t}\n\n\t// --- Paste Interceptor ---\n\n\tprivate readonly handlePaste: PasteInterceptor = (\n\t\tplainText: string,\n\t\t_html: string,\n\t\tstate: EditorState,\n\t): Transaction | null => {\n\t\tif (this.isCursorInCodeBlock(state)) return null;\n\n\t\tconst segments: readonly PasteSegment[] | null = splitAndClassify(plainText, this.detectors);\n\t\tif (!segments) return null;\n\n\t\t// Single code-only segment: use existing fast path\n\t\tif (segments.length === 1 && segments[0]?.detection) {\n\t\t\treturn this.handleSingleCodeBlock(state, segments[0].detection);\n\t\t}\n\n\t\t// Mixed content: create multiple blocks\n\t\treturn this.handleMixedContent(state, segments);\n\t};\n\n\tprivate isCursorInCodeBlock(state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (!isTextSelection(sel)) return false;\n\n\t\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\t\treturn block?.type === 'code_block';\n\t}\n\n\t// --- Single Code Block (existing behavior) ---\n\n\tprivate handleSingleCodeBlock(\n\t\tstate: EditorState,\n\t\tdetection: DetectionResult,\n\t): Transaction | null {\n\t\tconst tr: Transaction | null = this.buildCodeBlockTransaction(state, detection);\n\t\tif (tr && this.context) {\n\t\t\tthis.context.announce(this.locale.detectedAsCodeBlock(detection.language));\n\t\t}\n\t\treturn tr;\n\t}\n\n\tprivate buildCodeBlockTransaction(\n\t\tstate: EditorState,\n\t\tdetection: DetectionResult,\n\t): Transaction | null {\n\t\tconst sel = state.selection;\n\t\tconst builder = state.transaction('paste');\n\n\t\t// Delete selection if range-selected\n\t\tlet anchorBlockId: BlockId;\n\t\tif (isTextSelection(sel) && !isCollapsed(sel)) {\n\t\t\tconst landingId: BlockId | undefined = addDeleteSelectionSteps(state, builder);\n\t\t\tanchorBlockId = landingId ?? sel.anchor.blockId;\n\t\t} else {\n\t\t\tanchorBlockId = resolveAnchorBlockId(sel);\n\t\t}\n\n\t\t// Create the code block node\n\t\tconst newBlockId: BlockId = generateBlockId();\n\t\tconst codeBlock: BlockNode = createBlockNode(\n\t\t\tnodeType('code_block') as NodeTypeName,\n\t\t\t[createTextNode(detection.formattedText)],\n\t\t\tnewBlockId,\n\t\t\t{ language: detection.language, backgroundColor: '' },\n\t\t);\n\n\t\t// Insert at cursor (handles cell vs root, empty anchor removal)\n\t\tconst inserted: boolean = insertBlockAfterAnchor(\n\t\t\tstate,\n\t\t\tbuilder,\n\t\t\tanchorBlockId,\n\t\t\tcodeBlock,\n\t\t\tsel,\n\t\t\tthis.context?.getSchemaRegistry(),\n\t\t);\n\t\tif (!inserted) return null;\n\n\t\tbuilder.setSelection(createCollapsedSelection(newBlockId, detection.formattedText.length));\n\n\t\treturn builder.build();\n\t}\n\n\t// --- Mixed Content (multiple blocks) ---\n\n\tprivate handleMixedContent(\n\t\tstate: EditorState,\n\t\tsegments: readonly PasteSegment[],\n\t): Transaction | null {\n\t\tconst tr: Transaction | null = this.buildMultiBlockTransaction(state, segments);\n\t\tif (tr && this.context) {\n\t\t\tthis.announceMixedContent(segments);\n\t\t}\n\t\treturn tr;\n\t}\n\n\tprivate buildMultiBlockTransaction(\n\t\tstate: EditorState,\n\t\tsegments: readonly PasteSegment[],\n\t): Transaction | null {\n\t\tconst sel = state.selection;\n\t\tconst builder = state.transaction('paste');\n\n\t\tlet anchorBlockId: BlockId;\n\t\tif (isTextSelection(sel) && !isCollapsed(sel)) {\n\t\t\tconst landingId: BlockId | undefined = addDeleteSelectionSteps(state, builder);\n\t\t\tanchorBlockId = landingId ?? sel.anchor.blockId;\n\t\t} else {\n\t\t\tanchorBlockId = resolveAnchorBlockId(sel);\n\t\t}\n\n\t\tconst cellId: BlockId | undefined = findTableCellAncestor(state, anchorBlockId);\n\t\tconst schemaRegistry = this.context?.getSchemaRegistry();\n\n\t\tconst ctx: InsertionContext | undefined = cellId\n\t\t\t? resolveCellInsertionContext(state, anchorBlockId, cellId, schemaRegistry)\n\t\t\t: resolveRootInsertionContext(state, anchorBlockId, schemaRegistry);\n\t\tif (!ctx) return null;\n\n\t\tconst insertOffset: number = !cellId && isGapCursor(sel) && sel.side === 'before' ? 0 : 1;\n\t\tlet insertIndex: number = ctx.anchorIndex + insertOffset;\n\t\tlet lastBlockId: BlockId | undefined;\n\t\tlet lastBlockTextLen = 0;\n\n\t\tfor (const segment of segments) {\n\t\t\tconst block: BlockNode = segment.detection\n\t\t\t\t? this.createCodeBlockNode(segment.detection)\n\t\t\t\t: this.createParagraphNode(segment.text);\n\n\t\t\tbuilder.insertNode(ctx.parentPath, insertIndex, block);\n\t\t\tinsertIndex++;\n\t\t\tlastBlockId = block.id;\n\t\t\tlastBlockTextLen = segment.detection\n\t\t\t\t? segment.detection.formattedText.length\n\t\t\t\t: segment.text.length;\n\t\t}\n\n\t\tconst shouldRemoveAnchor: boolean = cellId\n\t\t\t? ctx.isAnchorEmpty && ctx.anchorIndex >= 0\n\t\t\t: ctx.isAnchorEmpty && !isGapCursor(sel);\n\n\t\tif (shouldRemoveAnchor) {\n\t\t\tbuilder.removeNode(ctx.parentPath, ctx.anchorIndex);\n\t\t}\n\n\t\tif (lastBlockId) {\n\t\t\tbuilder.setSelection(createCollapsedSelection(lastBlockId, lastBlockTextLen));\n\t\t}\n\n\t\treturn builder.build();\n\t}\n\n\tprivate createCodeBlockNode(detection: DetectionResult): BlockNode {\n\t\treturn createBlockNode(\n\t\t\tnodeType('code_block') as NodeTypeName,\n\t\t\t[createTextNode(detection.formattedText)],\n\t\t\tgenerateBlockId(),\n\t\t\t{ language: detection.language, backgroundColor: '' },\n\t\t);\n\t}\n\n\tprivate createParagraphNode(text: string): BlockNode {\n\t\treturn createBlockNode(\n\t\t\tnodeType('paragraph') as NodeTypeName,\n\t\t\t[createTextNode(text)],\n\t\t\tgenerateBlockId(),\n\t\t);\n\t}\n\n\tprivate announceMixedContent(segments: readonly PasteSegment[]): void {\n\t\tlet textCount = 0;\n\t\tlet codeCount = 0;\n\t\tconst languages: string[] = [];\n\n\t\tfor (const segment of segments) {\n\t\t\tif (segment.detection) {\n\t\t\t\tcodeCount++;\n\t\t\t\tif (!languages.includes(segment.detection.language)) {\n\t\t\t\t\tlanguages.push(segment.detection.language);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttextCount++;\n\t\t\t}\n\t\t}\n\n\t\tthis.context?.announce(this.locale.detectedMixedContent(textCount, codeCount, languages));\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{c as t,o as s}from"./PluginHelpers-KDuTlmXm.mjs";import{t as o}from"./ShortcutFormatting-TwiufqeV.mjs";import{t as r}from"./SimpleMark-CaQtFAau.mjs";var i={label:"Strikethrough",tooltip:t=>`Strikethrough (${t})`},e=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-XmSFrtmd.mjs"),"./locales/de.ts":()=>import("./de-DViI26lG.mjs"),"./locales/es.ts":()=>import("./es-paXY7HFt.mjs"),"./locales/fr.ts":()=>import("./fr-ZsRdLuys.mjs"),"./locales/hi.ts":()=>import("./hi-CTWubxLY.mjs"),"./locales/pt.ts":()=>import("./pt-paXY7HFt.mjs"),"./locales/ru.ts":()=>import("./ru-Y11wuxOB.mjs"),"./locales/zh.ts":()=>import("./zh-C7iCgCRP.mjs")});async function a(s){return t(e,s,i)}var l={},h=class{id="strikethrough";name="Strikethrough";priority=22;config;locale;constructor(t){this.config={...l,...t}}async init(t){this.locale=await s(t,this.config.locale,i,a),r(t,{markSpec:{type:"strikethrough",rank:3,toDOM:()=>document.createElement("s"),toHTMLString:(t,s)=>`<s>${s}</s>`,parseHTML:[{tag:"s"},{tag:"strike"},{tag:"del"},{tag:"span",getAttrs:t=>!!t.style.textDecoration.includes("line-through")&&{}}],sanitize:{tags:["s"]}},command:"toggleStrikethrough",keyBinding:"Mod-Shift-X",toolbar:{id:"strikethrough",group:"format",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 19h4v-3h-4v3zM5 4v3h5v3h4V7h5V4H5zM3 14h18v-2H3v2z"/></svg>',label:this.locale.label,tooltip:this.locale.tooltip(o("Mod-Shift-X"))}})}};export{i as n,a as r,h as t};
2
+ //# sourceMappingURL=StrikethroughPlugin-BLKDRWtf.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"StrikethroughPlugin-Bsg7Ma4I.mjs","names":[],"sources":["../../src/plugins/strikethrough/StrikethroughLocale.ts","../../src/plugins/strikethrough/StrikethroughPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the StrikethroughPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface StrikethroughLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const STRIKETHROUGH_LOCALE_EN: StrikethroughLocale = {\n\tlabel: 'Strikethrough',\n\ttooltip: (shortcut: string) => `Strikethrough (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<StrikethroughLocale> = import.meta.glob<{\n\tdefault: StrikethroughLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadStrikethroughLocale(lang: string): Promise<StrikethroughLocale> {\n\treturn loadLocaleModule(localeModules, lang, STRIKETHROUGH_LOCALE_EN);\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 type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { registerSimpleMark } from '../shared/SimpleMark.js';\nimport {\n\tSTRIKETHROUGH_LOCALE_EN,\n\ttype StrikethroughLocale,\n\tloadStrikethroughLocale,\n} from './StrikethroughLocale.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\treadonly locale?: StrikethroughLocale;\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\tprivate locale!: StrikethroughLocale;\n\n\tconstructor(config?: Partial<StrikethroughConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSTRIKETHROUGH_LOCALE_EN,\n\t\t\tloadStrikethroughLocale,\n\t\t);\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\tregisterSimpleMark(context, {\n\t\t\tmarkSpec: {\n\t\t\t\ttype: 'strikethrough',\n\t\t\t\trank: 3,\n\t\t\t\ttoDOM() {\n\t\t\t\t\treturn document.createElement('s');\n\t\t\t\t},\n\t\t\t\ttoHTMLString: (_mark, content) => `<s>${content}</s>`,\n\t\t\t\tparseHTML: [\n\t\t\t\t\t{ tag: 's' },\n\t\t\t\t\t{ tag: 'strike' },\n\t\t\t\t\t{ tag: 'del' },\n\t\t\t\t\t{\n\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\t\t\treturn el.style.textDecoration.includes('line-through') ? {} : false;\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsanitize: { tags: ['s'] },\n\t\t\t},\n\t\t\tcommand: 'toggleStrikethrough',\n\t\t\tkeyBinding: 'Mod-Shift-X',\n\t\t\ttoolbar: {\n\t\t\t\tid: 'strikethrough',\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon,\n\t\t\t\tlabel: this.locale.label,\n\t\t\t\ttooltip: this.locale.tooltip(formatShortcut('Mod-Shift-X')),\n\t\t\t},\n\t\t});\n\t}\n}\n"],"mappings":"uJAeA,IAAa,EAA+C,CAC3D,MAAO,gBACP,QAAU,GAAqB,kBAAkB,MAK5C,iBAAsD,OAAA,OAAA,CAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,uBAI5D,eAAsB,EAAwB,GAC7C,OAAO,EAAiB,EAAe,EAAM,EAC9C,CCCA,IAAM,EAAsC,CAAC,EAIhC,EAAb,MACC,GAAc,gBACd,KAAgB,gBAChB,SAAoB,GAEpB,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,KAAmB,EACvC,CAEA,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAKD,EAAmB,EAAS,CAC3B,SAAU,CACT,KAAM,gBACN,KAAM,EACN,MAAA,IACQ,SAAS,cAAc,KAE/B,aAAA,CAAe,EAAO,IAAY,MAAM,QACxC,UAAW,CACV,CAAE,IAAK,KACP,CAAE,IAAK,UACP,CAAE,IAAK,OACP,CACC,IAAK,OACL,SAAW,KACH,EAAG,MAAM,eAAe,SAAS,iBAAkB,CAAC,IAI9D,SAAU,CAAE,KAAM,CAAC,OAEpB,QAAS,sBACT,WAAY,cACZ,QAAS,CACR,GAAI,gBACJ,MAAO,SACP,KAAA,uIACA,MAAO,KAAK,OAAO,MACnB,QAAS,KAAK,OAAO,QAAQ,EAAe,kBAG/C"}
1
+ {"version":3,"file":"StrikethroughPlugin-BLKDRWtf.mjs","names":[],"sources":["../../src/plugins/strikethrough/StrikethroughLocale.ts","../../src/plugins/strikethrough/StrikethroughPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the StrikethroughPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface StrikethroughLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const STRIKETHROUGH_LOCALE_EN: StrikethroughLocale = {\n\tlabel: 'Strikethrough',\n\ttooltip: (shortcut: string) => `Strikethrough (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<StrikethroughLocale> = import.meta.glob<{\n\tdefault: StrikethroughLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadStrikethroughLocale(lang: string): Promise<StrikethroughLocale> {\n\treturn loadLocaleModule(localeModules, lang, STRIKETHROUGH_LOCALE_EN);\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 type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { registerSimpleMark } from '../shared/SimpleMark.js';\nimport {\n\tSTRIKETHROUGH_LOCALE_EN,\n\ttype StrikethroughLocale,\n\tloadStrikethroughLocale,\n} from './StrikethroughLocale.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\treadonly locale?: StrikethroughLocale;\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\tprivate locale!: StrikethroughLocale;\n\n\tconstructor(config?: Partial<StrikethroughConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSTRIKETHROUGH_LOCALE_EN,\n\t\t\tloadStrikethroughLocale,\n\t\t);\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\tregisterSimpleMark(context, {\n\t\t\tmarkSpec: {\n\t\t\t\ttype: 'strikethrough',\n\t\t\t\trank: 3,\n\t\t\t\ttoDOM() {\n\t\t\t\t\treturn document.createElement('s');\n\t\t\t\t},\n\t\t\t\ttoHTMLString: (_mark, content) => `<s>${content}</s>`,\n\t\t\t\tparseHTML: [\n\t\t\t\t\t{ tag: 's' },\n\t\t\t\t\t{ tag: 'strike' },\n\t\t\t\t\t{ tag: 'del' },\n\t\t\t\t\t{\n\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\t\t\treturn el.style.textDecoration.includes('line-through') ? {} : false;\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsanitize: { tags: ['s'] },\n\t\t\t},\n\t\t\tcommand: 'toggleStrikethrough',\n\t\t\tkeyBinding: 'Mod-Shift-X',\n\t\t\ttoolbar: {\n\t\t\t\tid: 'strikethrough',\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon,\n\t\t\t\tlabel: this.locale.label,\n\t\t\t\ttooltip: this.locale.tooltip(formatShortcut('Mod-Shift-X')),\n\t\t\t},\n\t\t});\n\t}\n}\n"],"mappings":"4JAeA,IAAa,EAA+C,CAC3D,MAAO,gBACP,QAAU,GAAqB,kBAAkB,MAK5C,iBAAsD,OAAA,OAAA,CAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,uBAI5D,eAAsB,EAAwB,GAC7C,OAAO,EAAiB,EAAe,EAAM,EAC9C,CCCA,IAAM,EAAsC,CAAC,EAIhC,EAAb,MACC,GAAc,gBACd,KAAgB,gBAChB,SAAoB,GAEpB,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,KAAmB,EACvC,CAEA,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAKD,EAAmB,EAAS,CAC3B,SAAU,CACT,KAAM,gBACN,KAAM,EACN,MAAA,IACQ,SAAS,cAAc,KAE/B,aAAA,CAAe,EAAO,IAAY,MAAM,QACxC,UAAW,CACV,CAAE,IAAK,KACP,CAAE,IAAK,UACP,CAAE,IAAK,OACP,CACC,IAAK,OACL,SAAW,KACH,EAAG,MAAM,eAAe,SAAS,iBAAkB,CAAC,IAI9D,SAAU,CAAE,KAAM,CAAC,OAEpB,QAAS,sBACT,WAAY,cACZ,QAAS,CACR,GAAI,gBACJ,MAAO,SACP,KAAA,uIACA,MAAO,KAAK,OAAO,MACnB,QAAS,KAAK,OAAO,QAAQ,EAAe,kBAG/C"}
@@ -1,2 +1,2 @@
1
- import{_ as s,m as t}from"./Commands-CyT1Li7_.mjs";import{i as e}from"./TypeBrands-Ch9856Gb.mjs";import{a as i,n as r,o,s as p}from"./PluginHelpers-D4quRJ5a.mjs";import{t as c}from"./ShortcutFormatting-TwiufqeV.mjs";var a={superscriptLabel:"Superscript",superscriptTooltip:s=>`Superscript (${s})`,subscriptLabel:"Subscript",subscriptTooltip:s=>`Subscript (${s})`},n=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-NV_puwI2.mjs"),"./locales/de.ts":()=>import("./de-BX4y4PlH.mjs"),"./locales/es.ts":()=>import("./es-BdpTTRuX.mjs"),"./locales/fr.ts":()=>import("./fr-CKjH6tJI.mjs"),"./locales/hi.ts":()=>import("./hi-DsdXcOB6.mjs"),"./locales/pt.ts":()=>import("./pt-OXa_IR4Q.mjs"),"./locales/ru.ts":()=>import("./ru-d68SZpEe.mjs"),"./locales/zh.ts":()=>import("./zh-BP97XjlS.mjs")});async function l(s){return p(n,s,a)}var u={superscript:!0,subscript:!0},m=[{type:"superscript",opposite:"subscript",configKey:"superscript",rank:4,tag:"sup",icon:['<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">','<path d="M16 7.41L11.41 12 16 16.59 14.59 18l-6-6 6-6z"',' fill="none"/>','<path d="M9.64 7.64c.23-.5.36-1.05.36-1.64'," 0-2.21-1.79-4-4-4H2v14h4.36c2.34 0 4.24-1.9"," 4.24-4.24 0-1.6-.89-2.99-2.2-3.71zM4.5 4.5H6c.83"," 0 1.5.67 1.5 1.5S6.83 7.5 6 7.5H4.5v-3zm2 9H4.5v-3H6.5c.83",' 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" fill="none"/>','<path d="M15.97 3.84c0-.47.19-.91.53-1.21.34-.31.8-.49'," 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02","-.96-.43-1.83-1.13-2.42C19.36.77 18.45.44 17.5.44c-.88"," 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34"," 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"," 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54","-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96"," 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","-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46",'-.59-.46-.94z"/>','<path d="M5.88 20h2.66l3.4-5.42L15.3 20h2.67l-4.73-7.38',' 4.37-6.62h-2.6l-3.07 4.98L8.92 6h-2.6l4.26 6.58z"/>',"</svg>"].join(""),keyBinding:"Mod-.",toHTMLString:s=>`<sup>${s}</sup>`,parseHTML:[{tag:"sup"}],sanitize:{tags:["sup"]}},{type:"subscript",opposite:"superscript",configKey:"subscript",rank:4,tag:"sub",icon:['<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">','<path d="M15.97 16.84c0-.47.19-.91.53-1.21.34-.31.8-.49'," 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02","-.96-.43-1.83-1.13-2.42-.7-.58-1.61-.91-2.56-.91-.88"," 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34"," 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"," 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54","-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96"," 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","-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46",'-.59-.46-.94z"/>','<path d="M5.88 18h2.66l3.4-5.42L15.3 18h2.67l-4.73-7.38',' 4.37-6.62h-2.6l-3.07 4.98L8.92 4h-2.6l4.26 6.58z"/>',"</svg>"].join(""),keyBinding:"Mod-,",toHTMLString:s=>`<sub>${s}</sub>`,parseHTML:[{tag:"sub"}],sanitize:{tags:["sub"]}}],g=class{id="super-sub";name="Superscript & Subscript";priority=23;config;locale;constructor(s){this.config={...u,...s}}async init(s){this.locale=await i(s,this.config.locale,a,l);const t=m.filter(s=>this.config[s.configKey]);for(const e of t)this.registerMark(s,e);this.registerKeymaps(s,t),this.registerExclusivityMiddleware(s,t),this.registerDisabledToolbarItems(s)}registerMark(i,p){const a=o(p.type),n=this.isToolbarVisible(p.configKey);if(i.registerMarkSpec({type:p.type,rank:p.rank,toDOM:()=>document.createElement(p.tag),toHTMLString:(s,t)=>p.toHTMLString(t),parseHTML:p.parseHTML,sanitize:p.sanitize}),i.registerCommand(a,()=>r(i,s(i.getState(),e(p.type)))),n){const s="superscript"===p.type?this.locale.superscriptLabel:this.locale.subscriptLabel,r="superscript"===p.type?this.locale.superscriptTooltip(c(p.keyBinding)):this.locale.subscriptTooltip(c(p.keyBinding));i.registerToolbarItem({id:p.type,group:"format",icon:p.icon,label:s,tooltip:r,command:a,isActive:s=>t(s,e(p.type))})}}registerKeymaps(s,t){const e={};for(const i of t){const t=o(i.type);e[i.keyBinding]=()=>s.executeCommand(t)}Object.keys(e).length>0&&s.registerKeymap(e)}registerExclusivityMiddleware(s,t){t.some(s=>"superscript"===s.type)&&t.some(s=>"subscript"===s.type)&&s.registerMiddleware((s,t,i)=>{let r=!1;const o=[];for(const c of s.steps){if("addMark"!==c.type){o.push(c);continue}const s=c.mark.type,t=m.find(t=>t.type===s);if(!t){o.push(c);continue}r=!0;const i={type:"removeMark",blockId:c.blockId,from:c.from,to:c.to,mark:{type:e(t.opposite)},...c.path?{path:c.path}:{}};o.push(i,c)}let p=s.storedMarksAfter;if(p){const s=p.some(s=>"superscript"===s.type),t=p.some(s=>"subscript"===s.type);if(s&&t){const s=p.findLastIndex(s=>"superscript"===s.type)>p.findLastIndex(s=>"subscript"===s.type)?"subscript":"superscript";p=p.filter(t=>t.type!==s),r=!0}}i(r?{...s,steps:o,storedMarksAfter:p}:s)},{name:"super-sub:exclusivity"})}registerDisabledToolbarItems(s){if(this.config.toolbar)for(const t of m){const e=this.config[t.configKey],i=this.config.toolbar[t.configKey]??!0;if(!e&&i){const e="superscript"===t.type?this.locale.superscriptLabel:this.locale.subscriptLabel;s.registerToolbarItem({id:t.type,group:"format",icon:t.icon,label:e,command:o(t.type),isEnabled:()=>!1})}}}isToolbarVisible(s){return!this.config.toolbar||(this.config.toolbar[s]??!0)}};export{a as n,l as r,g as t};
2
- //# sourceMappingURL=SuperSubPlugin-ChEga-b_.mjs.map
1
+ import{_ as s,m as t}from"./Commands-BIIpx_Zd.mjs";import{i as e}from"./TypeBrands-Ch9856Gb.mjs";import{c as i,n as r,o,s as p}from"./PluginHelpers-KDuTlmXm.mjs";import{t as c}from"./ShortcutFormatting-TwiufqeV.mjs";var a={superscriptLabel:"Superscript",superscriptTooltip:s=>`Superscript (${s})`,subscriptLabel:"Subscript",subscriptTooltip:s=>`Subscript (${s})`},n=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-NV_puwI2.mjs"),"./locales/de.ts":()=>import("./de-BX4y4PlH.mjs"),"./locales/es.ts":()=>import("./es-BdpTTRuX.mjs"),"./locales/fr.ts":()=>import("./fr-CKjH6tJI.mjs"),"./locales/hi.ts":()=>import("./hi-DsdXcOB6.mjs"),"./locales/pt.ts":()=>import("./pt-OXa_IR4Q.mjs"),"./locales/ru.ts":()=>import("./ru-d68SZpEe.mjs"),"./locales/zh.ts":()=>import("./zh-BP97XjlS.mjs")});async function l(s){return i(n,s,a)}var u={superscript:!0,subscript:!0},m=[{type:"superscript",opposite:"subscript",configKey:"superscript",rank:4,tag:"sup",icon:['<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">','<path d="M16 7.41L11.41 12 16 16.59 14.59 18l-6-6 6-6z"',' fill="none"/>','<path d="M9.64 7.64c.23-.5.36-1.05.36-1.64'," 0-2.21-1.79-4-4-4H2v14h4.36c2.34 0 4.24-1.9"," 4.24-4.24 0-1.6-.89-2.99-2.2-3.71zM4.5 4.5H6c.83"," 0 1.5.67 1.5 1.5S6.83 7.5 6 7.5H4.5v-3zm2 9H4.5v-3H6.5c.83",' 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z" fill="none"/>','<path d="M15.97 3.84c0-.47.19-.91.53-1.21.34-.31.8-.49'," 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02","-.96-.43-1.83-1.13-2.42C19.36.77 18.45.44 17.5.44c-.88"," 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34"," 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"," 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54","-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96"," 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","-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46",'-.59-.46-.94z"/>','<path d="M5.88 20h2.66l3.4-5.42L15.3 20h2.67l-4.73-7.38',' 4.37-6.62h-2.6l-3.07 4.98L8.92 6h-2.6l4.26 6.58z"/>',"</svg>"].join(""),keyBinding:"Mod-.",toHTMLString:s=>`<sup>${s}</sup>`,parseHTML:[{tag:"sup"}],sanitize:{tags:["sup"]}},{type:"subscript",opposite:"superscript",configKey:"subscript",rank:4,tag:"sub",icon:['<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">','<path d="M15.97 16.84c0-.47.19-.91.53-1.21.34-.31.8-.49'," 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02","-.96-.43-1.83-1.13-2.42-.7-.58-1.61-.91-2.56-.91-.88"," 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34"," 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"," 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54","-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96"," 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","-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46",'-.59-.46-.94z"/>','<path d="M5.88 18h2.66l3.4-5.42L15.3 18h2.67l-4.73-7.38',' 4.37-6.62h-2.6l-3.07 4.98L8.92 4h-2.6l4.26 6.58z"/>',"</svg>"].join(""),keyBinding:"Mod-,",toHTMLString:s=>`<sub>${s}</sub>`,parseHTML:[{tag:"sub"}],sanitize:{tags:["sub"]}}],g=class{id="super-sub";name="Superscript & Subscript";priority=23;config;locale;constructor(s){this.config={...u,...s}}async init(s){this.locale=await o(s,this.config.locale,a,l);const t=m.filter(s=>this.config[s.configKey]);for(const e of t)this.registerMark(s,e);this.registerKeymaps(s,t),this.registerExclusivityMiddleware(s,t),this.registerDisabledToolbarItems(s)}registerMark(i,o){const a=p(o.type),n=this.isToolbarVisible(o.configKey);if(i.registerMarkSpec({type:o.type,rank:o.rank,toDOM:()=>document.createElement(o.tag),toHTMLString:(s,t)=>o.toHTMLString(t),parseHTML:o.parseHTML,sanitize:o.sanitize}),i.registerCommand(a,()=>r(i,s(i.getState(),e(o.type)))),n){const s="superscript"===o.type?this.locale.superscriptLabel:this.locale.subscriptLabel,r="superscript"===o.type?this.locale.superscriptTooltip(c(o.keyBinding)):this.locale.subscriptTooltip(c(o.keyBinding));i.registerToolbarItem({id:o.type,group:"format",icon:o.icon,label:s,tooltip:r,command:a,isActive:s=>t(s,e(o.type))})}}registerKeymaps(s,t){const e={};for(const i of t){const t=p(i.type);e[i.keyBinding]=()=>s.executeCommand(t)}Object.keys(e).length>0&&s.registerKeymap(e)}registerExclusivityMiddleware(s,t){t.some(s=>"superscript"===s.type)&&t.some(s=>"subscript"===s.type)&&s.registerMiddleware((s,t,i)=>{let r=!1;const o=[];for(const c of s.steps){if("addMark"!==c.type){o.push(c);continue}const s=c.mark.type,t=m.find(t=>t.type===s);if(!t){o.push(c);continue}r=!0;const i={type:"removeMark",blockId:c.blockId,from:c.from,to:c.to,mark:{type:e(t.opposite)},...c.path?{path:c.path}:{}};o.push(i,c)}let p=s.storedMarksAfter;if(p){const s=p.some(s=>"superscript"===s.type),t=p.some(s=>"subscript"===s.type);if(s&&t){const s=p.findLastIndex(s=>"superscript"===s.type)>p.findLastIndex(s=>"subscript"===s.type)?"subscript":"superscript";p=p.filter(t=>t.type!==s),r=!0}}i(r?{...s,steps:o,storedMarksAfter:p}:s)},{name:"super-sub:exclusivity"})}registerDisabledToolbarItems(s){if(this.config.toolbar)for(const t of m){const e=this.config[t.configKey],i=this.config.toolbar[t.configKey]??!0;if(!e&&i){const e="superscript"===t.type?this.locale.superscriptLabel:this.locale.subscriptLabel;s.registerToolbarItem({id:t.type,group:"format",icon:t.icon,label:e,command:p(t.type),isEnabled:()=>!1})}}}isToolbarVisible(s){return!this.config.toolbar||(this.config.toolbar[s]??!0)}};export{a as n,l as r,g as t};
2
+ //# sourceMappingURL=SuperSubPlugin-DVP7VnIz.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"SuperSubPlugin-ChEga-b_.mjs","names":[],"sources":["../../src/plugins/super-sub/SuperSubLocale.ts","../../src/plugins/super-sub/SuperSubPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the SuperSubPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface SuperSubLocale {\n\treadonly superscriptLabel: string;\n\treadonly superscriptTooltip: (shortcut: string) => string;\n\treadonly subscriptLabel: string;\n\treadonly subscriptTooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const SUPER_SUB_LOCALE_EN: SuperSubLocale = {\n\tsuperscriptLabel: 'Superscript',\n\tsuperscriptTooltip: (shortcut: string) => `Superscript (${shortcut})`,\n\tsubscriptLabel: 'Subscript',\n\tsubscriptTooltip: (shortcut: string) => `Subscript (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<SuperSubLocale> = import.meta.glob<{\n\tdefault: SuperSubLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadSuperSubLocale(lang: string): Promise<SuperSubLocale> {\n\treturn loadLocaleModule(localeModules, lang, SUPER_SUB_LOCALE_EN);\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 type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.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 { dispatchIfPresent, resolveLocale, toCommandName } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { SUPER_SUB_LOCALE_EN, type SuperSubLocale, loadSuperSubLocale } from './SuperSubLocale.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\treadonly locale?: SuperSubLocale;\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' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\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\ticon: SUPERSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-.',\n\t\ttoHTMLString: (content) => `<sup>${content}</sup>`,\n\t\tparseHTML: [{ tag: 'sup' }],\n\t\tsanitize: { tags: ['sup'] },\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\ticon: SUBSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-,',\n\t\ttoHTMLString: (content) => `<sub>${content}</sub>`,\n\t\tparseHTML: [{ tag: 'sub' }],\n\t\tsanitize: { tags: ['sub'] },\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\tprivate locale!: SuperSubLocale;\n\n\tconstructor(config?: Partial<SuperSubConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSUPER_SUB_LOCALE_EN,\n\t\t\tloadSuperSubLocale,\n\t\t);\n\n\t\tconst enabledMarks: MarkDefinition[] = MARK_DEFINITIONS.filter(\n\t\t\t(def) => this.config[def.configKey],\n\t\t);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tthis.registerMark(context, def);\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): 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\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () =>\n\t\t\tdispatchIfPresent(context, toggleMark(context.getState(), mkType(def.type))),\n\t\t);\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string =\n\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\n\t\t\tconst tooltip: string =\n\t\t\t\tdef.type === 'superscript'\n\t\t\t\t\t? this.locale.superscriptTooltip(formatShortcut(def.keyBinding))\n\t\t\t\t\t: this.locale.subscriptTooltip(formatShortcut(def.keyBinding));\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,\n\t\t\t\ttooltip,\n\t\t\t\tcommand: commandName,\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(\n\t\t\t(tr, _state, next) => {\n\t\t\t\tlet patched = false;\n\n\t\t\t\t// Handle addMark steps: inject removeMark for the opposite type\n\t\t\t\tconst patchedSteps: Step[] = [];\n\t\t\t\tfor (const step of tr.steps) {\n\t\t\t\t\tif (step.type !== 'addMark') {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst markName: string = step.mark.type;\n\t\t\t\t\tconst def: MarkDefinition | undefined = MARK_DEFINITIONS.find((d) => d.type === markName);\n\t\t\t\t\tif (!def) {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tpatched = true;\n\t\t\t\t\tconst removeStep: RemoveMarkStep = {\n\t\t\t\t\t\ttype: 'removeMark',\n\t\t\t\t\t\tblockId: step.blockId,\n\t\t\t\t\t\tfrom: step.from,\n\t\t\t\t\t\tto: step.to,\n\t\t\t\t\t\tmark: { type: mkType(def.opposite) },\n\t\t\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tpatchedSteps.push(removeStep, step);\n\t\t\t\t}\n\n\t\t\t\t// Handle stored marks: remove the opposite mark\n\t\t\t\tlet storedMarksAfter: readonly Mark[] | null = tr.storedMarksAfter;\n\t\t\t\tif (storedMarksAfter) {\n\t\t\t\t\tconst hasSup: boolean = storedMarksAfter.some((m) => m.type === 'superscript');\n\t\t\t\t\tconst hasSub: boolean = storedMarksAfter.some((m) => m.type === 'subscript');\n\n\t\t\t\t\tif (hasSup && hasSub) {\n\t\t\t\t\t\t// Keep the one that was most recently added (last in array)\n\t\t\t\t\t\tconst lastSupIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'superscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst lastSubIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'subscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst removeType: string = lastSupIdx > lastSubIdx ? 'subscript' : 'superscript';\n\n\t\t\t\t\t\tstoredMarksAfter = storedMarksAfter.filter((m) => m.type !== removeType);\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnext(patched ? { ...tr, steps: patchedSteps, storedMarksAfter } : tr);\n\t\t\t},\n\t\t\t{ name: 'super-sub:exclusivity' },\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\tconst label: string =\n\t\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\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,\n\t\t\t\t\tcommand: toCommandName(def.type),\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(configKey: keyof Omit<SuperSubConfig, 'toolbar' | 'locale'>): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SuperSubPlugin-DVP7VnIz.mjs","names":[],"sources":["../../src/plugins/super-sub/SuperSubLocale.ts","../../src/plugins/super-sub/SuperSubPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the SuperSubPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface SuperSubLocale {\n\treadonly superscriptLabel: string;\n\treadonly superscriptTooltip: (shortcut: string) => string;\n\treadonly subscriptLabel: string;\n\treadonly subscriptTooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const SUPER_SUB_LOCALE_EN: SuperSubLocale = {\n\tsuperscriptLabel: 'Superscript',\n\tsuperscriptTooltip: (shortcut: string) => `Superscript (${shortcut})`,\n\tsubscriptLabel: 'Subscript',\n\tsubscriptTooltip: (shortcut: string) => `Subscript (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<SuperSubLocale> = import.meta.glob<{\n\tdefault: SuperSubLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadSuperSubLocale(lang: string): Promise<SuperSubLocale> {\n\treturn loadLocaleModule(localeModules, lang, SUPER_SUB_LOCALE_EN);\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 type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.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 { dispatchIfPresent, resolveLocale, toCommandName } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { SUPER_SUB_LOCALE_EN, type SuperSubLocale, loadSuperSubLocale } from './SuperSubLocale.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\treadonly locale?: SuperSubLocale;\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' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\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\ticon: SUPERSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-.',\n\t\ttoHTMLString: (content) => `<sup>${content}</sup>`,\n\t\tparseHTML: [{ tag: 'sup' }],\n\t\tsanitize: { tags: ['sup'] },\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\ticon: SUBSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-,',\n\t\ttoHTMLString: (content) => `<sub>${content}</sub>`,\n\t\tparseHTML: [{ tag: 'sub' }],\n\t\tsanitize: { tags: ['sub'] },\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\tprivate locale!: SuperSubLocale;\n\n\tconstructor(config?: Partial<SuperSubConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tSUPER_SUB_LOCALE_EN,\n\t\t\tloadSuperSubLocale,\n\t\t);\n\n\t\tconst enabledMarks: MarkDefinition[] = MARK_DEFINITIONS.filter(\n\t\t\t(def) => this.config[def.configKey],\n\t\t);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tthis.registerMark(context, def);\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): 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\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () =>\n\t\t\tdispatchIfPresent(context, toggleMark(context.getState(), mkType(def.type))),\n\t\t);\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string =\n\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\n\t\t\tconst tooltip: string =\n\t\t\t\tdef.type === 'superscript'\n\t\t\t\t\t? this.locale.superscriptTooltip(formatShortcut(def.keyBinding))\n\t\t\t\t\t: this.locale.subscriptTooltip(formatShortcut(def.keyBinding));\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,\n\t\t\t\ttooltip,\n\t\t\t\tcommand: commandName,\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(\n\t\t\t(tr, _state, next) => {\n\t\t\t\tlet patched = false;\n\n\t\t\t\t// Handle addMark steps: inject removeMark for the opposite type\n\t\t\t\tconst patchedSteps: Step[] = [];\n\t\t\t\tfor (const step of tr.steps) {\n\t\t\t\t\tif (step.type !== 'addMark') {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst markName: string = step.mark.type;\n\t\t\t\t\tconst def: MarkDefinition | undefined = MARK_DEFINITIONS.find((d) => d.type === markName);\n\t\t\t\t\tif (!def) {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tpatched = true;\n\t\t\t\t\tconst removeStep: RemoveMarkStep = {\n\t\t\t\t\t\ttype: 'removeMark',\n\t\t\t\t\t\tblockId: step.blockId,\n\t\t\t\t\t\tfrom: step.from,\n\t\t\t\t\t\tto: step.to,\n\t\t\t\t\t\tmark: { type: mkType(def.opposite) },\n\t\t\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tpatchedSteps.push(removeStep, step);\n\t\t\t\t}\n\n\t\t\t\t// Handle stored marks: remove the opposite mark\n\t\t\t\tlet storedMarksAfter: readonly Mark[] | null = tr.storedMarksAfter;\n\t\t\t\tif (storedMarksAfter) {\n\t\t\t\t\tconst hasSup: boolean = storedMarksAfter.some((m) => m.type === 'superscript');\n\t\t\t\t\tconst hasSub: boolean = storedMarksAfter.some((m) => m.type === 'subscript');\n\n\t\t\t\t\tif (hasSup && hasSub) {\n\t\t\t\t\t\t// Keep the one that was most recently added (last in array)\n\t\t\t\t\t\tconst lastSupIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'superscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst lastSubIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'subscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst removeType: string = lastSupIdx > lastSubIdx ? 'subscript' : 'superscript';\n\n\t\t\t\t\t\tstoredMarksAfter = storedMarksAfter.filter((m) => m.type !== removeType);\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnext(patched ? { ...tr, steps: patchedSteps, storedMarksAfter } : tr);\n\t\t\t},\n\t\t\t{ name: 'super-sub:exclusivity' },\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\tconst label: string =\n\t\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\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,\n\t\t\t\t\tcommand: toCommandName(def.type),\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(configKey: keyof Omit<SuperSubConfig, 'toolbar' | 'locale'>): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{c as t,d as e,i as n,o,p as r,u as l}from"./Document-r7vLOAGA.mjs";import{c as i,l as s,o as a,r as c,t as d,u}from"./Selection-HYoVFpAx.mjs";import{a as b}from"./TypeBrands-Ch9856Gb.mjs";import{r as p}from"./HTMLUtils-C6B4UT00.mjs";import{_ as h,s as m}from"./BlockInsertion-6rR9tIGP.mjs";import{i as f,t as v}from"./Decoration-ZeyVfwJB.mjs";import{a as g,o as x,s as w}from"./StyleRuntime-BAutwDZT.mjs";import{n as C}from"./TypedKeys-CA4bfw9O.mjs";import{a as I,i as y,s as k}from"./PluginHelpers-D4quRJ5a.mjs";import{t as S}from"./KeyboardNav-D0my3wuy.mjs";import{r as L}from"./PopupPositioning-DtUrY9bh.mjs";import{i as A}from"./ColorValidation-DAijTjG9.mjs";import{n as R,t as B}from"./ColorGrid-CXRdpP_n.mjs";function E(){const e=n(b("paragraph"),[t("")],l());return n(b("table_cell"),[e],l())}function T(t,n){const o=t.getNodePath(n);if(!o)return null;let r=null,l=null,i=null,s=null;for(const e of o){const n=t.getBlock(e);n&&("table"===n.type?(r=e,l=n):"table_row"===n.type?i=e:"table_cell"===n.type&&(s=e))}if("table_cell"===t.getBlock(n)?.type&&(s=n),!(r&&l&&s&&i))return null;const a=t.doc.children.findIndex(t=>t.id===r),c=e(l),d=c.findIndex(t=>t.id===i);if(-1===d)return null;const u=c[d];if(!u)return null;const b=e(u),p=b.findIndex(t=>t.id===s);if(-1===p)return null;const h=b.length,m=c.length;return{tableId:r,tableIndex:a,rowId:i,rowIndex:d,cellId:s,colIndex:p,totalRows:m,totalCols:h}}function M(t,n,o,r){const l=t.getBlock(n);if(!l)return null;const i=e(l)[o];return i?e(i)[r]?.id??null:null}function N(t,n){const o=t.getBlock(n);if(!o)return n;const r=e(o)[0];if(!r)return n;let l=r;for(;;){const t=e(l)[0];if(!t)return l.id;l=t}}function H(t,n){const o=t.getBlock(n);if(!o)return n;const r=e(o),l=r[r.length-1];if(!l)return n;let i=l;for(;;){const t=e(i),n=t[t.length-1];if(!n)return i.id;i=n}}function P(t,e){const n=t.getNodePath(e);if(!n)return!1;for(const o of n)if("table"===t.getBlock(o)?.type)return!0;return!1}var D={insertRowAbove:"Insert Row Above",insertRowBelow:"Insert Row Below",insertColumnLeft:"Insert Column Left",insertColumnRight:"Insert Column Right",deleteRow:"Delete Row",deleteColumn:"Delete Column",borderColorLabel:"Border Color...",deleteTable:"Delete Table",tableActions:"Table actions",menuKeyboardHint:"↑↓ Navigate · Enter Select · Esc Close",insertRow:"Insert row",insertColumn:"Insert column",addRow:"Add row",addColumn:"Add column",tableActionsHint:"Table actions (Right-click or Shift+F10)",contextMenuHint:"Right-click or Shift+F10 for table actions",borderColor:"Border color",defaultColor:"Default",noBorders:"No borders",borderColorPicker:"Border color picker",announceBorderColorSet:t=>`Table border color set to ${t}`,announceBorderReset:"Table borders reset to default",borderSwatchLabel:t=>`Border ${t}`,announceRowInsertedAbove:"Row inserted above",announceRowInsertedBelow:"Row inserted below",announceColumnInserted:t=>`Column inserted ${t}`,announceRowDeleted:"Row deleted",announceColumnDeleted:"Column deleted",announceTableDeleted:"Table deleted",insertTable:"Insert Table",tableAriaLabel:(t,e)=>`Table with ${t} rows and ${e} columns`,tableAriaDescription:"Right-click or press Shift+F10 for table actions"},z=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-jbplYWkC.mjs"),"./locales/de.ts":()=>import("./de-DN-e6G5A.mjs"),"./locales/es.ts":()=>import("./es-CM55WeEN.mjs"),"./locales/fr.ts":()=>import("./fr-C_2i5Ono.mjs"),"./locales/hi.ts":()=>import("./hi-C9fvG91d.mjs"),"./locales/pt.ts":()=>import("./pt-GqLw5tN0.mjs"),"./locales/ru.ts":()=>import("./ru-4g_qsaLr.mjs"),"./locales/zh.ts":()=>import("./zh-DeZP08HI.mjs")});async function $(t){return k(z,t,D)}var j=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#980000","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#0b5394","#38761d"];function _(t,e,n){const o=t.getBlock(e);if(!o||"table"!==o.type)return null;const r=t.getNodePath(e);if(!r)return null;if(void 0===n){const{borderColor:e,...n}=o.attrs??{},l=n;return t.transaction("command").setNodeAttr(r,l).setSelection(t.selection).build()}const l={...o.attrs,borderColor:n};return t.transaction("command").setNodeAttr(r,l).setSelection(t.selection).build()}function V(t,e,n=D){const o=t.getState();if(!u(o.selection))return!1;const r=T(o,o.selection.anchor.blockId);if(!r)return!1;const l=_(o,r.tableId,e);if(!l)return!1;t.dispatch(l);const i="none"===e?"none":R(e);return t.announce(n.announceBorderColorSet(i)),!0}function O(t,e=D){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=_(n,o.tableId,void 0);return!!r&&(t.dispatch(r),t.announce(e.announceBorderReset),!0)}function F(t,e){const n=t.getBlock(e);if(n)return n.attrs?.borderColor}function q(t,e,n,o,r=D){t.classList.add("notectl-color-picker");const l=F(e.getState(),n),i=document.createElement("button");i.type="button",i.className="notectl-color-picker__default",i.textContent=r.defaultColor,i.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),O(e,r),o()}),i.addEventListener("keydown",t=>{"Escape"===t.key&&(t.preventDefault(),o())}),t.appendChild(i);const s=document.createElement("button");s.type="button",s.className="notectl-color-picker__default",s.textContent=r.noBorders,s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),V(e,"none",r),o()}),s.addEventListener("keydown",t=>{"Escape"===t.key&&(t.preventDefault(),o())}),t.appendChild(s),B(t,{colors:j,columns:5,ariaLabel:r.borderColorPicker,ariaLabelPrefix:"",activeColor:l??null,swatchLabel:r.borderSwatchLabel,titleAsName:!0,onSelect:t=>{V(e,t,r),o()},onClose:o})}function Z(t,o,r){const i=t.getBlock(o);if(!i)return null;const s=e(i),a=s[0]?e(s[0]).length:0;if(0===a)return null;const c=function(t){const e=[];for(let n=0;n<t;n++)e.push(E());return n(b("table_row"),e,l())}(a),u=t.transaction("command").insertNode([o],r,c),p=e(c)[0],h=p?e(p)[0]:void 0;return h?u.setSelection(d(h.id,0)):p&&u.setSelection(d(p.id,0)),u.build()}function K(t,n,o){const r=t.getBlock(n);if(!r)return null;const l=e(r),i=t.transaction("command");for(const e of l){const t=E();i.insertNode([n,e.id],o,t)}return i.setSelection(t.selection),i.build()}function Y(t,n,o,r=0){const l=t.getBlock(n);if(!l)return null;if(e(l).length<=1)return W(t,n);const i=t.transaction("command").removeNode([n],o),s=M(t,n,o>0?o-1:1,r);if(s){const e=N(t,s);i.setSelection(d(e,0))}return i.build()}function X(t,n,o,r=0){const l=t.getBlock(n);if(!l)return null;const i=e(l);if((i[0]?e(i[0]).length:0)<=1)return W(t,n);const s=t.transaction("command");for(let e=i.length-1;e>=0;e--){const t=i[e];t&&s.removeNode([n,t.id],o)}const a=M(t,n,r,o>0?o-1:1);if(a){const e=N(t,a);s.setSelection(d(e,0))}return s.build()}function W(t,e){const n=t.doc.children.findIndex(t=>t.id===e);if(-1===n)return null;if(1===t.doc.children.length){const e=o(l());return t.transaction("command").insertNode([],0,e).removeNode([],1).setSelection(d(e.id,0)).build()}const r=t.transaction("command").removeNode([],n),i=t.doc.children[n+1];if(i){const e=h(t,i.id,"start");if(e)return r.setSelection(e),r.build()}const s=t.doc.children[n-1];if(s){const e=h(t,s.id,"end");if(e)return r.setSelection(e),r.build()}return null}function U(t,o,r){const i=t.getState(),s=y(i);if(!s)return!1;const a=function(t,e){const o=l(),r=[];for(let i=0;i<t;i++){const t=[];for(let n=0;n<e;n++)t.push(E());r.push(n(b("table_row"),t,l()))}return n(b("table"),r,o)}(o,r),c=i.transaction("command");if(!m(i,c,s,a))return!1;const u=e(a)[0],p=u?e(u)[0]:void 0,h=p?e(p)[0]:void 0;return h?c.setSelection(d(h.id,0)):p&&c.setSelection(d(p.id,0)),t.dispatch(c.build()),!0}function G(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Z(n,o.tableId,o.rowIndex+1);return!!r&&(t.dispatch(r),t.announce(e.announceRowInsertedBelow),!0)}function Q(t,e,n){const o=t.getState();if(!u(o.selection))return!1;const r=T(o,o.selection.anchor.blockId);if(!r)return!1;const l="left"===e?r.colIndex:r.colIndex+1,i=K(o,r.tableId,l);return!!i&&(t.dispatch(i),t.announce(n.announceColumnInserted(e)),!0)}function J(t,e){t.registerCommand("insertTable",()=>U(t,3,3)),t.registerCommand("addRowAbove",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Z(n,o.tableId,o.rowIndex);return!!r&&(t.dispatch(r),t.announce(e.announceRowInsertedAbove),!0)}(t,e)),t.registerCommand("addRowBelow",()=>G(t,e)),t.registerCommand("addColumnLeft",()=>function(t,e){return Q(t,"left",e)}(t,e)),t.registerCommand("addColumnRight",()=>function(t,e){return Q(t,"right",e)}(t,e)),t.registerCommand("deleteRow",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Y(n,o.tableId,o.rowIndex,o.colIndex);return!!r&&(t.dispatch(r),t.announce(e.announceRowDeleted),!0)}(t,e)),t.registerCommand("deleteColumn",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=X(n,o.tableId,o.colIndex,o.rowIndex);return!!r&&(t.dispatch(r),t.announce(e.announceColumnDeleted),!0)}(t,e)),t.registerCommand("selectTable",()=>function(t){const e=t.getState(),n=e.selection;if(s(n))return"table"===e.getBlock(n.nodeId)?.type;if(i(n))return!1;const o=T(e,n.anchor.blockId);if(!o)return!1;const r=e.getNodePath(o.tableId);if(!r)return!1;const l=e.transaction("command").setSelection(c(o.tableId,r)).build();return t.dispatch(l),!0}(t)),t.registerCommand("deleteTable",()=>function(t,e){const n=t.getState(),o=function(t){if(s(t.selection)){const e=t.getBlock(t.selection.nodeId);return"table"!==e?.type?null:{tableId:e.id}}if(i(t.selection))return null;const e=T(t,t.selection.anchor.blockId);return e?{tableId:e.tableId}:null}(n);if(!o)return!1;const r=W(n,o.tableId);return!!r&&(t.dispatch(r),t.announce(e.announceTableDeleted),!0)}(t,e))}function tt(t,e,n,o,r,l=D,i){let s=!0,a=null,c=null;const d=document.createElement("div");d.className="notectl-table-context-menu",d.setAttribute("role","menu"),d.setAttribute("aria-label",l.tableActions),d.setAttribute("contenteditable","false");const u=[];let b=0;const p=function(t){return[{type:"item",label:t.insertRowAbove,command:"addRowAbove"},{type:"item",label:t.insertRowBelow,command:"addRowBelow"},{type:"separator"},{type:"item",label:t.insertColumnLeft,command:"addColumnLeft"},{type:"item",label:t.insertColumnRight,command:"addColumnRight"},{type:"separator"},{type:"item",label:t.deleteRow,command:"deleteRow"},{type:"item",label:t.deleteColumn,command:"deleteColumn"},{type:"separator"},{type:"submenu",label:t.borderColorLabel,id:"borderColor"},{type:"separator"},{type:"item",label:t.deleteTable,command:"deleteTable"}]}(l);for(const I of p){if("separator"===I.type){const t=document.createElement("div");t.setAttribute("role","separator"),d.appendChild(t);continue}const t=document.createElement("button");t.type="button",t.setAttribute("role","menuitem"),t.textContent=I.label,"submenu"===I.type&&(t.dataset.submenu=I.id,t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false")),"item"===I.type&&(t.dataset.command=I.command),t.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),t.addEventListener("click",n=>{n.stopPropagation(),"item"===I.type?(e.executeCommand(I.command),C()):"submenu"===I.type&&m(t)}),u.push(t),d.appendChild(t)}const h=document.createElement("div");function m(o){if(f(),o.setAttribute("aria-expanded","true"),i)c=i.open({anchor:o,position:"right",referenceNode:d,parent:{close:()=>C(),getElement:()=>d},onClose:()=>{c=null,a=null,v()},content:(t,r)=>{t.className="notectl-table-context-menu",t.setAttribute("contenteditable","false"),a=t,t.addEventListener("keydown",t=>{t.stopPropagation();const e="rtl"===getComputedStyle(d).direction?"ArrowRight":"ArrowLeft";t.key===e&&(t.preventDefault(),r(),o.focus())}),q(t,e,n,()=>C(),l)}});else{a=document.createElement("div"),a.className="notectl-table-context-menu",a.setAttribute("contenteditable","false"),a.addEventListener("keydown",t=>{t.stopPropagation();const e="rtl"===getComputedStyle(d).direction?"ArrowRight":"ArrowLeft";t.key===e&&(t.preventDefault(),f(),o.focus())}),q(a,e,n,()=>C(),l),t.appendChild(a);const r=d.getBoundingClientRect(),i="rtl"===getComputedStyle(d).direction;L(a,r,{position:"right",isRtl:i}),requestAnimationFrame(()=>{(a?.querySelector("button"))?.focus()})}}function f(){c?(c.close(),c=null,a=null):a&&(a.remove(),a=null),v()}function v(){for(const t of u)t.dataset.submenu&&t.setAttribute("aria-expanded","false")}h.className="notectl-table-context-menu__hint",h.setAttribute("aria-hidden","true"),h.textContent=l.menuKeyboardHint,d.appendChild(h),S(u,b),d.addEventListener("keydown",t=>{switch(t.stopPropagation(),t.key){case"Escape":return t.preventDefault(),void C();case"ArrowDown":return t.preventDefault(),b=(b+1)%u.length,S(u,b),void u[b]?.focus();case"ArrowUp":return t.preventDefault(),b=(b-1+u.length)%u.length,S(u,b),void u[b]?.focus();case"ArrowRight":case"ArrowLeft":{t.preventDefault();const e="rtl"===getComputedStyle(d).direction?"ArrowLeft":"ArrowRight";if(t.key===e){const t=u[b];t?.dataset.submenu&&m(t)}else f(),u[b]?.focus();return}case"Enter":case" ":{t.preventDefault();const n=u[b];if(!n)return;return void(n.dataset.submenu?m(n):n.dataset.command&&(e.executeCommand(n.dataset.command),C()))}case"Home":return t.preventDefault(),b=0,S(u,b),void u[b]?.focus();case"End":return t.preventDefault(),b=u.length-1,S(u,b),void u[b]?.focus()}}),L(d,o,{position:"below-start"}),t.appendChild(d),u[0]?.focus(),requestAnimationFrame(()=>{s&&u[0]&&u[0].focus()});const g=t=>{const e=t.composedPath();e.includes(d)||a&&e.includes(a)||C()};let x=null,w=!1;function C(){s&&(s=!1,f(),d.remove(),null!==x&&(clearTimeout(x),x=null),w&&(document.removeEventListener("mousedown",g,!0),w=!1),r?.())}return x=setTimeout(()=>{x=null,document.addEventListener("mousedown",g,!0),w=!0},0),{isOpen:()=>s,close:C,destroy:C}}var et=null;function nt(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=n.selection,r=T(n,o.anchor.blockId);return!!r&&e(n,o,r)}function ot(t){return nt(t,(e,n,o)=>{const r=o.tableIndex+1;if(r>=e.doc.children.length)return!1;const l=e.doc.children[r];if(!l)return!1;const i=e.transaction("command").setSelection(d(l.id,0)).build();return t.dispatch(i),!0})}function rt(t,e,n,o){const r=t.getState(),l=M(r,e,n,o);if(!l)return!1;const i=N(r,l),s=r.transaction("command").setSelection(d(i,0)).build();return t.dispatch(s),!0}function lt(t,e,n,o){const l=t.getState(),i=M(l,e,n,o);if(!i)return!1;const s=H(l,i),a=l.getBlock(s);if(!a)return!1;const c=r(a),u=l.transaction("command").setSelection(d(s,c)).build();return t.dispatch(u),!0}function it(t,e){const n=t.getState(),o=n.getNodePath(e);if(!o)return!1;const r=n.transaction("input").setSelection(c(e,o)).build();return t.dispatch(r),!0}var st='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M6 1v10M1 6h10" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>';function at(t,e,n){const o=document.createElement("button");return o.className=t,o.innerHTML=e,o.title=n,o.type="button",o.setAttribute("aria-label",n),o.setAttribute("contenteditable","false"),o.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),o}function ct(t,e){const n=document.createElement("div");n.className=`ntbl-insert-line ntbl-insert-line--${t}`,n.setAttribute("contenteditable","false"),n.setAttribute("data-notectl-no-print","");const o=at("ntbl-insert-btn",st,e);return n.appendChild(o),n}function dt(t,e){const n=document.createElement("button");n.className=`ntbl-add-zone ${t}`,n.type="button",n.setAttribute("contenteditable","false"),n.setAttribute("aria-label",e),n.setAttribute("data-notectl-no-print",""),n.title=e;const o=document.createElement("span");return o.className="ntbl-add-icon",o.innerHTML=st,n.appendChild(o),n.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),n}function ut(t){const e=document.createElement("div");return e.className=t,e.setAttribute("contenteditable","false"),e.setAttribute("data-notectl-no-print",""),e}function bt(t,e){x(t,"none"===e?{backgroundColor:"transparent",border:"1px dashed rgba(128,128,128,0.4)"}:e?{backgroundColor:e,border:"1px solid rgba(0,0,0,0.15)"}:{backgroundColor:"var(--notectl-border)",border:"1px solid rgba(0,0,0,0.15)"})}function pt(t,e,n,o){const r=document.createElement("div");r.className=`ntbl-handle ${t}`,r.dataset.index=String(e);const l=at("ntbl-handle-delete",'<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M2 2l6 6M8 2l-6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',n);return l.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),o(e)}),r.appendChild(l),r}function ht(t,e){let n=0,o=0,r=t;for(;r&&r!==e;)n+=r.offsetTop,o+=r.offsetLeft,r=r.offsetParent;return{top:n,left:o}}var mt=class{tableId;numRows;numCols;activeRowIndex=-1;activeColIndex=-1;colBar;rowBar;insertLineH;insertLineV;addRowZone;addColZone;deleteTableBtn;borderColorBtn;actionsBtn;contextHint;observer;borderColorPopup=null;activeContextMenu=null;container;tableEl;getState;dispatchFn;pluginContext;locale;onMouseMove=t=>{const e=this.tableEl.getBoundingClientRect(),n=t.clientX-e.left,o=t.clientY-e.top;if(!(n>=-10&&n<=e.width+10&&o>=-10&&o<=e.height+10))return void this.hideInsertLines();const r=function(t,e,n,o){let r=Number.POSITIVE_INFINITY,l=null;for(const a of n){const t=Math.abs(e-a.position);t<r&&t<10&&(r=t,l=a)}let i=Number.POSITIVE_INFINITY,s=null;for(const a of o){const e=Math.abs(t-a.position);e<i&&e<10&&(i=e,s=a)}return l&&(!s||r<=i)?{type:"row",border:l}:s?{type:"col",border:s}:{type:"none",border:null}}(n,o,function(t){const e=t.querySelectorAll(":scope > tbody > tr"),n=t.offsetTop,o=[];for(let r=1;r<e.length;r++){const t=e[r];t&&o.push({position:t.offsetTop-n,index:r})}return o}(this.tableEl),function(t,e){if(e<=1)return[];const n=t/e,o=[];for(let r=1;r<e;r++)o.push({position:Math.round(n*r),index:r});return o}(this.tableEl.offsetWidth,this.numCols));"row"===r.type&&r.border?(this.showHorizontalLine(r.border),this.hideVerticalLine()):"col"===r.type&&r.border?(this.showVerticalLine(r.border),this.hideHorizontalLine()):this.hideInsertLines()};onMouseLeave=()=>{this.hideInsertLines()};constructor(t,n,o,r,l,i,s=D){if(this.container=t,this.tableEl=n,this.getState=r,this.dispatchFn=l,this.pluginContext=i??null,this.locale=s,this.tableId=o.id,this.numRows=e(o).length,this.numCols=this.countCols(o),this.colBar=ut("ntbl-col-bar"),this.rowBar=ut("ntbl-row-bar"),this.insertLineH=ct("horizontal",s.insertRow),this.insertLineV=ct("vertical",s.insertColumn),this.addRowZone=dt("ntbl-add-row",s.addRow),this.addColZone=dt("ntbl-add-col",s.addColumn),this.deleteTableBtn=at("ntbl-delete-table-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M9 3h6m-9 4h12M10 11v6m4-6v6m-9 3h14l-1-13H6L5 20z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>',s.deleteTable),this.deleteTableBtn.setAttribute("data-notectl-no-print",""),i){const t=F(r(),this.tableId);this.borderColorBtn=function(t,e){const n=at("ntbl-border-color-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M3 3h18v18H3V3zm0 6h18M3 15h18M9 3v18M15 3v18" stroke="currentColor" stroke-width="1.5"/></svg>',t);n.setAttribute("data-notectl-no-print","");const o=document.createElement("span");return o.className="ntbl-border-color-swatch",bt(o,e),n.appendChild(o),n}(s.borderColor,t),this.actionsBtn=function(t){const e=at("ntbl-actions-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="12" cy="19" r="2"/></svg>',t);return e.setAttribute("data-notectl-no-print",""),e}(s.tableActionsHint)}else this.borderColorBtn=null,this.actionsBtn=null;t.append(this.colBar,this.rowBar,this.insertLineH,this.insertLineV,this.addRowZone,this.addColZone,this.deleteTableBtn),this.borderColorBtn&&t.appendChild(this.borderColorBtn),this.actionsBtn&&t.appendChild(this.actionsBtn),this.contextHint=function(t){const e=document.createElement("div");return e.className="ntbl-context-hint",e.setAttribute("aria-hidden","true"),e.setAttribute("contenteditable","false"),e.setAttribute("data-notectl-no-print",""),e.textContent=t,e}(s.contextMenuHint),t.appendChild(this.contextHint),this.rebuildColHandles(),this.rebuildRowHandles(),this.bindEventListeners(),this.observer=new ResizeObserver(()=>{this.positionControls()}),this.observer.observe(n),requestAnimationFrame(()=>this.positionControls())}update(t){this.tableId=t.id;const n=e(t).length,o=this.countCols(t);if(n===this.numRows&&o===this.numCols||(this.numRows=n,this.numCols=o,this.rebuildColHandles(),this.rebuildRowHandles()),this.borderColorBtn){const e=this.borderColorBtn.querySelector(".ntbl-border-color-swatch");if(e){const n=t.attrs?.borderColor;bt(e,n)}}requestAnimationFrame(()=>this.positionControls())}destroy(){this.activeContextMenu?.destroy(),this.closeBorderColorPopup(),this.observer.disconnect(),this.container.removeEventListener("mousemove",this.onMouseMove),this.container.removeEventListener("mouseleave",this.onMouseLeave),this.colBar.remove(),this.rowBar.remove(),this.insertLineH.remove(),this.insertLineV.remove(),this.addRowZone.remove(),this.addColZone.remove(),this.deleteTableBtn.remove(),this.borderColorBtn?.remove(),this.actionsBtn?.remove(),this.contextHint.remove()}bindEventListeners(){const t=this.insertLineH.querySelector(".ntbl-insert-btn"),e=this.insertLineV.querySelector(".ntbl-insert-btn");if(t.addEventListener("click",()=>{this.activeRowIndex>=0&&this.dispatchTransaction(Z(this.getState(),this.tableId,this.activeRowIndex))}),e.addEventListener("click",()=>{this.activeColIndex>=0&&this.dispatchTransaction(K(this.getState(),this.tableId,this.activeColIndex))}),this.addRowZone.addEventListener("click",()=>{this.dispatchTransaction(Z(this.getState(),this.tableId,this.numRows))}),this.addColZone.addEventListener("click",()=>{this.dispatchTransaction(K(this.getState(),this.tableId,this.numCols))}),this.deleteTableBtn.addEventListener("click",()=>{this.dispatchTransaction(W(this.getState(),this.tableId))}),this.borderColorBtn&&this.pluginContext){const t=this.pluginContext;this.borderColorBtn.addEventListener("click",()=>{this.toggleBorderColorPopup(t)})}if(this.actionsBtn&&this.pluginContext){const t=this.pluginContext;this.actionsBtn.addEventListener("click",()=>{this.openActionsMenu(t)})}this.container.addEventListener("mousemove",this.onMouseMove),this.container.addEventListener("mouseleave",this.onMouseLeave)}openActionsMenu(t){if(this.activeContextMenu?.isOpen())return this.activeContextMenu.close(),void(this.activeContextMenu=null);if(!this.actionsBtn)return;const e=this.actionsBtn.getBoundingClientRect(),n=new DOMRect(e.left,e.bottom+4,0,0);this.activeContextMenu=tt(this.container,t,this.tableId,n,()=>{this.activeContextMenu=null},this.locale)}toggleBorderColorPopup(t){this.borderColorPopup?this.closeBorderColorPopup():(this.borderColorPopup=document.createElement("div"),this.borderColorPopup.className="notectl-table-context-menu",x(this.borderColorPopup,{position:"absolute",top:"24px",left:"24px",zIndex:"10000"}),this.borderColorPopup.setAttribute("contenteditable","false"),q(this.borderColorPopup,t,this.tableId,()=>{this.closeBorderColorPopup()},this.locale),this.container.appendChild(this.borderColorPopup))}closeBorderColorPopup(){this.borderColorPopup&&(this.borderColorPopup.remove(),this.borderColorPopup=null)}dispatchTransaction(t){t&&this.dispatchFn(t)}countCols(t){const n=e(t);return n[0]?e(n[0]).length:0}positionControls(){!function(t,e,n){const o=t.children;if(0===o.length)return;const r=e/n;for(let l=0;l<o.length;l++){const t=o[l];x(t,{left:`${Math.round(r*l)}px`,width:`${Math.round(r)}px`})}w(t,"width",`${e}px`)}(this.colBar,this.tableEl.offsetWidth,this.numCols),function(t,e){const n=t.children;if(0===n.length)return;const o=e.querySelectorAll(":scope > tbody > tr"),r=e.offsetTop;let l=0;for(let i=0;i<n.length;i++){const t=n[i],e=o[i];if(e){const n=e.offsetTop-r,o=e.offsetHeight;x(t,{top:`${n}px`,height:`${o}px`}),l=n+o}}w(t,"height",`${l}px`)}(this.rowBar,this.tableEl),function(t,e,n,o){const r=ht(n,o),l=n.offsetHeight,i=n.offsetWidth;x(t,{width:`${i}px`,left:`${r.left}px`}),x(e,{height:`${l}px`,top:`${r.top}px`})}(this.addRowZone,this.addColZone,this.tableEl,this.container)}showHorizontalLine(t){this.activeRowIndex=t.index;const e=ht(this.tableEl,this.container);x(this.insertLineH,{top:e.top+t.position-1+"px",left:`${e.left}px`,width:`${this.tableEl.offsetWidth}px`}),this.insertLineH.classList.add("ntbl-insert-line--visible")}showVerticalLine(t){this.activeColIndex=t.index;const e=ht(this.tableEl,this.container);x(this.insertLineV,{left:e.left+t.position-1+"px",top:`${e.top}px`,height:`${this.tableEl.offsetHeight}px`}),this.insertLineV.classList.add("ntbl-insert-line--visible")}hideInsertLines(){this.hideHorizontalLine(),this.hideVerticalLine()}hideHorizontalLine(){this.insertLineH.classList.remove("ntbl-insert-line--visible"),this.activeRowIndex=-1}hideVerticalLine(){this.insertLineV.classList.remove("ntbl-insert-line--visible"),this.activeColIndex=-1}rebuildColHandles(){this.colBar.innerHTML="";for(let t=0;t<this.numCols;t++){const e=pt("ntbl-col-handle",t,this.locale.deleteColumn,t=>{this.dispatchTransaction(X(this.getState(),this.tableId,t))});this.colBar.appendChild(e)}}rebuildRowHandles(){this.rowBar.innerHTML="";for(let t=0;t<this.numRows;t++){const e=pt("ntbl-row-handle",t,this.locale.deleteRow,t=>{this.dispatchTransaction(Y(this.getState(),this.tableId,t))});this.rowBar.appendChild(e)}}};function ft(t,e){"none"===e?(w(t,"--ntbl-border-color","transparent"),t.classList.add("notectl-table--borderless")):e?(w(t,"--ntbl-border-color",e),t.classList.remove("notectl-table--borderless")):(g(t,"--ntbl-border-color"),t.classList.remove("notectl-table--borderless"))}var vt=new C("tableSelection"),gt={maxPickerRows:8,maxPickerCols:8},xt="border-collapse: collapse; width: 100%; table-layout: fixed",wt="border: 1px solid var(--ntbl-bc, #d0d0d0); padding: 8px 12px; vertical-align: top",Ct=class{id="table";name="Table";priority=40;config;locale;selectionService=null;cleanupMouseSelection=null;context=null;constructor(t){this.config={...gt,...t}}async init(t){this.locale=await I(t,this.config.locale,D,$),t.registerStyleSheet('\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/* Border resolution order: per-table local override → theme component token → theme global token.\n * The inline --ntbl-border-color is set by the toolbar\'s "border color" action and must win\n * over the theme so per-table customizations remain visible after a theme switch.\n */\n.notectl-table td {\n\tborder: 1px solid var(--ntbl-border-color, var(--notectl-table-border, var(--notectl-border)));\n\tbackground: var(--notectl-table-cell-bg, transparent);\n\tpadding: 8px 12px;\n\tmin-width: 60px;\n\tvertical-align: top;\n\tmin-height: 1.6em;\n}\n\n.notectl-table th {\n\tborder: 1px solid var(--ntbl-border-color, var(--notectl-table-border, var(--notectl-border)));\n\tbackground: var(--notectl-table-header-bg, var(--notectl-surface-raised));\n\tpadding: 8px 12px;\n\tmin-width: 60px;\n\tvertical-align: top;\n\ttext-align: start;\n\tfont-weight: 600;\n}\n\n.notectl-table--borderless td {\n\tborder: 1px dashed rgba(128, 128, 128, 0.15);\n}\n\n@media print {\n\t.notectl-table--borderless td {\n\t\tborder: none;\n\t}\n}\n\n.notectl-table td:focus-within {\n\toutline: 2px solid var(--notectl-primary);\n\toutline-offset: -2px;\n}\n\n.notectl-table-cell--selected {\n\tbackground: var(--notectl-primary-muted);\n}\n\n/* Table Context Menu */\n.notectl-table-context-menu {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\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: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tfont-family: inherit;\n}\n\n.notectl-table-context-menu button:hover {\n\tbackground: var(--notectl-hover-bg);\n}\n\n.notectl-table-context-menu hr {\n\tborder: none;\n\tborder-top: 1px solid var(--notectl-border);\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-block-start: 24px;\n\tpadding-inline-start: 24px;\n}\n\n.ntbl-container .notectl-table-wrapper {\n\tmargin: 0;\n}\n\n.ntbl-container.notectl-table--selected .notectl-table-wrapper {\n\toutline: 2px solid var(--notectl-primary-fg);\n\toutline-offset: 2px;\n\tborder-radius: 6px;\n}\n\n/* --- Column Handle Bar --- */\n.ntbl-col-bar {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 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.ntbl-container:focus-within .ntbl-col-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.ntbl-container.notectl-table--selected .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\tinset-inline-start: 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.ntbl-container:focus-within .ntbl-row-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.ntbl-container.notectl-table--selected .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: var(--notectl-hover-bg);\n\tborder-radius: 4px 4px 0 0;\n}\n\n.ntbl-col-handle:hover {\n\tbackground: var(--notectl-border);\n}\n\n.ntbl-row-handle {\n\twidth: 100%;\n\tbackground: var(--notectl-hover-bg);\n\tborder-start-start-radius: 4px;\n\tborder-end-start-radius: 4px;\n}\n\n.ntbl-row-handle:hover {\n\tbackground: var(--notectl-border);\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: var(--notectl-fg-muted);\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.ntbl-handle:focus-within .ntbl-handle-delete {\n\topacity: 1;\n\ttransform: scale(1);\n}\n\n.ntbl-handle-delete:hover,\n.ntbl-handle-delete:focus-visible {\n\tbackground: var(--notectl-danger-muted);\n\tcolor: var(--notectl-danger);\n}\n\n.ntbl-handle-delete:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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\tvar(--notectl-primary) 8%,\n\t\tvar(--notectl-primary) 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px var(--notectl-focus-ring);\n}\n\n.ntbl-insert-line--vertical {\n\twidth: 2px;\n\tbackground: linear-gradient(\n\t\t180deg,\n\t\ttransparent,\n\t\tvar(--notectl-primary) 8%,\n\t\tvar(--notectl-primary) 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px var(--notectl-focus-ring);\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: var(--notectl-surface-raised);\n\tborder: 2px solid var(--notectl-primary);\n\tcolor: var(--notectl-primary);\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 var(--notectl-focus-ring);\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\tinset-inline-start: -9px;\n\ttransform: translateY(-50%);\n}\n\n.ntbl-insert-btn:hover,\n.ntbl-insert-btn:focus-visible {\n\tbackground: var(--notectl-primary);\n\tcolor: var(--notectl-primary-fg);\n\tbox-shadow: 0 2px 12px var(--notectl-focus-ring);\n}\n\n.ntbl-insert-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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.ntbl-container:focus-within .ntbl-add-zone {\n\topacity: 1;\n}\n\n.ntbl-container.notectl-table--selected .ntbl-add-zone {\n\topacity: 1;\n}\n\n.ntbl-delete-table-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 0;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-danger);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-danger);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n}\n\n.ntbl-container:hover .ntbl-delete-table-btn,\n.ntbl-container:focus-within .ntbl-delete-table-btn,\n.ntbl-container.notectl-table--selected .ntbl-delete-table-btn {\n\topacity: 1;\n}\n\n.ntbl-delete-table-btn:hover,\n.ntbl-delete-table-btn:focus-visible {\n\tbackground: var(--notectl-danger-muted);\n\tborder-color: var(--notectl-danger);\n}\n\n.ntbl-delete-table-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n/* --- Context Menu Discovery Hint --- */\n.ntbl-context-hint {\n\tposition: absolute;\n\ttop: 4px;\n\tinset-inline-end: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tpadding: 2px 8px;\n\tborder-radius: 4px;\n\topacity: 0;\n\ttransition: opacity 0.2s ease;\n\tpointer-events: none;\n\twhite-space: nowrap;\n\tz-index: 5;\n}\n\n.ntbl-container:hover .ntbl-context-hint,\n.ntbl-container:focus-within .ntbl-context-hint,\n.ntbl-container.notectl-table--selected .ntbl-context-hint {\n\topacity: 1;\n}\n\n/* --- Table Actions Button --- */\n.ntbl-actions-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 48px;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg-muted);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n\tcursor: pointer;\n\tpadding: 0;\n}\n\n.ntbl-container:hover .ntbl-actions-btn,\n.ntbl-container:focus-within .ntbl-actions-btn,\n.ntbl-container.notectl-table--selected .ntbl-actions-btn {\n\topacity: 1;\n}\n\n.ntbl-actions-btn:hover,\n.ntbl-actions-btn:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\tborder-color: var(--notectl-primary);\n}\n\n.ntbl-actions-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n/* --- Border Color Button --- */\n.ntbl-border-color-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 24px;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg-muted);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n\tcursor: pointer;\n\tpadding: 0;\n}\n\n.ntbl-container:hover .ntbl-border-color-btn,\n.ntbl-container:focus-within .ntbl-border-color-btn,\n.ntbl-container.notectl-table--selected .ntbl-border-color-btn {\n\topacity: 1;\n}\n\n.ntbl-border-color-btn:hover,\n.ntbl-border-color-btn:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\tborder-color: var(--notectl-primary);\n}\n\n.ntbl-border-color-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.ntbl-border-color-swatch {\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 2px;\n\tborder: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n/* --- Context Menu Keyboard Hint --- */\n.notectl-table-context-menu__hint {\n\tpadding: 4px 12px 6px;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tborder-top: 1px solid var(--notectl-border);\n\tmargin-top: 4px;\n\ttext-align: center;\n\tuser-select: none;\n}\n\n/* --- Context Menu Focus --- */\n.notectl-table-context-menu button:focus-visible {\n\toutline: none;\n\tbackground: var(--notectl-primary-muted);\n\tbox-shadow: inset 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.notectl-table-context-menu [role="separator"] {\n\tborder: none;\n\tborder-top: 1px solid var(--notectl-border);\n\tmargin: 4px 0;\n\theight: 0;\n}\n\n.ntbl-add-row {\n\tbottom: 0;\n\theight: 24px;\n\tborder: 1px dashed var(--notectl-border);\n\tborder-end-start-radius: 6px;\n\tborder-end-end-radius: 6px;\n\tborder-block-start: none;\n\tcolor: var(--notectl-fg-muted);\n\ttransform: translateY(100%);\n}\n\n.ntbl-add-row:hover,\n.ntbl-add-row:focus-visible {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n\tcolor: var(--notectl-primary);\n}\n\n.ntbl-add-row:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.ntbl-add-col {\n\tinset-inline-end: 0;\n\ttop: 24px;\n\twidth: 24px;\n\tborder: 1px dashed var(--notectl-border);\n\tborder-start-end-radius: 6px;\n\tborder-end-end-radius: 6px;\n\tborder-inline-start: none;\n\tcolor: var(--notectl-fg-muted);\n\ttransform: translateX(100%);\n}\n\n[dir="rtl"] .ntbl-add-col {\n\ttransform: translateX(-100%);\n}\n\n.ntbl-add-col:hover,\n.ntbl-add-col:focus-visible {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n\tcolor: var(--notectl-primary);\n}\n\n.ntbl-add-col:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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'),this.context=t,this.registerNodeSpecs(t),this.registerNodeViews(t),J(t,this.locale),t.registerCommand("resetTableBorderColor",()=>O(t,this.locale)),function(t,e){t.registerKeymap({Tab:()=>function(t,e){return nt(t,(n,o,r)=>r.colIndex<r.totalCols-1?rt(t,r.tableId,r.rowIndex,r.colIndex+1):r.rowIndex<r.totalRows-1?rt(t,r.tableId,r.rowIndex+1,0):(G(t,e),!0))}(t,e),"Shift-Tab":()=>function(t){return nt(t,(e,n,o)=>o.colIndex>0?rt(t,o.tableId,o.rowIndex,o.colIndex-1):!(o.rowIndex>0)||rt(t,o.tableId,o.rowIndex-1,o.totalCols-1))}(t),Backspace:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;if(0!==n.anchor.offset)return!1;if(0!==o.rowIndex||0!==o.colIndex)return!1;const r=N(e,o.cellId);return n.anchor.blockId===r&&it(t,o.tableId)})}(t),Delete:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;const l=e.getBlock(n.anchor.blockId);if(!l)return!1;const i=r(l);if(n.anchor.offset!==i)return!1;if(o.rowIndex!==o.totalRows-1||o.colIndex!==o.totalCols-1)return!1;const s=H(e,o.cellId);return n.anchor.blockId===s&&it(t,o.tableId)})}(t),ArrowDown:()=>function(t){return nt(t,(e,n,o)=>{const r=H(e,o.cellId);return n.anchor.blockId===r&&(o.rowIndex>=o.totalRows-1?ot(t):rt(t,o.tableId,o.rowIndex+1,o.colIndex))})}(t),ArrowUp:()=>function(t){return nt(t,(e,n,o)=>{const r=N(e,o.cellId);return n.anchor.blockId===r&&!(o.rowIndex<=0)&&rt(t,o.tableId,o.rowIndex-1,o.colIndex)})}(t),ArrowRight:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;const l=e.getBlock(n.anchor.blockId);if(!l)return!1;const i=r(l);if(n.anchor.offset!==i)return!1;const s=H(e,o.cellId);return n.anchor.blockId===s&&(o.colIndex<o.totalCols-1?rt(t,o.tableId,o.rowIndex,o.colIndex+1):!(o.rowIndex<o.totalRows-1)||rt(t,o.tableId,o.rowIndex+1,0))})}(t),ArrowLeft:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;if(0!==n.anchor.offset)return!1;const r=N(e,o.cellId);return n.anchor.blockId===r&&(o.colIndex>0?lt(t,o.tableId,o.rowIndex,o.colIndex-1):!(o.rowIndex>0)||lt(t,o.tableId,o.rowIndex-1,o.totalCols-1))})}(t),Escape:()=>ot(t),"Shift-F10":()=>function(t){return nt(t,(e,n,o)=>{const r=t.getContainer(),l=r.querySelector(`[data-block-id="${o.cellId}"]`);if(!l)return!1;const i=l.getBoundingClientRect(),s=new DOMRect(i.left+i.width/2,i.bottom,0,0),a=r.querySelector(`[data-block-id="${o.tableId}"].ntbl-container`)??r;return et?.close(),et=tt(a,t,o.tableId,s,()=>{et=null}),!0})}(t)},{priority:"context"})}(t,this.locale),this.registerToolbarItem(t),this.selectionService=function(t){let e=null,n=[],o=/* @__PURE__ */new Set;function r(){if(!e)return n=[],void(o=/* @__PURE__ */new Set);const r=t.getState(),l=[],i=Math.min(e.fromRow,e.toRow),s=Math.max(e.fromRow,e.toRow),a=Math.min(e.fromCol,e.toCol),c=Math.max(e.fromCol,e.toCol);for(let t=i;t<=s;t++)for(let n=a;n<=c;n++){const o=M(r,e.tableId,t,n);o&&l.push(o)}n=l,o=new Set(l)}const l={getSelectedRange:()=>e,setSelectedRange(n){e=n,r();const o=t.getState();t.dispatch(o.transaction("api").setSelection(o.selection).build())},clearSelectionSilent(){e=null,r()},getSelectedCellIds:()=>n,isSelected:t=>o.has(t)};return t.registerService(vt,l),l}(t)}onReady(){this.context&&this.selectionService&&(this.cleanupMouseSelection=function(t,e){const n=t.getContainer();let o=null,r=!1;function l(n){const l=n.target.closest("td[data-block-id]");if(!l)return o=null,r=!1,void e.setSelectedRange(null);if(n.shiftKey){if(o){const r=T(t.getState(),l.getAttribute("data-block-id"));if(!r||r.tableId!==o.tableId)return o=null,void e.setSelectedRange(null);n.preventDefault(),e.setSelectedRange({tableId:o.tableId,fromRow:o.row,fromCol:o.col,toRow:r.rowIndex,toCol:r.colIndex})}}else{e.setSelectedRange(null);const n=T(t.getState(),l.getAttribute("data-block-id"));if(!n)return o=null,void(r=!1);o={tableId:n.tableId,row:n.rowIndex,col:n.colIndex},r=!0}}function i(n){if(!r||!o)return;const l=n.target.closest("td[data-block-id]");if(!l)return;const i=T(t.getState(),l.getAttribute("data-block-id"));i&&i.tableId===o.tableId&&(i.rowIndex===o.row&&i.colIndex===o.col||(n.preventDefault(),e.setSelectedRange({tableId:o.tableId,fromRow:o.row,fromCol:o.col,toRow:i.rowIndex,toCol:i.colIndex})))}function s(){r=!1}return n.addEventListener("mousedown",l),n.addEventListener("mousemove",i),document.addEventListener("mouseup",s),()=>{n.removeEventListener("mousedown",l),n.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s)}}(this.context,this.selectionService))}destroy(){this.cleanupMouseSelection?.(),this.cleanupMouseSelection=null,this.selectionService=null,this.context=null}decorations(t){if(!this.selectionService)return v.empty;if(!this.selectionService.getSelectedRange())return v.empty;const e=t.selection;if(!u(e)||!P(t,e.anchor.blockId))return this.selectionService.clearSelectionSilent(),v.empty;const n=this.selectionService.getSelectedCellIds();if(0===n.length)return v.empty;const o=[];for(const r of n)o.push(f(r,{class:"notectl-table-cell--selected"}));return v.create(o)}registerNodeSpecs(t){t.registerNodeSpec({type:"table",group:"block",content:{allow:["table_row"],min:1},isolating:!0,selectable:!0,toDOM(t){const e=document.createElement("div");return e.className="notectl-table-wrapper",e.setAttribute("data-block-id",t.id),e.setAttribute("part","table"),e},toHTML(t,e,n){const o=t.attrs?.borderColor,r=function(t){return t?"none"===t?`${xt}; --ntbl-bc: transparent`:A(t)?`${xt}; --ntbl-bc: ${p(t)}`:xt:xt}(o);return`<table${n?.styleAttr(r)??` style="${r}"`}>${e}</table>`},sanitize:{tags:["table","tbody"]}}),t.registerNodeSpec({type:"table_row",group:"table_content",content:{allow:["table_cell"],min:1},toDOM(t){const e=document.createElement("tr");return e.setAttribute("data-block-id",t.id),e.setAttribute("role","row"),e.setAttribute("part","table-row"),e},toHTML:(t,e)=>`<tr>${e}</tr>`,sanitize:{tags:["tr"]}}),t.registerNodeSpec({type:"table_cell",group:"table_content",content:{allow:["paragraph","list_item","heading","blockquote","image","video","horizontal_rule"]},isolating:!0,toDOM(t){const e=document.createElement("td");return e.setAttribute("data-block-id",t.id),e.setAttribute("role","cell"),e.setAttribute("part","table-cell"),e},toHTML(t,e,n){const o=t.attrs?.colspan??1,r=t.attrs?.rowspan??1,l=[n?.styleAttr(wt)??` style="${wt}"`];return o>1&&l.push(` colspan="${o}"`),r>1&&l.push(` rowspan="${r}"`),`<td${l.join("")}>${e}</td>`},sanitize:{tags:["td"],attrs:["colspan","rowspan"]}})}registerNodeViews(t){t.getSchemaRegistry(),t.registerNodeView("table",function(t,n,o=D){return(t,r,l)=>{const i=document.createElement("div");i.className="ntbl-container",i.setAttribute("data-block-id",t.id),i.setAttribute("data-selectable","true");const s=document.createElement("div");s.className="notectl-table-wrapper";const a=document.createElement("table");a.className="notectl-table",a.setAttribute("role","table");const c=e(t),d=c.length,u=c[0]?e(c[0]).length:0;a.setAttribute("aria-label",o.tableAriaLabel(d,u)),a.setAttribute("aria-description",o.tableAriaDescription);const b=document.createElement("tbody");a.appendChild(b),s.appendChild(a),i.appendChild(s),ft(a,t.attrs?.borderColor);const p=document.createElement("div");p.className="notectl-sr-only",p.setAttribute("aria-live","polite"),p.setAttribute("aria-atomic","true"),i.appendChild(p);const h=function(t,e,n,o,r,l,i){return new mt(t,e,n,o,r,l,i)}(i,a,t,r,l,n,o);let m=null,f=t.id;const v=t=>{if(!n)return;t.preventDefault(),t.stopPropagation(),m?.close();const e=new DOMRect(t.clientX,t.clientY,0,0);m=tt(i,n,f,e,()=>{m=null},o)};return a.addEventListener("contextmenu",v),{dom:i,contentDOM:b,update(t){if("table"!==t.type)return!1;f=t.id,i.setAttribute("data-block-id",t.id),i.setAttribute("data-selectable","true");const n=e(t),r=n.length,l=n[0]?e(n[0]).length:0;return a.setAttribute("aria-label",o.tableAriaLabel(r,l)),ft(a,t.attrs?.borderColor),h.update(t),!1},destroy(){m?.destroy(),a.removeEventListener("contextmenu",v),h.destroy()},selectNode(){i.classList.add("notectl-table--selected")},deselectNode(){i.classList.remove("notectl-table--selected")}}}}(0,t,this.locale)),t.registerNodeView("table_row",(t,e,n)=>{const o=document.createElement("tr");return o.setAttribute("data-block-id",t.id),o.setAttribute("role","row"),{dom:o,contentDOM:o,update:t=>("table_row"!==t.type||o.setAttribute("data-block-id",t.id),!1),destroy(){}}}),t.registerNodeView("table_cell",(t,e,n)=>{const o=document.createElement("td");o.setAttribute("data-block-id",t.id),o.setAttribute("role","cell");const r=t.attrs?.colspan??1,l=t.attrs?.rowspan??1;r>1&&(o.colSpan=r),l>1&&(o.rowSpan=l);const i=t.attrs?.align;return i&&"left"!==i&&w(o,"textAlign",i),{dom:o,contentDOM:o,update(t){if("table_cell"!==t.type)return!1;o.setAttribute("data-block-id",t.id);const e=t.attrs?.colspan??1,n=t.attrs?.rowspan??1;return e>1?o.colSpan=e:o.removeAttribute("colspan"),n>1?o.rowSpan=n:o.removeAttribute("rowspan"),!1},destroy(){}}})}registerToolbarItem(t){const e=this.config.maxPickerRows??8,n=this.config.maxPickerCols??8;t.registerToolbarItem({id:"table",group:"insert",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 3h18v18H3V3zm2 2v4h6V5H5zm8 0v4h6V5h-6zm-8 6v4h6v-4H5zm8 0v4h6v-4h-6zm-8 6v4h6v-4H5zm8 0v4h6v-4h-6z"/></svg>',label:this.locale.insertTable,tooltip:this.locale.insertTable,command:"insertTable",popupType:"gridPicker",popupConfig:{maxRows:e,maxCols:n,onSelect:(e,n)=>{U(t,e,n)}},isActive:t=>!!u(t.selection)&&P(t,t.selection.anchor.blockId)})}};export{vt as n,Ct as t};
2
- //# sourceMappingURL=TablePlugin-CRp4qSZE.mjs.map
1
+ import{c as t,d as e,i as n,o,p as r,u as l}from"./Document-r7vLOAGA.mjs";import{c as i,l as s,o as a,r as c,t as d,u}from"./Selection-HYoVFpAx.mjs";import{a as b}from"./TypeBrands-Ch9856Gb.mjs";import{r as p}from"./HTMLUtils-C6B4UT00.mjs";import{_ as h,s as m}from"./BlockInsertion-6rR9tIGP.mjs";import{i as f,t as v}from"./Decoration-ZeyVfwJB.mjs";import{a as g,o as x,s as w}from"./StyleRuntime-BAutwDZT.mjs";import{n as C}from"./TypedKeys-CA4bfw9O.mjs";import{c as I,i as y,o as k}from"./PluginHelpers-KDuTlmXm.mjs";import{t as S}from"./KeyboardNav-D0my3wuy.mjs";import{r as A}from"./PopupPositioning-DtUrY9bh.mjs";import{i as L}from"./ColorValidation-DAijTjG9.mjs";import{n as R,t as B}from"./ColorGrid-CXRdpP_n.mjs";function E(){const e=n(b("paragraph"),[t("")],l());return n(b("table_cell"),[e],l())}function T(t,n){const o=t.getNodePath(n);if(!o)return null;let r=null,l=null,i=null,s=null;for(const e of o){const n=t.getBlock(e);n&&("table"===n.type?(r=e,l=n):"table_row"===n.type?i=e:"table_cell"===n.type&&(s=e))}if("table_cell"===t.getBlock(n)?.type&&(s=n),!(r&&l&&s&&i))return null;const a=t.doc.children.findIndex(t=>t.id===r),c=e(l),d=c.findIndex(t=>t.id===i);if(-1===d)return null;const u=c[d];if(!u)return null;const b=e(u),p=b.findIndex(t=>t.id===s);if(-1===p)return null;const h=b.length,m=c.length;return{tableId:r,tableIndex:a,rowId:i,rowIndex:d,cellId:s,colIndex:p,totalRows:m,totalCols:h}}function M(t,n,o,r){const l=t.getBlock(n);if(!l)return null;const i=e(l)[o];return i?e(i)[r]?.id??null:null}function N(t,n){const o=t.getBlock(n);if(!o)return n;const r=e(o)[0];if(!r)return n;let l=r;for(;;){const t=e(l)[0];if(!t)return l.id;l=t}}function H(t,n){const o=t.getBlock(n);if(!o)return n;const r=e(o),l=r[r.length-1];if(!l)return n;let i=l;for(;;){const t=e(i),n=t[t.length-1];if(!n)return i.id;i=n}}function P(t,e){const n=t.getNodePath(e);if(!n)return!1;for(const o of n)if("table"===t.getBlock(o)?.type)return!0;return!1}var D={insertRowAbove:"Insert Row Above",insertRowBelow:"Insert Row Below",insertColumnLeft:"Insert Column Left",insertColumnRight:"Insert Column Right",deleteRow:"Delete Row",deleteColumn:"Delete Column",borderColorLabel:"Border Color...",deleteTable:"Delete Table",tableActions:"Table actions",menuKeyboardHint:"↑↓ Navigate · Enter Select · Esc Close",insertRow:"Insert row",insertColumn:"Insert column",addRow:"Add row",addColumn:"Add column",tableActionsHint:"Table actions (Right-click or Shift+F10)",contextMenuHint:"Right-click or Shift+F10 for table actions",borderColor:"Border color",defaultColor:"Default",noBorders:"No borders",borderColorPicker:"Border color picker",announceBorderColorSet:t=>`Table border color set to ${t}`,announceBorderReset:"Table borders reset to default",borderSwatchLabel:t=>`Border ${t}`,announceRowInsertedAbove:"Row inserted above",announceRowInsertedBelow:"Row inserted below",announceColumnInserted:t=>`Column inserted ${t}`,announceRowDeleted:"Row deleted",announceColumnDeleted:"Column deleted",announceTableDeleted:"Table deleted",insertTable:"Insert Table",tableAriaLabel:(t,e)=>`Table with ${t} rows and ${e} columns`,tableAriaDescription:"Right-click or press Shift+F10 for table actions"},z=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-jbplYWkC.mjs"),"./locales/de.ts":()=>import("./de-DN-e6G5A.mjs"),"./locales/es.ts":()=>import("./es-CM55WeEN.mjs"),"./locales/fr.ts":()=>import("./fr-C_2i5Ono.mjs"),"./locales/hi.ts":()=>import("./hi-C9fvG91d.mjs"),"./locales/pt.ts":()=>import("./pt-GqLw5tN0.mjs"),"./locales/ru.ts":()=>import("./ru-4g_qsaLr.mjs"),"./locales/zh.ts":()=>import("./zh-DeZP08HI.mjs")});async function $(t){return I(z,t,D)}var j=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#980000","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#0b5394","#38761d"];function _(t,e,n){const o=t.getBlock(e);if(!o||"table"!==o.type)return null;const r=t.getNodePath(e);if(!r)return null;if(void 0===n){const{borderColor:e,...n}=o.attrs??{},l=n;return t.transaction("command").setNodeAttr(r,l).setSelection(t.selection).build()}const l={...o.attrs,borderColor:n};return t.transaction("command").setNodeAttr(r,l).setSelection(t.selection).build()}function V(t,e,n=D){const o=t.getState();if(!u(o.selection))return!1;const r=T(o,o.selection.anchor.blockId);if(!r)return!1;const l=_(o,r.tableId,e);if(!l)return!1;t.dispatch(l);const i="none"===e?"none":R(e);return t.announce(n.announceBorderColorSet(i)),!0}function O(t,e=D){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=_(n,o.tableId,void 0);return!!r&&(t.dispatch(r),t.announce(e.announceBorderReset),!0)}function F(t,e){const n=t.getBlock(e);if(n)return n.attrs?.borderColor}function q(t,e,n,o,r=D){t.classList.add("notectl-color-picker");const l=F(e.getState(),n),i=document.createElement("button");i.type="button",i.className="notectl-color-picker__default",i.textContent=r.defaultColor,i.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),O(e,r),o()}),i.addEventListener("keydown",t=>{"Escape"===t.key&&(t.preventDefault(),o())}),t.appendChild(i);const s=document.createElement("button");s.type="button",s.className="notectl-color-picker__default",s.textContent=r.noBorders,s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),V(e,"none",r),o()}),s.addEventListener("keydown",t=>{"Escape"===t.key&&(t.preventDefault(),o())}),t.appendChild(s),B(t,{colors:j,columns:5,ariaLabel:r.borderColorPicker,ariaLabelPrefix:"",activeColor:l??null,swatchLabel:r.borderSwatchLabel,titleAsName:!0,onSelect:t=>{V(e,t,r),o()},onClose:o})}function Z(t,o,r){const i=t.getBlock(o);if(!i)return null;const s=e(i),a=s[0]?e(s[0]).length:0;if(0===a)return null;const c=function(t){const e=[];for(let n=0;n<t;n++)e.push(E());return n(b("table_row"),e,l())}(a),u=t.transaction("command").insertNode([o],r,c),p=e(c)[0],h=p?e(p)[0]:void 0;return h?u.setSelection(d(h.id,0)):p&&u.setSelection(d(p.id,0)),u.build()}function K(t,n,o){const r=t.getBlock(n);if(!r)return null;const l=e(r),i=t.transaction("command");for(const e of l){const t=E();i.insertNode([n,e.id],o,t)}return i.setSelection(t.selection),i.build()}function Y(t,n,o,r=0){const l=t.getBlock(n);if(!l)return null;if(e(l).length<=1)return W(t,n);const i=t.transaction("command").removeNode([n],o),s=M(t,n,o>0?o-1:1,r);if(s){const e=N(t,s);i.setSelection(d(e,0))}return i.build()}function X(t,n,o,r=0){const l=t.getBlock(n);if(!l)return null;const i=e(l);if((i[0]?e(i[0]).length:0)<=1)return W(t,n);const s=t.transaction("command");for(let e=i.length-1;e>=0;e--){const t=i[e];t&&s.removeNode([n,t.id],o)}const a=M(t,n,r,o>0?o-1:1);if(a){const e=N(t,a);s.setSelection(d(e,0))}return s.build()}function W(t,e){const n=t.doc.children.findIndex(t=>t.id===e);if(-1===n)return null;if(1===t.doc.children.length){const e=o(l());return t.transaction("command").insertNode([],0,e).removeNode([],1).setSelection(d(e.id,0)).build()}const r=t.transaction("command").removeNode([],n),i=t.doc.children[n+1];if(i){const e=h(t,i.id,"start");if(e)return r.setSelection(e),r.build()}const s=t.doc.children[n-1];if(s){const e=h(t,s.id,"end");if(e)return r.setSelection(e),r.build()}return null}function U(t,o,r){const i=t.getState(),s=y(i);if(!s)return!1;const a=function(t,e){const o=l(),r=[];for(let i=0;i<t;i++){const t=[];for(let n=0;n<e;n++)t.push(E());r.push(n(b("table_row"),t,l()))}return n(b("table"),r,o)}(o,r),c=i.transaction("command");if(!m(i,c,s,a))return!1;const u=e(a)[0],p=u?e(u)[0]:void 0,h=p?e(p)[0]:void 0;return h?c.setSelection(d(h.id,0)):p&&c.setSelection(d(p.id,0)),t.dispatch(c.build()),!0}function G(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Z(n,o.tableId,o.rowIndex+1);return!!r&&(t.dispatch(r),t.announce(e.announceRowInsertedBelow),!0)}function Q(t,e,n){const o=t.getState();if(!u(o.selection))return!1;const r=T(o,o.selection.anchor.blockId);if(!r)return!1;const l="left"===e?r.colIndex:r.colIndex+1,i=K(o,r.tableId,l);return!!i&&(t.dispatch(i),t.announce(n.announceColumnInserted(e)),!0)}function J(t,e){t.registerCommand("insertTable",()=>U(t,3,3)),t.registerCommand("addRowAbove",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Z(n,o.tableId,o.rowIndex);return!!r&&(t.dispatch(r),t.announce(e.announceRowInsertedAbove),!0)}(t,e)),t.registerCommand("addRowBelow",()=>G(t,e)),t.registerCommand("addColumnLeft",()=>function(t,e){return Q(t,"left",e)}(t,e)),t.registerCommand("addColumnRight",()=>function(t,e){return Q(t,"right",e)}(t,e)),t.registerCommand("deleteRow",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=Y(n,o.tableId,o.rowIndex,o.colIndex);return!!r&&(t.dispatch(r),t.announce(e.announceRowDeleted),!0)}(t,e)),t.registerCommand("deleteColumn",()=>function(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=T(n,n.selection.anchor.blockId);if(!o)return!1;const r=X(n,o.tableId,o.colIndex,o.rowIndex);return!!r&&(t.dispatch(r),t.announce(e.announceColumnDeleted),!0)}(t,e)),t.registerCommand("selectTable",()=>function(t){const e=t.getState(),n=e.selection;if(s(n))return"table"===e.getBlock(n.nodeId)?.type;if(i(n))return!1;const o=T(e,n.anchor.blockId);if(!o)return!1;const r=e.getNodePath(o.tableId);if(!r)return!1;const l=e.transaction("command").setSelection(c(o.tableId,r)).build();return t.dispatch(l),!0}(t)),t.registerCommand("deleteTable",()=>function(t,e){const n=t.getState(),o=function(t){if(s(t.selection)){const e=t.getBlock(t.selection.nodeId);return"table"!==e?.type?null:{tableId:e.id}}if(i(t.selection))return null;const e=T(t,t.selection.anchor.blockId);return e?{tableId:e.tableId}:null}(n);if(!o)return!1;const r=W(n,o.tableId);return!!r&&(t.dispatch(r),t.announce(e.announceTableDeleted),!0)}(t,e))}function tt(t,e,n,o,r,l=D,i){let s=!0,a=null,c=null;const d=document.createElement("div");d.className="notectl-table-context-menu",d.setAttribute("role","menu"),d.setAttribute("aria-label",l.tableActions),d.setAttribute("contenteditable","false");const u=[];let b=0;const p=function(t){return[{type:"item",label:t.insertRowAbove,command:"addRowAbove"},{type:"item",label:t.insertRowBelow,command:"addRowBelow"},{type:"separator"},{type:"item",label:t.insertColumnLeft,command:"addColumnLeft"},{type:"item",label:t.insertColumnRight,command:"addColumnRight"},{type:"separator"},{type:"item",label:t.deleteRow,command:"deleteRow"},{type:"item",label:t.deleteColumn,command:"deleteColumn"},{type:"separator"},{type:"submenu",label:t.borderColorLabel,id:"borderColor"},{type:"separator"},{type:"item",label:t.deleteTable,command:"deleteTable"}]}(l);for(const I of p){if("separator"===I.type){const t=document.createElement("div");t.setAttribute("role","separator"),d.appendChild(t);continue}const t=document.createElement("button");t.type="button",t.setAttribute("role","menuitem"),t.textContent=I.label,"submenu"===I.type&&(t.dataset.submenu=I.id,t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false")),"item"===I.type&&(t.dataset.command=I.command),t.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),t.addEventListener("click",n=>{n.stopPropagation(),"item"===I.type?(e.executeCommand(I.command),C()):"submenu"===I.type&&m(t)}),u.push(t),d.appendChild(t)}const h=document.createElement("div");function m(o){if(f(),o.setAttribute("aria-expanded","true"),i)c=i.open({anchor:o,position:"right",referenceNode:d,parent:{close:()=>C(),getElement:()=>d},onClose:()=>{c=null,a=null,v()},content:(t,r)=>{t.className="notectl-table-context-menu",t.setAttribute("contenteditable","false"),a=t,t.addEventListener("keydown",t=>{t.stopPropagation();const e="rtl"===getComputedStyle(d).direction?"ArrowRight":"ArrowLeft";t.key===e&&(t.preventDefault(),r(),o.focus())}),q(t,e,n,()=>C(),l)}});else{a=document.createElement("div"),a.className="notectl-table-context-menu",a.setAttribute("contenteditable","false"),a.addEventListener("keydown",t=>{t.stopPropagation();const e="rtl"===getComputedStyle(d).direction?"ArrowRight":"ArrowLeft";t.key===e&&(t.preventDefault(),f(),o.focus())}),q(a,e,n,()=>C(),l),t.appendChild(a);const r=d.getBoundingClientRect(),i="rtl"===getComputedStyle(d).direction;A(a,r,{position:"right",isRtl:i}),requestAnimationFrame(()=>{(a?.querySelector("button"))?.focus()})}}function f(){c?(c.close(),c=null,a=null):a&&(a.remove(),a=null),v()}function v(){for(const t of u)t.dataset.submenu&&t.setAttribute("aria-expanded","false")}h.className="notectl-table-context-menu__hint",h.setAttribute("aria-hidden","true"),h.textContent=l.menuKeyboardHint,d.appendChild(h),S(u,b),d.addEventListener("keydown",t=>{switch(t.stopPropagation(),t.key){case"Escape":return t.preventDefault(),void C();case"ArrowDown":return t.preventDefault(),b=(b+1)%u.length,S(u,b),void u[b]?.focus();case"ArrowUp":return t.preventDefault(),b=(b-1+u.length)%u.length,S(u,b),void u[b]?.focus();case"ArrowRight":case"ArrowLeft":{t.preventDefault();const e="rtl"===getComputedStyle(d).direction?"ArrowLeft":"ArrowRight";if(t.key===e){const t=u[b];t?.dataset.submenu&&m(t)}else f(),u[b]?.focus();return}case"Enter":case" ":{t.preventDefault();const n=u[b];if(!n)return;return void(n.dataset.submenu?m(n):n.dataset.command&&(e.executeCommand(n.dataset.command),C()))}case"Home":return t.preventDefault(),b=0,S(u,b),void u[b]?.focus();case"End":return t.preventDefault(),b=u.length-1,S(u,b),void u[b]?.focus()}}),A(d,o,{position:"below-start"}),t.appendChild(d),u[0]?.focus(),requestAnimationFrame(()=>{s&&u[0]&&u[0].focus()});const g=t=>{const e=t.composedPath();e.includes(d)||a&&e.includes(a)||C()};let x=null,w=!1;function C(){s&&(s=!1,f(),d.remove(),null!==x&&(clearTimeout(x),x=null),w&&(document.removeEventListener("mousedown",g,!0),w=!1),r?.())}return x=setTimeout(()=>{x=null,document.addEventListener("mousedown",g,!0),w=!0},0),{isOpen:()=>s,close:C,destroy:C}}var et=null;function nt(t,e){const n=t.getState();if(!u(n.selection))return!1;const o=n.selection,r=T(n,o.anchor.blockId);return!!r&&e(n,o,r)}function ot(t){return nt(t,(e,n,o)=>{const r=o.tableIndex+1;if(r>=e.doc.children.length)return!1;const l=e.doc.children[r];if(!l)return!1;const i=e.transaction("command").setSelection(d(l.id,0)).build();return t.dispatch(i),!0})}function rt(t,e,n,o){const r=t.getState(),l=M(r,e,n,o);if(!l)return!1;const i=N(r,l),s=r.transaction("command").setSelection(d(i,0)).build();return t.dispatch(s),!0}function lt(t,e,n,o){const l=t.getState(),i=M(l,e,n,o);if(!i)return!1;const s=H(l,i),a=l.getBlock(s);if(!a)return!1;const c=r(a),u=l.transaction("command").setSelection(d(s,c)).build();return t.dispatch(u),!0}function it(t,e){const n=t.getState(),o=n.getNodePath(e);if(!o)return!1;const r=n.transaction("input").setSelection(c(e,o)).build();return t.dispatch(r),!0}var st='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M6 1v10M1 6h10" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>';function at(t,e,n){const o=document.createElement("button");return o.className=t,o.innerHTML=e,o.title=n,o.type="button",o.setAttribute("aria-label",n),o.setAttribute("contenteditable","false"),o.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),o}function ct(t,e){const n=document.createElement("div");n.className=`ntbl-insert-line ntbl-insert-line--${t}`,n.setAttribute("contenteditable","false"),n.setAttribute("data-notectl-no-print","");const o=at("ntbl-insert-btn",st,e);return n.appendChild(o),n}function dt(t,e){const n=document.createElement("button");n.className=`ntbl-add-zone ${t}`,n.type="button",n.setAttribute("contenteditable","false"),n.setAttribute("aria-label",e),n.setAttribute("data-notectl-no-print",""),n.title=e;const o=document.createElement("span");return o.className="ntbl-add-icon",o.innerHTML=st,n.appendChild(o),n.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),n}function ut(t){const e=document.createElement("div");return e.className=t,e.setAttribute("contenteditable","false"),e.setAttribute("data-notectl-no-print",""),e}function bt(t,e){x(t,"none"===e?{backgroundColor:"transparent",border:"1px dashed rgba(128,128,128,0.4)"}:e?{backgroundColor:e,border:"1px solid rgba(0,0,0,0.15)"}:{backgroundColor:"var(--notectl-border)",border:"1px solid rgba(0,0,0,0.15)"})}function pt(t,e,n,o){const r=document.createElement("div");r.className=`ntbl-handle ${t}`,r.dataset.index=String(e);const l=at("ntbl-handle-delete",'<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M2 2l6 6M8 2l-6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',n);return l.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),o(e)}),r.appendChild(l),r}function ht(t,e){let n=0,o=0,r=t;for(;r&&r!==e;)n+=r.offsetTop,o+=r.offsetLeft,r=r.offsetParent;return{top:n,left:o}}var mt=class{tableId;numRows;numCols;activeRowIndex=-1;activeColIndex=-1;colBar;rowBar;insertLineH;insertLineV;addRowZone;addColZone;deleteTableBtn;borderColorBtn;actionsBtn;contextHint;observer;borderColorPopup=null;activeContextMenu=null;container;tableEl;getState;dispatchFn;pluginContext;locale;onMouseMove=t=>{const e=this.tableEl.getBoundingClientRect(),n=t.clientX-e.left,o=t.clientY-e.top;if(!(n>=-10&&n<=e.width+10&&o>=-10&&o<=e.height+10))return void this.hideInsertLines();const r=function(t,e,n,o){let r=Number.POSITIVE_INFINITY,l=null;for(const a of n){const t=Math.abs(e-a.position);t<r&&t<10&&(r=t,l=a)}let i=Number.POSITIVE_INFINITY,s=null;for(const a of o){const e=Math.abs(t-a.position);e<i&&e<10&&(i=e,s=a)}return l&&(!s||r<=i)?{type:"row",border:l}:s?{type:"col",border:s}:{type:"none",border:null}}(n,o,function(t){const e=t.querySelectorAll(":scope > tbody > tr"),n=t.offsetTop,o=[];for(let r=1;r<e.length;r++){const t=e[r];t&&o.push({position:t.offsetTop-n,index:r})}return o}(this.tableEl),function(t,e){if(e<=1)return[];const n=t/e,o=[];for(let r=1;r<e;r++)o.push({position:Math.round(n*r),index:r});return o}(this.tableEl.offsetWidth,this.numCols));"row"===r.type&&r.border?(this.showHorizontalLine(r.border),this.hideVerticalLine()):"col"===r.type&&r.border?(this.showVerticalLine(r.border),this.hideHorizontalLine()):this.hideInsertLines()};onMouseLeave=()=>{this.hideInsertLines()};constructor(t,n,o,r,l,i,s=D){if(this.container=t,this.tableEl=n,this.getState=r,this.dispatchFn=l,this.pluginContext=i??null,this.locale=s,this.tableId=o.id,this.numRows=e(o).length,this.numCols=this.countCols(o),this.colBar=ut("ntbl-col-bar"),this.rowBar=ut("ntbl-row-bar"),this.insertLineH=ct("horizontal",s.insertRow),this.insertLineV=ct("vertical",s.insertColumn),this.addRowZone=dt("ntbl-add-row",s.addRow),this.addColZone=dt("ntbl-add-col",s.addColumn),this.deleteTableBtn=at("ntbl-delete-table-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M9 3h6m-9 4h12M10 11v6m4-6v6m-9 3h14l-1-13H6L5 20z" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>',s.deleteTable),this.deleteTableBtn.setAttribute("data-notectl-no-print",""),i){const t=F(r(),this.tableId);this.borderColorBtn=function(t,e){const n=at("ntbl-border-color-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M3 3h18v18H3V3zm0 6h18M3 15h18M9 3v18M15 3v18" stroke="currentColor" stroke-width="1.5"/></svg>',t);n.setAttribute("data-notectl-no-print","");const o=document.createElement("span");return o.className="ntbl-border-color-swatch",bt(o,e),n.appendChild(o),n}(s.borderColor,t),this.actionsBtn=function(t){const e=at("ntbl-actions-btn",'<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="12" cy="19" r="2"/></svg>',t);return e.setAttribute("data-notectl-no-print",""),e}(s.tableActionsHint)}else this.borderColorBtn=null,this.actionsBtn=null;t.append(this.colBar,this.rowBar,this.insertLineH,this.insertLineV,this.addRowZone,this.addColZone,this.deleteTableBtn),this.borderColorBtn&&t.appendChild(this.borderColorBtn),this.actionsBtn&&t.appendChild(this.actionsBtn),this.contextHint=function(t){const e=document.createElement("div");return e.className="ntbl-context-hint",e.setAttribute("aria-hidden","true"),e.setAttribute("contenteditable","false"),e.setAttribute("data-notectl-no-print",""),e.textContent=t,e}(s.contextMenuHint),t.appendChild(this.contextHint),this.rebuildColHandles(),this.rebuildRowHandles(),this.bindEventListeners(),this.observer=new ResizeObserver(()=>{this.positionControls()}),this.observer.observe(n),requestAnimationFrame(()=>this.positionControls())}update(t){this.tableId=t.id;const n=e(t).length,o=this.countCols(t);if(n===this.numRows&&o===this.numCols||(this.numRows=n,this.numCols=o,this.rebuildColHandles(),this.rebuildRowHandles()),this.borderColorBtn){const e=this.borderColorBtn.querySelector(".ntbl-border-color-swatch");if(e){const n=t.attrs?.borderColor;bt(e,n)}}requestAnimationFrame(()=>this.positionControls())}destroy(){this.activeContextMenu?.destroy(),this.closeBorderColorPopup(),this.observer.disconnect(),this.container.removeEventListener("mousemove",this.onMouseMove),this.container.removeEventListener("mouseleave",this.onMouseLeave),this.colBar.remove(),this.rowBar.remove(),this.insertLineH.remove(),this.insertLineV.remove(),this.addRowZone.remove(),this.addColZone.remove(),this.deleteTableBtn.remove(),this.borderColorBtn?.remove(),this.actionsBtn?.remove(),this.contextHint.remove()}bindEventListeners(){const t=this.insertLineH.querySelector(".ntbl-insert-btn"),e=this.insertLineV.querySelector(".ntbl-insert-btn");if(t.addEventListener("click",()=>{this.activeRowIndex>=0&&this.dispatchTransaction(Z(this.getState(),this.tableId,this.activeRowIndex))}),e.addEventListener("click",()=>{this.activeColIndex>=0&&this.dispatchTransaction(K(this.getState(),this.tableId,this.activeColIndex))}),this.addRowZone.addEventListener("click",()=>{this.dispatchTransaction(Z(this.getState(),this.tableId,this.numRows))}),this.addColZone.addEventListener("click",()=>{this.dispatchTransaction(K(this.getState(),this.tableId,this.numCols))}),this.deleteTableBtn.addEventListener("click",()=>{this.dispatchTransaction(W(this.getState(),this.tableId))}),this.borderColorBtn&&this.pluginContext){const t=this.pluginContext;this.borderColorBtn.addEventListener("click",()=>{this.toggleBorderColorPopup(t)})}if(this.actionsBtn&&this.pluginContext){const t=this.pluginContext;this.actionsBtn.addEventListener("click",()=>{this.openActionsMenu(t)})}this.container.addEventListener("mousemove",this.onMouseMove),this.container.addEventListener("mouseleave",this.onMouseLeave)}openActionsMenu(t){if(this.activeContextMenu?.isOpen())return this.activeContextMenu.close(),void(this.activeContextMenu=null);if(!this.actionsBtn)return;const e=this.actionsBtn.getBoundingClientRect(),n=new DOMRect(e.left,e.bottom+4,0,0);this.activeContextMenu=tt(this.container,t,this.tableId,n,()=>{this.activeContextMenu=null},this.locale)}toggleBorderColorPopup(t){this.borderColorPopup?this.closeBorderColorPopup():(this.borderColorPopup=document.createElement("div"),this.borderColorPopup.className="notectl-table-context-menu",x(this.borderColorPopup,{position:"absolute",top:"24px",left:"24px",zIndex:"10000"}),this.borderColorPopup.setAttribute("contenteditable","false"),q(this.borderColorPopup,t,this.tableId,()=>{this.closeBorderColorPopup()},this.locale),this.container.appendChild(this.borderColorPopup))}closeBorderColorPopup(){this.borderColorPopup&&(this.borderColorPopup.remove(),this.borderColorPopup=null)}dispatchTransaction(t){t&&this.dispatchFn(t)}countCols(t){const n=e(t);return n[0]?e(n[0]).length:0}positionControls(){!function(t,e,n){const o=t.children;if(0===o.length)return;const r=e/n;for(let l=0;l<o.length;l++){const t=o[l];x(t,{left:`${Math.round(r*l)}px`,width:`${Math.round(r)}px`})}w(t,"width",`${e}px`)}(this.colBar,this.tableEl.offsetWidth,this.numCols),function(t,e){const n=t.children;if(0===n.length)return;const o=e.querySelectorAll(":scope > tbody > tr"),r=e.offsetTop;let l=0;for(let i=0;i<n.length;i++){const t=n[i],e=o[i];if(e){const n=e.offsetTop-r,o=e.offsetHeight;x(t,{top:`${n}px`,height:`${o}px`}),l=n+o}}w(t,"height",`${l}px`)}(this.rowBar,this.tableEl),function(t,e,n,o){const r=ht(n,o),l=n.offsetHeight,i=n.offsetWidth;x(t,{width:`${i}px`,left:`${r.left}px`}),x(e,{height:`${l}px`,top:`${r.top}px`})}(this.addRowZone,this.addColZone,this.tableEl,this.container)}showHorizontalLine(t){this.activeRowIndex=t.index;const e=ht(this.tableEl,this.container);x(this.insertLineH,{top:e.top+t.position-1+"px",left:`${e.left}px`,width:`${this.tableEl.offsetWidth}px`}),this.insertLineH.classList.add("ntbl-insert-line--visible")}showVerticalLine(t){this.activeColIndex=t.index;const e=ht(this.tableEl,this.container);x(this.insertLineV,{left:e.left+t.position-1+"px",top:`${e.top}px`,height:`${this.tableEl.offsetHeight}px`}),this.insertLineV.classList.add("ntbl-insert-line--visible")}hideInsertLines(){this.hideHorizontalLine(),this.hideVerticalLine()}hideHorizontalLine(){this.insertLineH.classList.remove("ntbl-insert-line--visible"),this.activeRowIndex=-1}hideVerticalLine(){this.insertLineV.classList.remove("ntbl-insert-line--visible"),this.activeColIndex=-1}rebuildColHandles(){this.colBar.innerHTML="";for(let t=0;t<this.numCols;t++){const e=pt("ntbl-col-handle",t,this.locale.deleteColumn,t=>{this.dispatchTransaction(X(this.getState(),this.tableId,t))});this.colBar.appendChild(e)}}rebuildRowHandles(){this.rowBar.innerHTML="";for(let t=0;t<this.numRows;t++){const e=pt("ntbl-row-handle",t,this.locale.deleteRow,t=>{this.dispatchTransaction(Y(this.getState(),this.tableId,t))});this.rowBar.appendChild(e)}}};function ft(t,e){"none"===e?(w(t,"--ntbl-border-color","transparent"),t.classList.add("notectl-table--borderless")):e?(w(t,"--ntbl-border-color",e),t.classList.remove("notectl-table--borderless")):(g(t,"--ntbl-border-color"),t.classList.remove("notectl-table--borderless"))}var vt=new C("tableSelection"),gt={maxPickerRows:8,maxPickerCols:8},xt="border-collapse: collapse; width: 100%; table-layout: fixed",wt="border: 1px solid var(--ntbl-bc, #d0d0d0); padding: 8px 12px; vertical-align: top",Ct=class{id="table";name="Table";priority=40;config;locale;selectionService=null;cleanupMouseSelection=null;context=null;constructor(t){this.config={...gt,...t}}async init(t){this.locale=await k(t,this.config.locale,D,$),t.registerStyleSheet('\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/* Border resolution order: per-table local override → theme component token → theme global token.\n * The inline --ntbl-border-color is set by the toolbar\'s "border color" action and must win\n * over the theme so per-table customizations remain visible after a theme switch.\n */\n.notectl-table td {\n\tborder: 1px solid var(--ntbl-border-color, var(--notectl-table-border, var(--notectl-border)));\n\tbackground: var(--notectl-table-cell-bg, transparent);\n\tpadding: 8px 12px;\n\tmin-width: 60px;\n\tvertical-align: top;\n\tmin-height: 1.6em;\n}\n\n.notectl-table th {\n\tborder: 1px solid var(--ntbl-border-color, var(--notectl-table-border, var(--notectl-border)));\n\tbackground: var(--notectl-table-header-bg, var(--notectl-surface-raised));\n\tpadding: 8px 12px;\n\tmin-width: 60px;\n\tvertical-align: top;\n\ttext-align: start;\n\tfont-weight: 600;\n}\n\n.notectl-table--borderless td {\n\tborder: 1px dashed rgba(128, 128, 128, 0.15);\n}\n\n@media print {\n\t.notectl-table--borderless td {\n\t\tborder: none;\n\t}\n}\n\n.notectl-table td:focus-within {\n\toutline: 2px solid var(--notectl-primary);\n\toutline-offset: -2px;\n}\n\n.notectl-table-cell--selected {\n\tbackground: var(--notectl-primary-muted);\n}\n\n/* Table Context Menu */\n.notectl-table-context-menu {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\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: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tfont-family: inherit;\n}\n\n.notectl-table-context-menu button:hover {\n\tbackground: var(--notectl-hover-bg);\n}\n\n.notectl-table-context-menu hr {\n\tborder: none;\n\tborder-top: 1px solid var(--notectl-border);\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-block-start: 24px;\n\tpadding-inline-start: 24px;\n}\n\n.ntbl-container .notectl-table-wrapper {\n\tmargin: 0;\n}\n\n.ntbl-container.notectl-table--selected .notectl-table-wrapper {\n\toutline: 2px solid var(--notectl-primary-fg);\n\toutline-offset: 2px;\n\tborder-radius: 6px;\n}\n\n/* --- Column Handle Bar --- */\n.ntbl-col-bar {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 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.ntbl-container:focus-within .ntbl-col-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.ntbl-container.notectl-table--selected .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\tinset-inline-start: 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.ntbl-container:focus-within .ntbl-row-bar {\n\topacity: 1;\n\tpointer-events: auto;\n}\n\n.ntbl-container.notectl-table--selected .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: var(--notectl-hover-bg);\n\tborder-radius: 4px 4px 0 0;\n}\n\n.ntbl-col-handle:hover {\n\tbackground: var(--notectl-border);\n}\n\n.ntbl-row-handle {\n\twidth: 100%;\n\tbackground: var(--notectl-hover-bg);\n\tborder-start-start-radius: 4px;\n\tborder-end-start-radius: 4px;\n}\n\n.ntbl-row-handle:hover {\n\tbackground: var(--notectl-border);\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: var(--notectl-fg-muted);\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.ntbl-handle:focus-within .ntbl-handle-delete {\n\topacity: 1;\n\ttransform: scale(1);\n}\n\n.ntbl-handle-delete:hover,\n.ntbl-handle-delete:focus-visible {\n\tbackground: var(--notectl-danger-muted);\n\tcolor: var(--notectl-danger);\n}\n\n.ntbl-handle-delete:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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\tvar(--notectl-primary) 8%,\n\t\tvar(--notectl-primary) 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px var(--notectl-focus-ring);\n}\n\n.ntbl-insert-line--vertical {\n\twidth: 2px;\n\tbackground: linear-gradient(\n\t\t180deg,\n\t\ttransparent,\n\t\tvar(--notectl-primary) 8%,\n\t\tvar(--notectl-primary) 92%,\n\t\ttransparent\n\t);\n\tbox-shadow: 0 0 6px var(--notectl-focus-ring);\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: var(--notectl-surface-raised);\n\tborder: 2px solid var(--notectl-primary);\n\tcolor: var(--notectl-primary);\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 var(--notectl-focus-ring);\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\tinset-inline-start: -9px;\n\ttransform: translateY(-50%);\n}\n\n.ntbl-insert-btn:hover,\n.ntbl-insert-btn:focus-visible {\n\tbackground: var(--notectl-primary);\n\tcolor: var(--notectl-primary-fg);\n\tbox-shadow: 0 2px 12px var(--notectl-focus-ring);\n}\n\n.ntbl-insert-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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.ntbl-container:focus-within .ntbl-add-zone {\n\topacity: 1;\n}\n\n.ntbl-container.notectl-table--selected .ntbl-add-zone {\n\topacity: 1;\n}\n\n.ntbl-delete-table-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 0;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-danger);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-danger);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n}\n\n.ntbl-container:hover .ntbl-delete-table-btn,\n.ntbl-container:focus-within .ntbl-delete-table-btn,\n.ntbl-container.notectl-table--selected .ntbl-delete-table-btn {\n\topacity: 1;\n}\n\n.ntbl-delete-table-btn:hover,\n.ntbl-delete-table-btn:focus-visible {\n\tbackground: var(--notectl-danger-muted);\n\tborder-color: var(--notectl-danger);\n}\n\n.ntbl-delete-table-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n/* --- Context Menu Discovery Hint --- */\n.ntbl-context-hint {\n\tposition: absolute;\n\ttop: 4px;\n\tinset-inline-end: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tpadding: 2px 8px;\n\tborder-radius: 4px;\n\topacity: 0;\n\ttransition: opacity 0.2s ease;\n\tpointer-events: none;\n\twhite-space: nowrap;\n\tz-index: 5;\n}\n\n.ntbl-container:hover .ntbl-context-hint,\n.ntbl-container:focus-within .ntbl-context-hint,\n.ntbl-container.notectl-table--selected .ntbl-context-hint {\n\topacity: 1;\n}\n\n/* --- Table Actions Button --- */\n.ntbl-actions-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 48px;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg-muted);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n\tcursor: pointer;\n\tpadding: 0;\n}\n\n.ntbl-container:hover .ntbl-actions-btn,\n.ntbl-container:focus-within .ntbl-actions-btn,\n.ntbl-container.notectl-table--selected .ntbl-actions-btn {\n\topacity: 1;\n}\n\n.ntbl-actions-btn:hover,\n.ntbl-actions-btn:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\tborder-color: var(--notectl-primary);\n}\n\n.ntbl-actions-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n/* --- Border Color Button --- */\n.ntbl-border-color-btn {\n\tposition: absolute;\n\ttop: 0;\n\tinset-inline-start: 24px;\n\twidth: 20px;\n\theight: 20px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg-muted);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.2s ease, background 0.15s, border-color 0.15s;\n\tz-index: 7;\n\tcursor: pointer;\n\tpadding: 0;\n}\n\n.ntbl-container:hover .ntbl-border-color-btn,\n.ntbl-container:focus-within .ntbl-border-color-btn,\n.ntbl-container.notectl-table--selected .ntbl-border-color-btn {\n\topacity: 1;\n}\n\n.ntbl-border-color-btn:hover,\n.ntbl-border-color-btn:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\tborder-color: var(--notectl-primary);\n}\n\n.ntbl-border-color-btn:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.ntbl-border-color-swatch {\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 2px;\n\tborder: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n/* --- Context Menu Keyboard Hint --- */\n.notectl-table-context-menu__hint {\n\tpadding: 4px 12px 6px;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tborder-top: 1px solid var(--notectl-border);\n\tmargin-top: 4px;\n\ttext-align: center;\n\tuser-select: none;\n}\n\n/* --- Context Menu Focus --- */\n.notectl-table-context-menu button:focus-visible {\n\toutline: none;\n\tbackground: var(--notectl-primary-muted);\n\tbox-shadow: inset 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.notectl-table-context-menu [role="separator"] {\n\tborder: none;\n\tborder-top: 1px solid var(--notectl-border);\n\tmargin: 4px 0;\n\theight: 0;\n}\n\n.ntbl-add-row {\n\tbottom: 0;\n\theight: 24px;\n\tborder: 1px dashed var(--notectl-border);\n\tborder-end-start-radius: 6px;\n\tborder-end-end-radius: 6px;\n\tborder-block-start: none;\n\tcolor: var(--notectl-fg-muted);\n\ttransform: translateY(100%);\n}\n\n.ntbl-add-row:hover,\n.ntbl-add-row:focus-visible {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n\tcolor: var(--notectl-primary);\n}\n\n.ntbl-add-row:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n}\n\n.ntbl-add-col {\n\tinset-inline-end: 0;\n\ttop: 24px;\n\twidth: 24px;\n\tborder: 1px dashed var(--notectl-border);\n\tborder-start-end-radius: 6px;\n\tborder-end-end-radius: 6px;\n\tborder-inline-start: none;\n\tcolor: var(--notectl-fg-muted);\n\ttransform: translateX(100%);\n}\n\n[dir="rtl"] .ntbl-add-col {\n\ttransform: translateX(-100%);\n}\n\n.ntbl-add-col:hover,\n.ntbl-add-col:focus-visible {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n\tcolor: var(--notectl-primary);\n}\n\n.ntbl-add-col:focus-visible {\n\toutline: none;\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\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'),this.context=t,this.registerNodeSpecs(t),this.registerNodeViews(t),J(t,this.locale),t.registerCommand("resetTableBorderColor",()=>O(t,this.locale)),function(t,e){t.registerKeymap({Tab:()=>function(t,e){return nt(t,(n,o,r)=>r.colIndex<r.totalCols-1?rt(t,r.tableId,r.rowIndex,r.colIndex+1):r.rowIndex<r.totalRows-1?rt(t,r.tableId,r.rowIndex+1,0):(G(t,e),!0))}(t,e),"Shift-Tab":()=>function(t){return nt(t,(e,n,o)=>o.colIndex>0?rt(t,o.tableId,o.rowIndex,o.colIndex-1):!(o.rowIndex>0)||rt(t,o.tableId,o.rowIndex-1,o.totalCols-1))}(t),Backspace:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;if(0!==n.anchor.offset)return!1;if(0!==o.rowIndex||0!==o.colIndex)return!1;const r=N(e,o.cellId);return n.anchor.blockId===r&&it(t,o.tableId)})}(t),Delete:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;const l=e.getBlock(n.anchor.blockId);if(!l)return!1;const i=r(l);if(n.anchor.offset!==i)return!1;if(o.rowIndex!==o.totalRows-1||o.colIndex!==o.totalCols-1)return!1;const s=H(e,o.cellId);return n.anchor.blockId===s&&it(t,o.tableId)})}(t),ArrowDown:()=>function(t){return nt(t,(e,n,o)=>{const r=H(e,o.cellId);return n.anchor.blockId===r&&(o.rowIndex>=o.totalRows-1?ot(t):rt(t,o.tableId,o.rowIndex+1,o.colIndex))})}(t),ArrowUp:()=>function(t){return nt(t,(e,n,o)=>{const r=N(e,o.cellId);return n.anchor.blockId===r&&!(o.rowIndex<=0)&&rt(t,o.tableId,o.rowIndex-1,o.colIndex)})}(t),ArrowRight:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;const l=e.getBlock(n.anchor.blockId);if(!l)return!1;const i=r(l);if(n.anchor.offset!==i)return!1;const s=H(e,o.cellId);return n.anchor.blockId===s&&(o.colIndex<o.totalCols-1?rt(t,o.tableId,o.rowIndex,o.colIndex+1):!(o.rowIndex<o.totalRows-1)||rt(t,o.tableId,o.rowIndex+1,0))})}(t),ArrowLeft:()=>function(t){return nt(t,(e,n,o)=>{if(!a(n))return!1;if(0!==n.anchor.offset)return!1;const r=N(e,o.cellId);return n.anchor.blockId===r&&(o.colIndex>0?lt(t,o.tableId,o.rowIndex,o.colIndex-1):!(o.rowIndex>0)||lt(t,o.tableId,o.rowIndex-1,o.totalCols-1))})}(t),Escape:()=>ot(t),"Shift-F10":()=>function(t){return nt(t,(e,n,o)=>{const r=t.getContainer(),l=r.querySelector(`[data-block-id="${o.cellId}"]`);if(!l)return!1;const i=l.getBoundingClientRect(),s=new DOMRect(i.left+i.width/2,i.bottom,0,0),a=r.querySelector(`[data-block-id="${o.tableId}"].ntbl-container`)??r;return et?.close(),et=tt(a,t,o.tableId,s,()=>{et=null}),!0})}(t)},{priority:"context"})}(t,this.locale),this.registerToolbarItem(t),this.selectionService=function(t){let e=null,n=[],o=/* @__PURE__ */new Set;function r(){if(!e)return n=[],void(o=/* @__PURE__ */new Set);const r=t.getState(),l=[],i=Math.min(e.fromRow,e.toRow),s=Math.max(e.fromRow,e.toRow),a=Math.min(e.fromCol,e.toCol),c=Math.max(e.fromCol,e.toCol);for(let t=i;t<=s;t++)for(let n=a;n<=c;n++){const o=M(r,e.tableId,t,n);o&&l.push(o)}n=l,o=new Set(l)}const l={getSelectedRange:()=>e,setSelectedRange(n){e=n,r();const o=t.getState();t.dispatch(o.transaction("api").setSelection(o.selection).build())},clearSelectionSilent(){e=null,r()},getSelectedCellIds:()=>n,isSelected:t=>o.has(t)};return t.registerService(vt,l),l}(t)}onReady(){this.context&&this.selectionService&&(this.cleanupMouseSelection=function(t,e){const n=t.getContainer();let o=null,r=!1;function l(n){const l=n.target.closest("td[data-block-id]");if(!l)return o=null,r=!1,void e.setSelectedRange(null);if(n.shiftKey){if(o){const r=T(t.getState(),l.getAttribute("data-block-id"));if(!r||r.tableId!==o.tableId)return o=null,void e.setSelectedRange(null);n.preventDefault(),e.setSelectedRange({tableId:o.tableId,fromRow:o.row,fromCol:o.col,toRow:r.rowIndex,toCol:r.colIndex})}}else{e.setSelectedRange(null);const n=T(t.getState(),l.getAttribute("data-block-id"));if(!n)return o=null,void(r=!1);o={tableId:n.tableId,row:n.rowIndex,col:n.colIndex},r=!0}}function i(n){if(!r||!o)return;const l=n.target.closest("td[data-block-id]");if(!l)return;const i=T(t.getState(),l.getAttribute("data-block-id"));i&&i.tableId===o.tableId&&(i.rowIndex===o.row&&i.colIndex===o.col||(n.preventDefault(),e.setSelectedRange({tableId:o.tableId,fromRow:o.row,fromCol:o.col,toRow:i.rowIndex,toCol:i.colIndex})))}function s(){r=!1}return n.addEventListener("mousedown",l),n.addEventListener("mousemove",i),document.addEventListener("mouseup",s),()=>{n.removeEventListener("mousedown",l),n.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s)}}(this.context,this.selectionService))}destroy(){this.cleanupMouseSelection?.(),this.cleanupMouseSelection=null,this.selectionService=null,this.context=null}decorations(t){if(!this.selectionService)return v.empty;if(!this.selectionService.getSelectedRange())return v.empty;const e=t.selection;if(!u(e)||!P(t,e.anchor.blockId))return this.selectionService.clearSelectionSilent(),v.empty;const n=this.selectionService.getSelectedCellIds();if(0===n.length)return v.empty;const o=[];for(const r of n)o.push(f(r,{class:"notectl-table-cell--selected"}));return v.create(o)}registerNodeSpecs(t){t.registerNodeSpec({type:"table",group:"block",content:{allow:["table_row"],min:1},isolating:!0,selectable:!0,toDOM(t){const e=document.createElement("div");return e.className="notectl-table-wrapper",e.setAttribute("data-block-id",t.id),e.setAttribute("part","table"),e},toHTML(t,e,n){const o=t.attrs?.borderColor,r=function(t){return t?"none"===t?`${xt}; --ntbl-bc: transparent`:L(t)?`${xt}; --ntbl-bc: ${p(t)}`:xt:xt}(o);return`<table${n?.styleAttr(r)??` style="${r}"`}>${e}</table>`},sanitize:{tags:["table","tbody"]}}),t.registerNodeSpec({type:"table_row",group:"table_content",content:{allow:["table_cell"],min:1},toDOM(t){const e=document.createElement("tr");return e.setAttribute("data-block-id",t.id),e.setAttribute("role","row"),e.setAttribute("part","table-row"),e},toHTML:(t,e)=>`<tr>${e}</tr>`,sanitize:{tags:["tr"]}}),t.registerNodeSpec({type:"table_cell",group:"table_content",content:{allow:["paragraph","list_item","heading","blockquote","image","video","horizontal_rule"]},isolating:!0,toDOM(t){const e=document.createElement("td");return e.setAttribute("data-block-id",t.id),e.setAttribute("role","cell"),e.setAttribute("part","table-cell"),e},toHTML(t,e,n){const o=t.attrs?.colspan??1,r=t.attrs?.rowspan??1,l=[n?.styleAttr(wt)??` style="${wt}"`];return o>1&&l.push(` colspan="${o}"`),r>1&&l.push(` rowspan="${r}"`),`<td${l.join("")}>${e}</td>`},sanitize:{tags:["td"],attrs:["colspan","rowspan"]}})}registerNodeViews(t){t.getSchemaRegistry(),t.registerNodeView("table",function(t,n,o=D){return(t,r,l)=>{const i=document.createElement("div");i.className="ntbl-container",i.setAttribute("data-block-id",t.id),i.setAttribute("data-selectable","true");const s=document.createElement("div");s.className="notectl-table-wrapper",s.setAttribute("part","table");const a=document.createElement("table");a.className="notectl-table",a.setAttribute("role","table");const c=e(t),d=c.length,u=c[0]?e(c[0]).length:0;a.setAttribute("aria-label",o.tableAriaLabel(d,u)),a.setAttribute("aria-description",o.tableAriaDescription);const b=document.createElement("tbody");a.appendChild(b),s.appendChild(a),i.appendChild(s),ft(a,t.attrs?.borderColor);const p=document.createElement("div");p.className="notectl-sr-only",p.setAttribute("aria-live","polite"),p.setAttribute("aria-atomic","true"),i.appendChild(p);const h=function(t,e,n,o,r,l,i){return new mt(t,e,n,o,r,l,i)}(i,a,t,r,l,n,o);let m=null,f=t.id;const v=t=>{if(!n)return;t.preventDefault(),t.stopPropagation(),m?.close();const e=new DOMRect(t.clientX,t.clientY,0,0);m=tt(i,n,f,e,()=>{m=null},o)};return a.addEventListener("contextmenu",v),{dom:i,contentDOM:b,update(t){if("table"!==t.type)return!1;f=t.id,i.setAttribute("data-block-id",t.id),i.setAttribute("data-selectable","true");const n=e(t),r=n.length,l=n[0]?e(n[0]).length:0;return a.setAttribute("aria-label",o.tableAriaLabel(r,l)),ft(a,t.attrs?.borderColor),h.update(t),!1},destroy(){m?.destroy(),a.removeEventListener("contextmenu",v),h.destroy()},selectNode(){i.classList.add("notectl-table--selected")},deselectNode(){i.classList.remove("notectl-table--selected")}}}}(0,t,this.locale)),t.registerNodeView("table_row",(t,e,n)=>{const o=document.createElement("tr");return o.setAttribute("data-block-id",t.id),o.setAttribute("role","row"),o.setAttribute("part","table-row"),{dom:o,contentDOM:o,update:t=>("table_row"!==t.type||o.setAttribute("data-block-id",t.id),!1),destroy(){}}}),t.registerNodeView("table_cell",(t,e,n)=>{const o=document.createElement("td");o.setAttribute("data-block-id",t.id),o.setAttribute("role","cell"),o.setAttribute("part","table-cell");const r=t.attrs?.colspan??1,l=t.attrs?.rowspan??1;r>1&&(o.colSpan=r),l>1&&(o.rowSpan=l);const i=t.attrs?.align;return i&&"left"!==i&&w(o,"textAlign",i),{dom:o,contentDOM:o,update(t){if("table_cell"!==t.type)return!1;o.setAttribute("data-block-id",t.id);const e=t.attrs?.colspan??1,n=t.attrs?.rowspan??1;return e>1?o.colSpan=e:o.removeAttribute("colspan"),n>1?o.rowSpan=n:o.removeAttribute("rowspan"),!1},destroy(){}}})}registerToolbarItem(t){const e=this.config.maxPickerRows??8,n=this.config.maxPickerCols??8;t.registerToolbarItem({id:"table",group:"insert",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 3h18v18H3V3zm2 2v4h6V5H5zm8 0v4h6V5h-6zm-8 6v4h6v-4H5zm8 0v4h6v-4h-6zm-8 6v4h6v-4H5zm8 0v4h6v-4h-6z"/></svg>',label:this.locale.insertTable,tooltip:this.locale.insertTable,command:"insertTable",popupType:"gridPicker",popupConfig:{maxRows:e,maxCols:n,onSelect:(e,n)=>{U(t,e,n)}},isActive:t=>!!u(t.selection)&&P(t,t.selection.anchor.blockId)})}};export{vt as n,Ct as t};
2
+ //# sourceMappingURL=TablePlugin-D93RR5xH.mjs.map