patent-editor 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib.css +1 -1
- package/dist/lib.d.ts +7 -3
- package/dist/lib.js +2059 -2554
- package/dist/lib.js.map +1 -1
- package/package.json +1 -1
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sources":["../src/editor/extensions/slashCommand.ts","../src/store/editorStore.ts","../src/components/SlashMenu.tsx","../src/editor/extensions/searchReplace.ts","../src/editor/ai/patchDiff.ts","../src/editor/schema/baseNodes.ts","../src/editor/schema/baseMarks.ts","../src/editor/schema/schema.ts","../src/editor/core/CommandRegistry.ts","../src/editor/core/PluginManager.ts","../src/lib/editorI18n.ts","../src/editor/plugins/mermaid/mermaidNode.ts","../src/editor/plugins/mermaid/index.ts","../src/editor/plugins/drawio/drawioNode.ts","../src/editor/plugins/drawio/index.ts","../src/editor/plugins/math/MathComponent.tsx","../src/editor/plugins/math/mathNode.ts","../src/editor/plugins/math/index.ts","../src/editor/commands/nodeQueries.ts","../src/editor/commands/nodeCommands.ts","../src/editor/plugins/patent/claimNode.ts","../src/editor/plugins/patent/figureNode.ts","../src/editor/plugins/patent/referenceNode.ts","../src/editor/plugins/patent/sectionNode.ts","../src/editor/plugins/patent/patentDocTemplate.ts","../src/editor/plugins/patent/index.ts","../src/editor/plugins/index.ts","../src/editor/core/EditorCore.ts","../src/editor/export/wordExport.ts","../src/components/Toolbar.tsx","../src/components/NodeToolbar.tsx","../src/editor/plugins/patent/claimIndustrial.ts","../src/components/ClaimWorkspacePanel.tsx","../src/editor/ai/sectionContextDeps.ts","../src/editor/ai/aiContext.ts","../src/components/BubbleMenu.tsx","../src/components/FindReplace.tsx","../src/components/WordCount.tsx","../src/components/OutlinePanel.tsx","../src/editor/renderer/NodeRenderer.tsx","../src/components/EditorView.tsx","../src/editor/ai/aiService.ts","../src/PatentEditor.tsx","../src/editor/ai/streamWriter.ts","../src/editor/ai/mockAIService.ts","../src/editor/ai/postProcessClaims.ts","../src/editor/ai/docDiff.ts","../src/editor/plugins/patent/validation.ts"],"sourcesContent":["import { Extension } from '@tiptap/react';\r\nimport { PluginKey } from '@tiptap/pm/state';\r\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion';\r\n\r\nexport interface SlashCommandItem {\r\n title: string;\r\n description: string;\r\n icon: string;\r\n command: (props: { editor: any; range: any }) => void;\r\n}\r\n\r\nexport const SlashCommandPluginKey = new PluginKey('slashCommand');\r\n\r\nexport const SlashCommand = Extension.create({\r\n name: 'slashCommand',\r\n\r\n addOptions() {\r\n return {\r\n suggestion: {\r\n char: '/',\r\n command: ({ editor, range, props }: { editor: any; range: any; props: SlashCommandItem }) => {\r\n props.command({ editor, range });\r\n },\r\n } as Partial<SuggestionOptions<SlashCommandItem>>,\r\n };\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n return [\r\n Suggestion<SlashCommandItem>({\r\n editor: this.editor,\r\n ...this.options.suggestion,\r\n pluginKey: SlashCommandPluginKey,\r\n }),\r\n ];\r\n },\r\n});\r\n","import { create } from 'zustand';\r\nimport { Editor, JSONContent } from '@tiptap/react';\r\nimport type { AIServiceAdapter, ChatSessionAPI } from '../editor/ai/aiService';\r\n\r\nexport type EditorLanguage = 'zh' | 'en';\r\nexport type AutoSaveStatus = 'idle' | 'saving' | 'saved' | 'error';\r\nexport type AIStatus = 'idle' | 'streaming' | 'loading' | 'error';\r\nexport type RightPanelTab = 'drafting' | 'chat';\r\n\r\ninterface AIStreamingState {\r\n status: AIStatus;\r\n activeSectionType: string | null;\r\n requestId: string | null;\r\n abortFn: (() => void) | null;\r\n}\r\n\r\nexport interface ChatReference {\r\n id: string;\r\n text: string;\r\n from?: number;\r\n to?: number;\r\n sectionType?: string;\r\n}\r\n\r\ninterface RightPanelState {\r\n visible: boolean;\r\n activeTab: RightPanelTab;\r\n activeSectionType: string | null;\r\n activeSectionPos: number | null;\r\n regenerate: boolean;\r\n chatReferences: ChatReference[];\r\n pendingChatMessage: string | null;\r\n}\r\n\r\ninterface EditorState {\r\n editor: Editor | null;\r\n document: JSONContent | null;\r\n selection: { from: number; to: number } | null;\r\n editorLanguage: EditorLanguage;\r\n autoSaveStatus: AutoSaveStatus;\r\n lastSavedAt: Date | null;\r\n ai: AIStreamingState;\r\n aiService: AIServiceAdapter | null;\r\n chatSessionAPI: ChatSessionAPI | null;\r\n chatSessionId: string | null;\r\n rightPanel: RightPanelState;\r\n setEditor: (editor: Editor) => void;\r\n setDocument: (document: JSONContent) => void;\r\n setSelection: (selection: { from: number; to: number }) => void;\r\n setEditorLanguage: (language: EditorLanguage) => void;\r\n setAutoSaveStatus: (status: AutoSaveStatus) => void;\r\n setLastSavedAt: (date: Date | null) => void;\r\n setAIStatus: (status: AIStatus, sectionType?: string | null) => void;\r\n setAIAbort: (abortFn: (() => void) | null) => void;\r\n resetAI: () => void;\r\n setAIService: (adapter: AIServiceAdapter | null) => void;\r\n setChatSessionAPI: (api: ChatSessionAPI | null) => void;\r\n setChatSessionId: (id: string | null) => void;\r\n setActiveSection: (sectionType: string, sectionPos: number) => void;\r\n openDraftingPanel: (sectionType: string, sectionPos: number, regenerate?: boolean) => void;\r\n openChatPanel: () => void;\r\n setRightPanelTab: (tab: RightPanelTab) => void;\r\n closeRightPanel: () => void;\r\n addChatReference: (ref: Omit<ChatReference, 'id'>) => void;\r\n removeChatReference: (id: string) => void;\r\n clearChatReferences: () => void;\r\n setPendingChatMessage: (msg: string | null) => void;\r\n}\r\n\r\nconst defaultRightPanel: RightPanelState = {\r\n visible: true,\r\n activeTab: 'chat',\r\n activeSectionType: null,\r\n activeSectionPos: null,\r\n regenerate: false,\r\n chatReferences: [],\r\n pendingChatMessage: null,\r\n};\r\n\r\nexport const useEditorStore = create<EditorState>((set) => ({\r\n editor: null,\r\n document: null,\r\n selection: null,\r\n editorLanguage: 'zh',\r\n autoSaveStatus: 'idle',\r\n lastSavedAt: null,\r\n ai: { status: 'idle', activeSectionType: null, requestId: null, abortFn: null },\r\n aiService: null,\r\n chatSessionAPI: null,\r\n chatSessionId: null,\r\n rightPanel: { ...defaultRightPanel },\r\n setEditor: (editor) => set({ editor }),\r\n setDocument: (document) => set({ document }),\r\n setSelection: (selection) => set({ selection }),\r\n setEditorLanguage: (editorLanguage) => set({ editorLanguage }),\r\n setAutoSaveStatus: (autoSaveStatus) => set({ autoSaveStatus }),\r\n setLastSavedAt: (lastSavedAt) => set({ lastSavedAt }),\r\n setAIStatus: (status, sectionType) =>\r\n set((state) => ({\r\n ai: {\r\n ...state.ai,\r\n status,\r\n activeSectionType: sectionType ?? state.ai.activeSectionType,\r\n requestId: status === 'streaming' ? `req_${Date.now()}` : state.ai.requestId,\r\n },\r\n })),\r\n setAIAbort: (abortFn) =>\r\n set((state) => ({ ai: { ...state.ai, abortFn } })),\r\n resetAI: () =>\r\n set({ ai: { status: 'idle', activeSectionType: null, requestId: null, abortFn: null } }),\r\n setAIService: (adapter) => set({ aiService: adapter }),\r\n setChatSessionAPI: (api) => set({ chatSessionAPI: api }),\r\n setChatSessionId: (id) => set({ chatSessionId: id }),\r\n setActiveSection: (sectionType, sectionPos) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n activeSectionType: sectionType,\r\n activeSectionPos: sectionPos,\r\n regenerate: false,\r\n },\r\n })),\r\n openDraftingPanel: (sectionType, sectionPos, regenerate = false) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n visible: true,\r\n activeTab: 'drafting',\r\n activeSectionType: sectionType,\r\n activeSectionPos: sectionPos,\r\n regenerate,\r\n },\r\n })),\r\n openChatPanel: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, visible: true, activeTab: 'chat' },\r\n })),\r\n setRightPanelTab: (tab) =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, activeTab: tab },\r\n })),\r\n closeRightPanel: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, visible: false },\r\n })),\r\n addChatReference: (ref) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n chatReferences: [\r\n ...state.rightPanel.chatReferences,\r\n { ...ref, id: `ref_${Date.now()}_${Math.random().toString(36).slice(2, 6)}` },\r\n ],\r\n },\r\n })),\r\n removeChatReference: (id) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n chatReferences: state.rightPanel.chatReferences.filter((r) => r.id !== id),\r\n },\r\n })),\r\n clearChatReferences: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, chatReferences: [] },\r\n })),\r\n setPendingChatMessage: (msg) =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, pendingChatMessage: msg },\r\n })),\r\n}));\r\n","import React, {\r\n forwardRef,\r\n useEffect,\r\n useImperativeHandle,\r\n useState,\r\n useCallback,\r\n useRef,\r\n useLayoutEffect,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { ReactRenderer } from '@tiptap/react';\r\nimport tippy, { Instance as TippyInstance } from 'tippy.js';\r\nimport type { SuggestionOptions, SuggestionProps, SuggestionKeyDownProps } from '@tiptap/suggestion';\r\nimport type { SlashCommandItem } from '../editor/extensions/slashCommand';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport { createCommandExecutor } from '../editor/core/EditorCore';\r\n\r\ninterface SlashMenuListProps {\r\n items: SlashCommandItem[];\r\n command: (item: SlashCommandItem) => void;\r\n}\r\n\r\ninterface SlashMenuListRef {\r\n onKeyDown: (props: SuggestionKeyDownProps) => boolean;\r\n}\r\n\r\nconst SlashMenuList = forwardRef<SlashMenuListRef, SlashMenuListProps>(\r\n ({ items, command }, ref) => {\r\n const [selectedIndex, setSelectedIndex] = useState(0);\r\n\r\n useEffect(() => {\r\n setSelectedIndex(0);\r\n }, [items]);\r\n\r\n const selectItem = useCallback(\r\n (index: number) => {\r\n const item = items[index];\r\n if (item) command(item);\r\n },\r\n [items, command]\r\n );\r\n\r\n useImperativeHandle(ref, () => ({\r\n onKeyDown: ({ event }: SuggestionKeyDownProps) => {\r\n if (event.key === 'ArrowUp') {\r\n setSelectedIndex((prev) => (prev + items.length - 1) % items.length);\r\n return true;\r\n }\r\n if (event.key === 'ArrowDown') {\r\n setSelectedIndex((prev) => (prev + 1) % items.length);\r\n return true;\r\n }\r\n if (event.key === 'Enter') {\r\n selectItem(selectedIndex);\r\n return true;\r\n }\r\n return false;\r\n },\r\n }));\r\n\r\n if (!items.length) {\r\n return (\r\n <div className=\"slash-menu\">\r\n <div className=\"slash-menu-empty\">No results</div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"slash-menu\">\r\n {items.map((item, index) => (\r\n <button\r\n key={item.title}\r\n className={`slash-menu-item ${index === selectedIndex ? 'slash-menu-item--active' : ''}`}\r\n onClick={() => selectItem(index)}\r\n onMouseEnter={() => setSelectedIndex(index)}\r\n >\r\n <span className=\"slash-menu-icon\">{item.icon}</span>\r\n <div className=\"slash-menu-text\">\r\n <span className=\"slash-menu-title\">{item.title}</span>\r\n <span className=\"slash-menu-desc\">{item.description}</span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n }\r\n);\r\n\r\nSlashMenuList.displayName = 'SlashMenuList';\r\n\r\nexport function getSlashCommandItems(lang: 'zh' | 'en'): SlashCommandItem[] {\r\n const zh = lang === 'zh';\r\n return [\r\n {\r\n title: zh ? '段落' : 'Paragraph',\r\n description: zh ? '普通文本段落' : 'Plain text paragraph',\r\n icon: '¶',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setParagraph().run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 1' : 'Heading 1',\r\n description: zh ? '大标题' : 'Large heading',\r\n icon: 'H1',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 1 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 2' : 'Heading 2',\r\n description: zh ? '中标题' : 'Medium heading',\r\n icon: 'H2',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 2 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 3' : 'Heading 3',\r\n description: zh ? '小标题' : 'Small heading',\r\n icon: 'H3',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 3 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '无序列表' : 'Bullet List',\r\n description: zh ? '创建无序列表' : 'Create a bullet list',\r\n icon: '•',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleBulletList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '有序列表' : 'Ordered List',\r\n description: zh ? '创建有序列表' : 'Create a numbered list',\r\n icon: '1.',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleOrderedList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '任务列表' : 'Task List',\r\n description: zh ? '创建待办列表' : 'Create a task list',\r\n icon: '☑',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleTaskList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '引用' : 'Blockquote',\r\n description: zh ? '创建引用块' : 'Create a blockquote',\r\n icon: '❝',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleBlockquote().run();\r\n },\r\n },\r\n {\r\n title: zh ? '代码块' : 'Code Block',\r\n description: zh ? '插入代码块' : 'Insert a code block',\r\n icon: '<>',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleCodeBlock().run();\r\n },\r\n },\r\n {\r\n title: zh ? '表格' : 'Table',\r\n description: zh ? '插入 3×3 表格' : 'Insert a 3×3 table',\r\n icon: '⊞',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '分割线' : 'Horizontal Rule',\r\n description: zh ? '插入水平分割线' : 'Insert a horizontal rule',\r\n icon: '─',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHorizontalRule().run();\r\n },\r\n },\r\n {\r\n title: zh ? '图片' : 'Image',\r\n description: zh ? '插入图片(URL)' : 'Insert an image (URL)',\r\n icon: '🖼',\r\n command: ({ editor, range }) => {\r\n const url = window.prompt(zh ? '请输入图片 URL' : 'Enter image URL');\r\n if (url) {\r\n editor.chain().focus().deleteRange(range).setImage({ src: url }).run();\r\n }\r\n },\r\n },\r\n {\r\n title: zh ? '权利要求' : 'Claim',\r\n description: zh ? '插入权利要求条目 (Ctrl+Shift+C)' : 'Insert a patent claim block (Ctrl+Shift+C)',\r\n icon: '§',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).run();\r\n const executor = createCommandExecutor(editor);\r\n void executor.execCommand('insertClaim');\r\n },\r\n },\r\n ];\r\n}\r\n\r\nexport function createSlashSuggestion(): Partial<SuggestionOptions<SlashCommandItem>> {\r\n return {\r\n char: '/',\r\n items: ({ query }) => {\r\n const lang = useEditorStore.getState().editorLanguage;\r\n const all = getSlashCommandItems(lang);\r\n if (!query) return all;\r\n const lower = query.toLowerCase();\r\n return all.filter(\r\n (item) =>\r\n item.title.toLowerCase().includes(lower) ||\r\n item.description.toLowerCase().includes(lower)\r\n );\r\n },\r\n render: () => {\r\n let component: ReactRenderer<SlashMenuListRef> | null = null;\r\n let popup: TippyInstance[] | null = null;\r\n\r\n return {\r\n onStart: (props: SuggestionProps<SlashCommandItem>) => {\r\n component = new ReactRenderer(SlashMenuList, {\r\n props,\r\n editor: props.editor,\r\n });\r\n\r\n if (!props.clientRect) return;\r\n\r\n popup = tippy('body', {\r\n getReferenceClientRect: props.clientRect as () => DOMRect,\r\n appendTo: () => document.body,\r\n content: component.element,\r\n showOnCreate: true,\r\n interactive: true,\r\n trigger: 'manual',\r\n placement: 'bottom-start',\r\n });\r\n },\r\n onUpdate: (props: SuggestionProps<SlashCommandItem>) => {\r\n component?.updateProps(props);\r\n if (popup && props.clientRect) {\r\n popup[0].setProps({\r\n getReferenceClientRect: props.clientRect as () => DOMRect,\r\n });\r\n }\r\n },\r\n onKeyDown: (props: SuggestionKeyDownProps) => {\r\n if (props.event.key === 'Escape') {\r\n popup?.[0]?.hide();\r\n return true;\r\n }\r\n return component?.ref?.onKeyDown(props) ?? false;\r\n },\r\n onExit: () => {\r\n popup?.[0]?.destroy();\r\n component?.destroy();\r\n },\r\n };\r\n },\r\n };\r\n}\r\n","import { Extension } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\n\r\nexport interface SearchReplaceStorage {\r\n searchTerm: string;\r\n replaceTerm: string;\r\n caseSensitive: boolean;\r\n results: { from: number; to: number }[];\r\n currentIndex: number;\r\n}\r\n\r\nexport const SearchReplacePluginKey = new PluginKey('searchReplace');\r\n\r\nfunction findMatches(doc: any, searchTerm: string, caseSensitive: boolean): { from: number; to: number }[] {\r\n if (!searchTerm) return [];\r\n const results: { from: number; to: number }[] = [];\r\n const text = doc.textBetween(0, doc.content.size, '\\n', '\\0');\r\n const term = caseSensitive ? searchTerm : searchTerm.toLowerCase();\r\n const haystack = caseSensitive ? text : text.toLowerCase();\r\n\r\n let pos = 0;\r\n while (pos < haystack.length) {\r\n const idx = haystack.indexOf(term, pos);\r\n if (idx === -1) break;\r\n\r\n let docFrom = 0;\r\n let charCount = 0;\r\n let fromPos = -1;\r\n let toPos = -1;\r\n\r\n doc.descendants((node: any, nodePos: number) => {\r\n if (fromPos !== -1 && toPos !== -1) return false;\r\n if (node.isText) {\r\n const nodeText = node.text || '';\r\n for (let i = 0; i < nodeText.length; i++) {\r\n if (charCount === idx) fromPos = nodePos + i;\r\n if (charCount === idx + term.length) {\r\n toPos = nodePos + i;\r\n return false;\r\n }\r\n charCount++;\r\n }\r\n if (charCount === idx + term.length && toPos === -1) {\r\n toPos = nodePos + nodeText.length;\r\n }\r\n } else if (node.isBlock && charCount > 0) {\r\n if (charCount === idx) fromPos = nodePos;\r\n charCount++;\r\n }\r\n return true;\r\n });\r\n\r\n if (fromPos !== -1 && toPos !== -1) {\r\n results.push({ from: fromPos, to: toPos });\r\n }\r\n pos = idx + 1;\r\n }\r\n\r\n return results;\r\n}\r\n\r\nexport const SearchReplace = Extension.create<{}, SearchReplaceStorage>({\r\n name: 'searchReplace',\r\n\r\n addStorage() {\r\n return {\r\n searchTerm: '',\r\n replaceTerm: '',\r\n caseSensitive: false,\r\n results: [],\r\n currentIndex: 0,\r\n };\r\n },\r\n\r\n addCommands() {\r\n return {\r\n setSearchTerm: (term: string) => ({ editor }) => {\r\n this.storage.searchTerm = term;\r\n this.storage.results = findMatches(editor.state.doc, term, this.storage.caseSensitive);\r\n this.storage.currentIndex = this.storage.results.length > 0 ? 0 : -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n setReplaceTerm: (term: string) => () => {\r\n this.storage.replaceTerm = term;\r\n return true;\r\n },\r\n setCaseSensitive: (val: boolean) => ({ editor }) => {\r\n this.storage.caseSensitive = val;\r\n this.storage.results = findMatches(editor.state.doc, this.storage.searchTerm, val);\r\n this.storage.currentIndex = this.storage.results.length > 0 ? 0 : -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n nextSearchResult: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n this.storage.currentIndex = (this.storage.currentIndex + 1) % this.storage.results.length;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (r) {\r\n editor.commands.setTextSelection(r);\r\n scrollToSelection(editor);\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n previousSearchResult: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n this.storage.currentIndex =\r\n (this.storage.currentIndex - 1 + this.storage.results.length) % this.storage.results.length;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (r) {\r\n editor.commands.setTextSelection(r);\r\n scrollToSelection(editor);\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n replaceCurrent: () => ({ editor }) => {\r\n if (this.storage.results.length === 0 || this.storage.currentIndex < 0) return false;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (!r) return false;\r\n editor.chain().focus().insertContentAt(r, this.storage.replaceTerm).run();\r\n this.storage.results = findMatches(editor.state.doc, this.storage.searchTerm, this.storage.caseSensitive);\r\n if (this.storage.currentIndex >= this.storage.results.length) {\r\n this.storage.currentIndex = 0;\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n replaceAll: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n const { searchTerm, replaceTerm, caseSensitive } = this.storage;\r\n let matches = findMatches(editor.state.doc, searchTerm, caseSensitive);\r\n const tr = editor.state.tr;\r\n let offset = 0;\r\n for (const m of matches) {\r\n const from = m.from + offset;\r\n const to = m.to + offset;\r\n tr.insertText(replaceTerm, from, to);\r\n offset += replaceTerm.length - (m.to - m.from);\r\n }\r\n editor.view.dispatch(tr);\r\n this.storage.results = [];\r\n this.storage.currentIndex = -1;\r\n return true;\r\n },\r\n clearSearch: () => ({ editor }) => {\r\n this.storage.searchTerm = '';\r\n this.storage.replaceTerm = '';\r\n this.storage.results = [];\r\n this.storage.currentIndex = -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n } as any;\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n 'Mod-f': () => {\r\n const event = new CustomEvent('editor:toggleSearch');\r\n window.dispatchEvent(event);\r\n return true;\r\n },\r\n 'Mod-h': () => {\r\n const event = new CustomEvent('editor:toggleSearch', { detail: { replace: true } });\r\n window.dispatchEvent(event);\r\n return true;\r\n },\r\n };\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n const storage = this.storage;\r\n return [\r\n new Plugin({\r\n key: SearchReplacePluginKey,\r\n props: {\r\n decorations: (state) => {\r\n if (!storage.searchTerm || storage.results.length === 0) {\r\n return DecorationSet.empty;\r\n }\r\n const decorations = storage.results.map((r, i) => {\r\n const className = i === storage.currentIndex ? 'search-highlight search-highlight--current' : 'search-highlight';\r\n return Decoration.inline(r.from, r.to, { class: className });\r\n });\r\n return DecorationSet.create(state.doc, decorations);\r\n },\r\n },\r\n }),\r\n ];\r\n },\r\n});\r\n\r\nfunction scrollToSelection(editor: any) {\r\n requestAnimationFrame(() => {\r\n const dom = editor.view.domAtPos(editor.state.selection.from);\r\n if (dom?.node) {\r\n const el = dom.node instanceof HTMLElement ? dom.node : dom.node.parentElement;\r\n el?.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n }\r\n });\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Node as PMNode } from '@tiptap/pm/model';\r\nimport type { AIPatchData, ChatReference } from './aiService';\r\nimport { diff_match_patch } from 'diff-match-patch';\r\n\r\n// diff-match-patch constants\r\nconst DIFF_DELETE = -1;\r\nconst DIFF_INSERT = 1;\r\nconst DIFF_EQUAL = 0;\r\n\r\n// Lazy singleton\r\nlet _dmp: InstanceType<typeof diff_match_patch> | null = null;\r\nfunction getDmp(): InstanceType<typeof diff_match_patch> {\r\n if (!_dmp) _dmp = new diff_match_patch();\r\n return _dmp;\r\n}\r\n\r\nexport interface AIPatch {\r\n id: string;\r\n type: 'insert' | 'replace' | 'delete';\r\n from: number;\r\n to: number;\r\n content: string;\r\n originalText?: string;\r\n reason?: string;\r\n status: 'pending' | 'accepted' | 'rejected';\r\n}\r\n\r\nexport const PatchDiffPluginKey = new PluginKey('patchDiff');\r\n\r\n// ── Resolve semantic patch target to absolute positions ──\r\n\r\ninterface ResolvedRange {\r\n from: number;\r\n to: number;\r\n}\r\n\r\n/**\r\n * Find a patent_section node by sectionType, return its content range.\r\n */\r\nfunction findSectionRange(editor: Editor, sectionType: string): ResolvedRange | null {\r\n let result: ResolvedRange | null = null;\r\n editor.state.doc.descendants((node, pos) => {\r\n if (result) return false;\r\n if (node.type.name === 'patent_section' && node.attrs.sectionType === sectionType) {\r\n result = { from: pos + 1, to: pos + node.nodeSize - 1 };\r\n return false;\r\n }\r\n return true;\r\n });\r\n return result;\r\n}\r\n\r\n/**\r\n * A text segment mapping: textIdx in the concatenated string → docPos in ProseMirror.\r\n */\r\nexport interface TextSegment {\r\n textIdx: number;\r\n docPos: number;\r\n len: number;\r\n}\r\n\r\n/**\r\n * Build a concatenated text string that exactly mirrors `doc.textBetween(from, to, '\\0', '\\0')`\r\n * and simultaneously record position-mapping segments for every text node slice.\r\n *\r\n * ProseMirror's `textBetween` inserts `blockSeparator` before a block node\r\n * only when `!separated` (i.e. text/leaf content appeared before it).\r\n * The old implementation incorrectly counted `charCount++` for every non-leaf\r\n * non-text node, which over-counted for wrapper nodes like `patent_section`.\r\n */\r\nexport function buildTextMap(\r\n editor: Editor,\r\n rangeFrom: number,\r\n rangeTo: number,\r\n): { text: string; segments: TextSegment[] } {\r\n const segments: TextSegment[] = [];\r\n let text = '';\r\n let separated = true; // mirrors ProseMirror textBetween initial state\r\n\r\n editor.state.doc.nodesBetween(rangeFrom, rangeTo, (node, pos) => {\r\n if (node.isText) {\r\n const nodeStart = pos;\r\n const sliceFrom = Math.max(rangeFrom, nodeStart) - nodeStart;\r\n const sliceTo = Math.min(rangeTo, nodeStart + node.nodeSize) - nodeStart;\r\n const slice = node.text!.slice(sliceFrom, sliceTo);\r\n segments.push({ textIdx: text.length, docPos: nodeStart + sliceFrom, len: slice.length });\r\n text += slice;\r\n separated = false;\r\n } else if (node.isLeaf) {\r\n // leafText — mirrors textBetween's leafText parameter ('\\0')\r\n text += '\\0';\r\n separated = false;\r\n } else if (!separated && node.isBlock) {\r\n // blockSeparator — only inserted between consecutive text-bearing blocks\r\n text += '\\0';\r\n separated = true;\r\n }\r\n });\r\n\r\n return { text, segments };\r\n}\r\n\r\n/**\r\n * Convert a text offset (in the concatenated string from buildTextMap)\r\n * to an absolute ProseMirror document position.\r\n */\r\nexport function textOffsetToDocPos(segments: TextSegment[], offset: number): number {\r\n for (const seg of segments) {\r\n if (offset >= seg.textIdx && offset <= seg.textIdx + seg.len) {\r\n return seg.docPos + (offset - seg.textIdx);\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\n/**\r\n * Search for a text string within a document range [rangeFrom, rangeTo].\r\n * `skipPositions` is an optional set of doc positions to skip (avoid matching\r\n * ranges that are already claimed by earlier patches in the same section).\r\n * Returns the first non-skipped match position, or null.\r\n */\r\nfunction searchTextInRange(\r\n editor: Editor,\r\n searchText: string,\r\n rangeFrom: number,\r\n rangeTo: number,\r\n skipPositions?: Set<number>,\r\n): ResolvedRange | null {\r\n const { text, segments } = buildTextMap(editor, rangeFrom, rangeTo);\r\n\r\n let searchStart = 0;\r\n while (searchStart <= text.length - searchText.length) {\r\n const idx = text.indexOf(searchText, searchStart);\r\n if (idx === -1) return null;\r\n\r\n const matchFrom = textOffsetToDocPos(segments, idx);\r\n const matchTo = textOffsetToDocPos(segments, idx + searchText.length);\r\n\r\n if (matchFrom >= 0 && matchTo >= 0 && !(skipPositions && skipPositions.has(matchFrom))) {\r\n return { from: matchFrom, to: matchTo };\r\n }\r\n searchStart = idx + 1;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve an AIPatchData (with semantic target) into absolute from/to positions.\r\n * Returns an AIPatch ready for decoration, or null if resolution fails.\r\n */\r\nexport function resolvePatchTarget(\r\n editor: Editor,\r\n patchData: AIPatchData,\r\n refs: ChatReference[],\r\n patchIndex: number,\r\n alreadyResolved?: AIPatch[],\r\n): AIPatch | null {\r\n const target = patchData.target;\r\n let range: ResolvedRange | null = null;\r\n\r\n // Build a set of already-claimed positions to skip during search\r\n const claimedPositions = new Set<number>();\r\n if (alreadyResolved) {\r\n for (const p of alreadyResolved) {\r\n claimedPositions.add(p.from);\r\n }\r\n }\r\n\r\n // Step 1: Resolve target to a search scope\r\n if (!target) {\r\n // Legacy: use from/to directly\r\n if (patchData.from != null && patchData.to != null) {\r\n range = { from: patchData.from, to: patchData.to };\r\n }\r\n } else if (target.type === 'section' && target.sectionType) {\r\n range = findSectionRange(editor, target.sectionType);\r\n } else if (target.type === 'ref' && target.refIndex != null) {\r\n const ref = refs[target.refIndex];\r\n if (ref?.from != null && ref?.to != null) {\r\n range = { from: ref.from, to: ref.to };\r\n }\r\n } else if (target.type === 'search' && target.searchText) {\r\n range = searchTextInRange(editor, target.searchText, 0, editor.state.doc.content.size, claimedPositions);\r\n }\r\n\r\n if (!range) return null;\r\n\r\n // Step 2: If there's a search field, narrow down within the resolved range\r\n let finalRange = range;\r\n if (patchData.search) {\r\n const narrowed = searchTextInRange(editor, patchData.search, range.from, range.to, claimedPositions);\r\n if (narrowed) {\r\n finalRange = narrowed;\r\n }\r\n // If search fails, fallback to the full range\r\n }\r\n\r\n // Step 3: Build AIPatch\r\n const origText = (finalRange.from < finalRange.to)\r\n ? editor.state.doc.textBetween(finalRange.from, finalRange.to, ' ', '\\0')\r\n : '';\r\n\r\n return {\r\n id: `patch_${Date.now()}_${patchIndex}`,\r\n type: patchData.op === 'delete' ? 'delete' : patchData.op === 'insert' ? 'insert' : 'replace',\r\n from: finalRange.from,\r\n to: patchData.op === 'insert' ? finalRange.from : finalRange.to,\r\n content: patchData.content || '',\r\n originalText: origText,\r\n reason: patchData.reason,\r\n status: 'pending',\r\n };\r\n}\r\n\r\nlet pendingPatches: AIPatch[] = [];\r\nlet patchChangeListeners: Array<() => void> = [];\r\n\r\nexport function onPatchChange(listener: () => void): () => void {\r\n patchChangeListeners.push(listener);\r\n return () => {\r\n patchChangeListeners = patchChangeListeners.filter(l => l !== listener);\r\n };\r\n}\r\n\r\nfunction notifyPatchChange(): void {\r\n patchChangeListeners.forEach(l => l());\r\n}\r\n\r\nexport function getPatches(): AIPatch[] {\r\n return [...pendingPatches];\r\n}\r\n\r\nexport function setPatches(patches: AIPatch[]): void {\r\n pendingPatches = patches;\r\n notifyPatchChange();\r\n}\r\n\r\nexport function clearPatches(): void {\r\n pendingPatches = [];\r\n notifyPatchChange();\r\n}\r\n\r\nexport function acceptPatch(editor: Editor, patchId: string): boolean {\r\n const patch = pendingPatches.find(p => p.id === patchId);\r\n if (!patch || patch.status !== 'pending') return false;\r\n\r\n patch.status = 'accepted';\r\n const { tr } = editor.state;\r\n\r\n if (patch.type === 'delete') {\r\n tr.delete(patch.from, patch.to);\r\n } else if (patch.type === 'insert') {\r\n tr.insertText(patch.content, patch.from);\r\n } else {\r\n // Check if replacement spans a block container's full content (e.g. patent_section)\r\n const needsBlockContent = isBlockContainerContentRange(editor, patch.from, patch.to);\r\n if (needsBlockContent) {\r\n const nodes = textToParagraphs(editor, patch.content);\r\n tr.replaceWith(patch.from, patch.to, nodes);\r\n } else {\r\n tr.insertText(patch.content, patch.from, patch.to);\r\n }\r\n }\r\n\r\n editor.view.dispatch(tr);\r\n\r\n // Use ProseMirror mapping to remap remaining patches' positions.\r\n // This correctly handles any kind of replacement (block, inline, etc.)\r\n const mapping = tr.mapping;\r\n for (const p of pendingPatches) {\r\n if (p.id === patchId || p.status !== 'pending') continue;\r\n const newFrom = mapping.map(p.from, 1);\r\n const newTo = mapping.map(p.to, -1);\r\n if (newFrom >= newTo && p.type !== 'insert') {\r\n // Range collapsed — the accepted patch consumed this one's range\r\n p.status = 'rejected';\r\n } else {\r\n p.from = newFrom;\r\n p.to = p.type === 'insert' ? newFrom : newTo;\r\n }\r\n }\r\n\r\n pendingPatches = pendingPatches.filter(p => p.id !== patchId && p.status === 'pending');\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n return true;\r\n}\r\n\r\nexport function rejectPatch(editor: Editor, patchId: string): boolean {\r\n const patch = pendingPatches.find(p => p.id === patchId);\r\n if (!patch || patch.status !== 'pending') return false;\r\n\r\n patch.status = 'rejected';\r\n pendingPatches = pendingPatches.filter(p => p.id !== patchId);\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n return true;\r\n}\r\n\r\nexport function acceptAllPatches(editor: Editor): void {\r\n const pending = pendingPatches.filter(p => p.status === 'pending');\r\n const sorted = [...pending].sort((a, b) => b.from - a.from);\r\n const { tr } = editor.state;\r\n for (const patch of sorted) {\r\n if (patch.type === 'delete') {\r\n tr.delete(patch.from, patch.to);\r\n } else if (patch.type === 'insert') {\r\n tr.insertText(patch.content, patch.from);\r\n } else {\r\n const needsBlockContent = isBlockContainerContentRange(editor, patch.from, patch.to);\r\n if (needsBlockContent) {\r\n const nodes = textToParagraphs(editor, patch.content);\r\n tr.replaceWith(patch.from, patch.to, nodes);\r\n } else {\r\n tr.insertText(patch.content, patch.from, patch.to);\r\n }\r\n }\r\n }\r\n editor.view.dispatch(tr);\r\n pendingPatches = [];\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n}\r\n\r\nexport function rejectAllPatches(editor: Editor): void {\r\n pendingPatches = [];\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n}\r\n\r\nfunction refreshDecorations(editor: Editor): void {\r\n editor.view.dispatch(editor.state.tr.setMeta(PatchDiffPluginKey, true));\r\n}\r\n\r\n/**\r\n * Collect all inline text ranges within a block range [from, to].\r\n * Inline decorations cannot span across block boundaries, so we\r\n * need to find each text block's range and decorate individually.\r\n */\r\nfunction getInlineRanges(\r\n doc: PMNode,\r\n from: number,\r\n to: number\r\n): Array<{ from: number; to: number }> {\r\n const ranges: Array<{ from: number; to: number }> = [];\r\n doc.nodesBetween(from, to, (node, pos) => {\r\n if (node.isTextblock) {\r\n const blockStart = pos + 1; // inside the textblock\r\n const blockEnd = pos + node.nodeSize - 1;\r\n const rangeFrom = Math.max(blockStart, from);\r\n const rangeTo = Math.min(blockEnd, to);\r\n if (rangeTo > rangeFrom) {\r\n ranges.push({ from: rangeFrom, to: rangeTo });\r\n }\r\n return false; // don't descend into text nodes\r\n }\r\n return true;\r\n });\r\n return ranges;\r\n}\r\n\r\n/**\r\n * For a single-textblock replace patch, compute fine-grained word-level\r\n * diff decorations using diff-match-patch. Returns null if:\r\n * - patch spans multiple textblocks (fall back to whole-block)\r\n * - EQUAL ratio < 30% (mostly rewritten → whole-block is clearer)\r\n */\r\nfunction computeFineDiff(\r\n doc: PMNode,\r\n patch: AIPatch,\r\n): Decoration[] | null {\r\n if (!patch.originalText || !patch.content) return null;\r\n\r\n // Only use fine diff for single-textblock patches\r\n try {\r\n const $from = doc.resolve(patch.from);\r\n const $to = doc.resolve(patch.to);\r\n if ($from.parent !== $to.parent || !$from.parent.isTextblock) return null;\r\n } catch {\r\n return null;\r\n }\r\n\r\n const inst = getDmp();\r\n const diffs = inst.diff_main(patch.originalText, patch.content);\r\n inst.diff_cleanupSemantic(diffs);\r\n\r\n // Check EQUAL ratio — if too low, whole-block coloring is clearer\r\n const equalLen = diffs\r\n .filter(([op]) => op === DIFF_EQUAL)\r\n .reduce((sum, [, text]) => sum + text.length, 0);\r\n if (patch.originalText.length > 0 && equalLen / patch.originalText.length < 0.3) return null;\r\n\r\n const decorations: Decoration[] = [];\r\n let docPos = patch.from; // cursor in the document (advances for EQUAL and DELETE)\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === DIFF_EQUAL) {\r\n // Unchanged text — no decoration, advance cursor\r\n docPos += text.length;\r\n } else if (op === DIFF_DELETE) {\r\n // Red strikethrough on the exact deleted characters\r\n const delEnd = docPos + text.length;\r\n decorations.push(\r\n Decoration.inline(docPos, delEnd, {\r\n class: 'patch-diff-delete',\r\n 'data-patch-id': patch.id,\r\n })\r\n );\r\n docPos = delEnd;\r\n } else if (op === DIFF_INSERT) {\r\n // Green widget right at the deletion/cursor point\r\n decorations.push(\r\n Decoration.widget(docPos, () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-insert-inline';\r\n el.textContent = text;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n }, { side: 1 })\r\n );\r\n // docPos does NOT advance — inserts don't exist in the original doc\r\n }\r\n }\r\n\r\n return decorations;\r\n}\r\n\r\nexport function createPatchDiffPlugin(): Plugin {\r\n return new Plugin({\r\n key: PatchDiffPluginKey,\r\n props: {\r\n decorations(state) {\r\n const pending = pendingPatches.filter(p => p.status === 'pending');\r\n if (pending.length === 0) return DecorationSet.empty;\r\n\r\n const decorations: Decoration[] = [];\r\n for (const patch of pending) {\r\n // For replace: try fine-grained inline diff first\r\n if (patch.type === 'replace') {\r\n const fineDiffs = computeFineDiff(state.doc, patch);\r\n if (fineDiffs) {\r\n decorations.push(...fineDiffs);\r\n continue; // skip whole-block fallback\r\n }\r\n }\r\n\r\n if (patch.type === 'delete' || patch.type === 'replace') {\r\n // Whole-block fallback: 删除/替换 — 原文全部标红 + 删除线\r\n const ranges = getInlineRanges(state.doc, patch.from, patch.to);\r\n for (const range of ranges) {\r\n decorations.push(\r\n Decoration.inline(range.from, range.to, {\r\n class: 'patch-diff-delete',\r\n 'data-patch-id': patch.id,\r\n })\r\n );\r\n }\r\n\r\n if (patch.type === 'replace') {\r\n // 在原文之后插入绿色新内容 widget\r\n const widgetPos = ranges.length > 0 ? ranges[ranges.length - 1].to : patch.to;\r\n const isLong = patch.content.length > 120 || patch.content.includes('\\n');\r\n decorations.push(\r\n Decoration.widget(widgetPos, () => {\r\n const el = document.createElement(isLong ? 'div' : 'span');\r\n el.className = isLong\r\n ? 'patch-diff-insert-inline patch-diff-insert-block'\r\n : 'patch-diff-insert-inline';\r\n el.textContent = patch.content;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n }, { side: 1 })\r\n );\r\n }\r\n } else {\r\n // 插入:绿色 widget 显示新内容\r\n decorations.push(\r\n Decoration.widget(patch.from, () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-insert-inline';\r\n el.textContent = patch.content;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n })\r\n );\r\n }\r\n }\r\n return DecorationSet.create(state.doc, decorations);\r\n },\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Check if a position range spans the full content of a block container node\r\n * (e.g. patent_section with content: 'block+'). In that case, we need to\r\n * replace with block-level nodes instead of using insertText.\r\n */\r\nfunction isBlockContainerContentRange(editor: Editor, from: number, to: number): boolean {\r\n const $from = editor.state.doc.resolve(from);\r\n const parent = $from.parent;\r\n // If parent requires block content and range covers its full content\r\n if (parent.type.spec.content?.includes('block') && from === $from.start() && to === $from.end()) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Convert plain text into an array of paragraph nodes,\r\n * splitting by double newlines for paragraph breaks.\r\n */\r\nfunction textToParagraphs(editor: Editor, text: string): PMNode[] {\r\n const schema = editor.state.schema;\r\n const paragraphs = text.split(/\\n\\n+/);\r\n return paragraphs\r\n .filter(p => p.trim().length > 0)\r\n .map(p => {\r\n const content = p.replace(/\\n/g, ' ').trim();\r\n return schema.nodes.paragraph.create(\r\n null,\r\n content ? schema.text(content) : undefined\r\n );\r\n });\r\n}\r\n","import Document from '@tiptap/extension-document';\r\nimport Paragraph from '@tiptap/extension-paragraph';\r\nimport Text from '@tiptap/extension-text';\r\nimport Heading from '@tiptap/extension-heading';\r\nimport BulletList from '@tiptap/extension-bullet-list';\r\nimport OrderedList from '@tiptap/extension-ordered-list';\r\nimport ListItem from '@tiptap/extension-list-item';\r\nimport Blockquote from '@tiptap/extension-blockquote';\r\nimport CodeBlock from '@tiptap/extension-code-block';\r\nimport HorizontalRule from '@tiptap/extension-horizontal-rule';\r\nimport TaskList from '@tiptap/extension-task-list';\r\nimport TaskItem from '@tiptap/extension-task-item';\r\nimport Image from '@tiptap/extension-image';\r\nimport { Table } from '@tiptap/extension-table';\r\nimport TableRow from '@tiptap/extension-table-row';\r\nimport TableCell from '@tiptap/extension-table-cell';\r\nimport TableHeader from '@tiptap/extension-table-header';\r\nimport Placeholder from '@tiptap/extension-placeholder';\r\nimport History from '@tiptap/extension-history';\r\nimport { Extension, Node } from '@tiptap/react';\r\nimport { dropCursor } from 'prosemirror-dropcursor';\r\nimport { gapCursor } from 'prosemirror-gapcursor';\r\nimport TextAlign from '@tiptap/extension-text-align';\r\nimport { SlashCommand } from '../extensions/slashCommand';\r\nimport { createSlashSuggestion } from '../../components/SlashMenu';\r\nimport { SearchReplace } from '../extensions/searchReplace';\r\nimport { createPatchDiffPlugin } from '../ai/patchDiff';\r\n\r\nconst HardBreak = Node.create({\r\n name: 'hardBreak',\r\n inline: true,\r\n group: 'inline',\r\n selectable: false,\r\n parseHTML() {\r\n return [{ tag: 'br' }];\r\n },\r\n renderHTML() {\r\n return ['br'];\r\n },\r\n addKeyboardShortcuts() {\r\n return {\r\n 'Shift-Enter': () => {\r\n const nodeType = this.editor.schema.nodes.hardBreak;\r\n if (!nodeType) return false;\r\n const tr = this.editor.state.tr.replaceSelectionWith(nodeType.create()).scrollIntoView();\r\n this.editor.view.dispatch(tr);\r\n return true;\r\n },\r\n };\r\n },\r\n});\r\n\r\nconst DragDropUX = Extension.create({\r\n name: 'dragDropUX',\r\n addProseMirrorPlugins() {\r\n return [\r\n dropCursor({\r\n width: 3,\r\n color: '#2563eb',\r\n }),\r\n gapCursor(),\r\n ];\r\n },\r\n});\r\n\r\nconst PatchDiffExtension = Extension.create({\r\n name: 'patchDiff',\r\n addProseMirrorPlugins() {\r\n return [createPatchDiffPlugin()];\r\n },\r\n});\r\n\r\nexport const baseNodes = [\r\n Document,\r\n Paragraph,\r\n Text,\r\n DragDropUX,\r\n Heading.configure({\r\n levels: [1, 2, 3, 4, 5, 6],\r\n }),\r\n BulletList,\r\n OrderedList,\r\n ListItem,\r\n Blockquote,\r\n CodeBlock,\r\n HardBreak,\r\n HorizontalRule,\r\n TaskList,\r\n TaskItem.configure({ nested: true }),\r\n Image.extend({\r\n addAttributes() {\r\n return {\r\n ...this.parent?.(),\r\n width: {\r\n default: null,\r\n parseHTML: (element) => element.getAttribute('width') || element.style.width || null,\r\n renderHTML: (attributes) => {\r\n if (!attributes.width) return {};\r\n return { width: attributes.width, style: `width: ${attributes.width}` };\r\n },\r\n },\r\n };\r\n },\r\n }).configure({\r\n inline: true,\r\n allowBase64: true,\r\n }),\r\n Table.configure({\r\n resizable: true,\r\n }),\r\n TableRow,\r\n TableCell,\r\n TableHeader,\r\n Placeholder.configure({\r\n placeholder: ({ node }) => {\r\n if (node.type.name === 'heading') return 'Heading';\r\n return 'Type / for commands...';\r\n },\r\n }),\r\n History,\r\n SlashCommand.configure({\r\n suggestion: createSlashSuggestion(),\r\n }),\r\n SearchReplace,\r\n TextAlign.configure({\r\n types: ['heading', 'paragraph'],\r\n defaultAlignment: 'left',\r\n }),\r\n PatchDiffExtension,\r\n];\r\n","import Bold from '@tiptap/extension-bold';\r\nimport Italic from '@tiptap/extension-italic';\r\nimport Underline from '@tiptap/extension-underline';\r\nimport Strike from '@tiptap/extension-strike';\r\nimport Code from '@tiptap/extension-code';\r\nimport Superscript from '@tiptap/extension-superscript';\r\nimport Subscript from '@tiptap/extension-subscript';\r\nimport Link from '@tiptap/extension-link';\r\nimport { TextStyle } from '@tiptap/extension-text-style';\r\nimport Color from '@tiptap/extension-color';\r\nimport Highlight from '@tiptap/extension-highlight';\r\n\r\nexport const baseMarks = [\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strike,\r\n Code,\r\n Superscript,\r\n Subscript,\r\n Link.configure({\r\n openOnClick: false,\r\n }),\r\n TextStyle,\r\n Color,\r\n Highlight.configure({ multicolor: true }),\r\n];\r\n","import { baseNodes } from './baseNodes';\r\nimport { baseMarks } from './baseMarks';\r\n\r\nexport const schemaExtensions = [\r\n ...baseNodes,\r\n ...baseMarks,\r\n];\r\n","import { CommandCompletionResult, CommandExecutionContext, CommandExecutionOptions, EditorCommand, EditorCommandDefinition } from '../../types/plugin';\r\n\r\ninterface RegisterCommandOptions {\r\n namespace?: string;\r\n override?: boolean;\r\n}\r\n\r\nexport class CommandRegistry {\r\n private commands: Map<string, EditorCommandDefinition> = new Map();\r\n\r\n private normalizeCommand(command: EditorCommand | EditorCommandDefinition): EditorCommandDefinition {\r\n if (typeof command === 'function') {\r\n return {\r\n execute: command,\r\n };\r\n }\r\n return command;\r\n }\r\n\r\n private getFullName(name: string, namespace?: string) {\r\n return namespace ? `${namespace}.${name}` : name;\r\n }\r\n\r\n register(name: string, command: EditorCommand | EditorCommandDefinition, options: RegisterCommandOptions = {}) {\r\n const fullName = this.getFullName(name, options.namespace);\r\n if (this.commands.has(fullName) && !options.override) {\r\n console.warn(`Command \"${fullName}\" is already registered.`);\r\n return fullName;\r\n }\r\n this.commands.set(fullName, this.normalizeCommand(command));\r\n return fullName;\r\n }\r\n\r\n canExecute(name: string, context: CommandExecutionContext, payload?: unknown) {\r\n const command = this.commands.get(name);\r\n if (command) {\r\n if (command.canExecute) {\r\n return command.canExecute(context, payload);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n isActive(name: string, context: CommandExecutionContext) {\r\n const command = this.commands.get(name);\r\n if (!command || !command.isActive) {\r\n return false;\r\n }\r\n return command.isActive(context);\r\n }\r\n\r\n async execute(\r\n name: string,\r\n context: CommandExecutionContext,\r\n payload?: unknown,\r\n options: CommandExecutionOptions = {}\r\n ): Promise<boolean> {\r\n const startedAt = Date.now();\r\n const useTransaction = options.transaction ?? true;\r\n const rollbackOnFail = options.rollbackOnFail ?? true;\r\n const snapshot = useTransaction ? context.editor.getJSON() : null;\r\n const command = this.commands.get(name);\r\n if (!command) {\r\n console.warn(`Command \"${name}\" not found.`);\r\n options.onComplete?.({\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n });\r\n return false;\r\n }\r\n if (!this.canExecute(name, context, payload)) {\r\n options.onComplete?.({\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n });\r\n return false;\r\n }\r\n try {\r\n const result = await command.execute(context, payload);\r\n const success = Boolean(result);\r\n if (!success && snapshot && rollbackOnFail) {\r\n context.editor.commands.setContent(snapshot);\r\n }\r\n const completed: CommandCompletionResult = {\r\n name,\r\n success,\r\n durationMs: Date.now() - startedAt,\r\n };\r\n options.onComplete?.(completed);\r\n return success;\r\n } catch (error) {\r\n if (snapshot && rollbackOnFail) {\r\n context.editor.commands.setContent(snapshot);\r\n }\r\n const completed: CommandCompletionResult = {\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n error,\r\n };\r\n options.onComplete?.(completed);\r\n return false;\r\n }\r\n }\r\n\r\n getCommand(name: string) {\r\n return this.commands.get(name) || null;\r\n }\r\n\r\n getCommands() {\r\n return Array.from(this.commands.keys()).sort();\r\n }\r\n}\r\n\r\nexport const commandRegistry = new CommandRegistry();\r\n","import { Editor, Extension, Node, Mark } from '@tiptap/react';\r\nimport { CommandExecutionContext, CommandExecutionOptions, EditorPlugin, ToolbarItem } from '../../types/plugin';\r\nimport { commandRegistry } from './CommandRegistry';\r\n\r\ntype PluginLifecycleStage = 'register' | 'init' | 'stateSync' | 'destroy';\r\n\r\nexport class PluginManager {\r\n private plugins: Map<string, EditorPlugin> = new Map();\r\n private lifecycleOrder: PluginLifecycleStage[] = ['register', 'init', 'stateSync', 'destroy'];\r\n\r\n private logLifecycle(stage: PluginLifecycleStage, pluginName: string) {\r\n if (stage === 'stateSync') {\r\n return;\r\n }\r\n console.info(`[PluginManager:${stage}] ${pluginName}`);\r\n }\r\n\r\n private getOrderedPlugins() {\r\n return Array.from(this.plugins.values()).sort((a, b) => (a.priority || 0) - (b.priority || 0));\r\n }\r\n\r\n private registerPluginCommands(plugin: EditorPlugin) {\r\n if (!plugin.commands) {\r\n return;\r\n }\r\n Object.entries(plugin.commands).forEach(([commandName, command]) => {\r\n commandRegistry.register(commandName, command, { namespace: plugin.name });\r\n });\r\n }\r\n\r\n register(plugin: EditorPlugin) {\r\n if (this.plugins.has(plugin.name)) {\r\n console.warn(`Plugin \"${plugin.name}\" is already registered.`);\r\n return;\r\n }\r\n if (plugin.dependsOn && plugin.dependsOn.length > 0) {\r\n const missingDependencies = plugin.dependsOn.filter((dependency) => !this.plugins.has(dependency));\r\n if (missingDependencies.length > 0) {\r\n console.warn(`Plugin \"${plugin.name}\" has missing dependencies: ${missingDependencies.join(', ')}`);\r\n }\r\n }\r\n this.plugins.set(plugin.name, plugin);\r\n this.registerPluginCommands(plugin);\r\n this.logLifecycle('register', plugin.name);\r\n }\r\n\r\n getExtensions(): (Extension | Node | Mark)[] {\r\n const extensions: (Extension | Node | Mark)[] = [];\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.extensions) {\r\n extensions.push(...plugin.extensions);\r\n }\r\n });\r\n return extensions;\r\n }\r\n\r\n initializePlugins(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n this.logLifecycle('init', plugin.name);\r\n if (plugin.init) {\r\n plugin.init(editor);\r\n }\r\n });\r\n }\r\n\r\n notifySelectionChange(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.onSelectionChange) {\r\n plugin.onSelectionChange(editor);\r\n }\r\n });\r\n }\r\n\r\n notifyStateChange(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.onStateChange) {\r\n plugin.onStateChange(editor);\r\n }\r\n });\r\n }\r\n\r\n executeCommand(name: string, context: CommandExecutionContext, payload?: unknown, options?: CommandExecutionOptions) {\r\n return commandRegistry.execute(name, context, payload, options);\r\n }\r\n\r\n canExecuteCommand(name: string, context: CommandExecutionContext, payload?: unknown) {\r\n return commandRegistry.canExecute(name, context, payload);\r\n }\r\n\r\n isCommandActive(name: string, context: CommandExecutionContext) {\r\n return commandRegistry.isActive(name, context);\r\n }\r\n\r\n getCommandNames() {\r\n return commandRegistry.getCommands();\r\n }\r\n\r\n getLifecycleOrder() {\r\n return [...this.lifecycleOrder];\r\n }\r\n\r\n getCommandMeta(name: string) {\r\n return commandRegistry.getCommand(name);\r\n }\r\n\r\n getToolbarItems() {\r\n const items: ToolbarItem[] = [];\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (!plugin.toolbarItems) {\r\n return;\r\n }\r\n plugin.toolbarItems.forEach((item) => {\r\n const command = item.command.includes('.') ? item.command : `${plugin.name}.${item.command}`;\r\n items.push({\r\n ...item,\r\n command,\r\n group: item.group || 'technical',\r\n });\r\n });\r\n });\r\n return items;\r\n }\r\n\r\n destroyPlugins(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n this.logLifecycle('destroy', plugin.name);\r\n if (plugin.destroy) {\r\n plugin.destroy(editor);\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport const pluginManager = new PluginManager();\r\n","import type { EditorLanguage } from '../store/editorStore';\r\n\r\ntype ClaimGraphIssueCode =\r\n | 'forward_reference'\r\n | 'self_reference'\r\n | 'cycle_dependency'\r\n | 'too_many_independent'\r\n | 'multi_dependency_conflict';\r\n\r\nconst dict = {\r\n zh: {\r\n language: '语言',\r\n bold: '加粗',\r\n italic: '斜体',\r\n underline: '下划线',\r\n referenceTarget: '引用目标',\r\n referenceTargetPlaceholder: '请选择权利要求',\r\n insertReference: '插入权利要求引用',\r\n figureReferenceTarget: '附图目标',\r\n figureReferenceTargetPlaceholder: '请选择附图',\r\n insertFigureReference: '插入附图引用',\r\n validateClaimGraph: '校验权利要求依赖图',\r\n graphPassed: '依赖图校验通过',\r\n graphIssuesFound: (count: number) => `发现 ${count} 个依赖问题`,\r\n currentClaim: (number: number) => `当前 Claim ${number}`,\r\n dependsOn: '依赖',\r\n noDependencyCandidates: '无可选前置 Claim',\r\n placeCursorToEditDependencies: '将光标放入 Claim 段落后可编辑依赖关系',\r\n deleteSelection: '删除选区',\r\n claimWorkspacePanel: 'Claim 工业化面板',\r\n claimsSectionTitle: '权利要求书',\r\n totalCount: (count: number) => `总数 ${count}`,\r\n claimsSectionEnabled: '已启用 Claims 区',\r\n claimsSectionDisabled: '未启用 Claims 区',\r\n graphIssuesCount: (count: number) => (count === 0 ? '依赖图通过' : `依赖图问题 ${count}`),\r\n createClaimsSection: '创建 Claims 区',\r\n organizeClaimsSection: '整理到 Claims 区',\r\n exportCnipaXml: '导出 CNIPA XML',\r\n exportWordMapping: '导出 Word 映射',\r\n claimDependencyTree: 'Claim 依赖树',\r\n invalidClaimReference: '无效权利要求引用',\r\n invalidFigureReference: '无效附图引用',\r\n claimLabel: (number: number) => `权利要求${number}`,\r\n claimTypeLabel: (claimType: 'independent' | 'dependent' | string) => (claimType === 'dependent' ? '从属项' : '独立项'),\r\n claimInsertHintCreated: '已自动创建 Claim 区并插入新 Claim',\r\n claimInsertHintMoved: '当前光标在区外,已放入 Claim 区',\r\n referenceNavigateTitle: '点击跳转到目标权利要求',\r\n figureReferenceNavigateTitle: '点击跳转到目标附图',\r\n referenceNavigateDisabledTitle: '引用无效,无法跳转',\r\n currentFigure: '当前附图',\r\n figureId: '图号',\r\n figureCaption: '图注',\r\n figureIdConflict: '图号重复,请使用唯一图号',\r\n figureUploadHint: '点击上传或拖拽图片',\r\n figureReplaceImage: '更换图片',\r\n figureDrawioPlaceholder: 'Draw.io 编辑器',\r\n figureContentTypeImage: '图片',\r\n figureContentTypeMermaid: 'Mermaid 图表',\r\n figureContentTypeDrawio: 'Draw.io 图表',\r\n mermaidDoubleClickToEdit: '双击编辑',\r\n mermaidDoubleClickToCreate: '双击编辑 Mermaid 图表',\r\n mermaidSaveAndRender: '保存并渲染',\r\n mermaidCancel: '取消',\r\n mermaidSyntaxError: 'Mermaid 语法错误,请修正后重试',\r\n drawioDoubleClickToEdit: '双击编辑 Draw.io 图表',\r\n // Patent book titles\r\n bookTitle_description: '说明书',\r\n // Patent title placeholder\r\n patentTitlePlaceholder: '专利名称',\r\n // Patent section titles — Invention & Utility Model\r\n sectionTitle_technical_field: '技术领域',\r\n sectionTitle_background_art: '背景技术',\r\n sectionTitle_summary: '发明内容',\r\n sectionTitle_drawing_description: '附图说明',\r\n sectionTitle_detailed_description: '具体实施方式',\r\n sectionTitle_claims: '权利要求书',\r\n sectionTitle_abstract: '摘要',\r\n sectionTitle_abstract_drawing: '摘要附图',\r\n sectionTitle_drawing_figures: '说明书附图',\r\n // Patent section titles — Design\r\n sectionTitle_design_product_name: '产品名称',\r\n sectionTitle_design_usage: '用途说明',\r\n sectionTitle_design_description: '设计说明',\r\n sectionTitle_design_views: '图片或照片',\r\n sectionTitle_design_brief: '简要说明',\r\n // Auto-save\r\n // Figure insert dropdown\r\n insertImageFigure: '图片附图',\r\n insertMermaidFigure: 'Mermaid 附图',\r\n insertDrawioFigure: 'Draw.io 附图',\r\n switchFigureType: '切换附图类型',\r\n // Patent template (removed from toolbar)\r\n // Auto-save\r\n autoSaveSaving: '保存中...',\r\n autoSaveSaved: '已保存',\r\n autoSaveError: '保存失败',\r\n },\r\n en: {\r\n language: 'Language',\r\n bold: 'Bold',\r\n italic: 'Italic',\r\n underline: 'Underline',\r\n referenceTarget: 'Reference target',\r\n referenceTargetPlaceholder: 'Select claim',\r\n insertReference: 'Insert claim reference',\r\n figureReferenceTarget: 'Figure target',\r\n figureReferenceTargetPlaceholder: 'Select figure',\r\n insertFigureReference: 'Insert figure reference',\r\n validateClaimGraph: 'Validate claim graph',\r\n graphPassed: 'Claim graph validated',\r\n graphIssuesFound: (count: number) => `${count} dependency issue(s) found`,\r\n currentClaim: (number: number) => `Current Claim ${number}`,\r\n dependsOn: 'Depends on',\r\n noDependencyCandidates: 'No preceding claims available',\r\n placeCursorToEditDependencies: 'Place cursor inside a Claim to edit dependencies',\r\n deleteSelection: 'Delete selection',\r\n claimWorkspacePanel: 'Claim Industrial Panel',\r\n claimsSectionTitle: 'Claims',\r\n totalCount: (count: number) => `Total ${count}`,\r\n claimsSectionEnabled: 'Claims section enabled',\r\n claimsSectionDisabled: 'Claims section disabled',\r\n graphIssuesCount: (count: number) => (count === 0 ? 'Graph valid' : `Graph issues ${count}`),\r\n createClaimsSection: 'Create Claims Section',\r\n organizeClaimsSection: 'Organize to Claims Section',\r\n exportCnipaXml: 'Export CNIPA XML',\r\n exportWordMapping: 'Export Word Mapping',\r\n claimDependencyTree: 'Claim Dependency Tree',\r\n invalidClaimReference: 'Invalid claim reference',\r\n invalidFigureReference: 'Invalid figure reference',\r\n claimLabel: (number: number) => `Claim ${number}`,\r\n claimTypeLabel: (claimType: 'independent' | 'dependent' | string) =>\r\n claimType === 'dependent' ? 'Dependent' : 'Independent',\r\n claimInsertHintCreated: 'Claims section was created and a new Claim was inserted',\r\n claimInsertHintMoved: 'Cursor is outside claims section, inserted into Claims section',\r\n referenceNavigateTitle: 'Click to navigate to target claim',\r\n figureReferenceNavigateTitle: 'Click to navigate to target figure',\r\n referenceNavigateDisabledTitle: 'Invalid reference, navigation unavailable',\r\n currentFigure: 'Current Figure',\r\n figureId: 'Figure ID',\r\n figureCaption: 'Figure Caption',\r\n figureIdConflict: 'Figure ID already exists, please use a unique value',\r\n figureUploadHint: 'Click to upload or drop an image',\r\n figureReplaceImage: 'Replace image',\r\n figureDrawioPlaceholder: 'Draw.io editor coming soon',\r\n figureContentTypeImage: 'Image',\r\n figureContentTypeMermaid: 'Mermaid Diagram',\r\n figureContentTypeDrawio: 'Draw.io Diagram',\r\n mermaidDoubleClickToEdit: 'Double-click to edit',\r\n mermaidDoubleClickToCreate: 'Double-click to edit Mermaid diagram',\r\n mermaidSaveAndRender: 'Save & Render',\r\n mermaidCancel: 'Cancel',\r\n mermaidSyntaxError: 'Mermaid syntax error, please fix and retry',\r\n drawioDoubleClickToEdit: 'Double-click to edit Draw.io diagram (coming soon)',\r\n bookTitle_description: 'Description',\r\n patentTitlePlaceholder: 'Patent Title',\r\n sectionTitle_technical_field: 'Technical Field',\r\n sectionTitle_background_art: 'Background Art',\r\n sectionTitle_summary: 'Summary of Invention',\r\n sectionTitle_drawing_description: 'Brief Description of Drawings',\r\n sectionTitle_detailed_description: 'Detailed Description',\r\n sectionTitle_claims: 'Claims',\r\n sectionTitle_abstract: 'Abstract',\r\n sectionTitle_abstract_drawing: 'Abstract Drawing',\r\n sectionTitle_drawing_figures: 'Description Drawings',\r\n sectionTitle_design_product_name: 'Product Name',\r\n sectionTitle_design_usage: 'Usage Description',\r\n sectionTitle_design_description: 'Design Description',\r\n sectionTitle_design_views: 'Views (Photos/Images)',\r\n sectionTitle_design_brief: 'Brief Description',\r\n insertImageFigure: 'Image Figure',\r\n insertMermaidFigure: 'Mermaid Figure',\r\n insertDrawioFigure: 'Draw.io Figure',\r\n switchFigureType: 'Switch figure type',\r\n // Patent template keys removed from toolbar\r\n patentTemplateTooltip: 'Insert patent document template',\r\n autoSaveSaving: 'Saving...',\r\n autoSaveSaved: 'Saved',\r\n autoSaveError: 'Save failed',\r\n },\r\n} as const;\r\n\r\nexport const getEditorText = (language: EditorLanguage) => {\r\n return language === 'en' ? dict.en : dict.zh;\r\n};\r\n\r\nexport const formatClaimGraphIssueMessage = (\r\n language: EditorLanguage,\r\n code: ClaimGraphIssueCode,\r\n claimNumber: number,\r\n targetNumber?: number\r\n) => {\r\n if (language === 'en') {\r\n if (code === 'forward_reference') {\r\n return `Claim ${claimNumber} references later claim ${targetNumber}.`;\r\n }\r\n if (code === 'self_reference') {\r\n return `Claim ${claimNumber} references itself.`;\r\n }\r\n return `Claim ${claimNumber} has circular dependency.`;\r\n }\r\n if (code === 'forward_reference') {\r\n return `权利要求${claimNumber}引用了后置项权利要求${targetNumber}。`;\r\n }\r\n if (code === 'self_reference') {\r\n return `权利要求${claimNumber}引用了自身。`;\r\n }\r\n return `权利要求${claimNumber}存在循环依赖。`;\r\n};\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nlet mermaidIdCounter = 0;\r\n\r\nconst cleanupOrphans = () => {\r\n document.querySelectorAll('body > svg[id^=\"standalone-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > svg[id^=\"d\"]').forEach((el) => {\r\n if (el.id.startsWith('dmermaid') || el.id.startsWith('dstandalone')) el.remove();\r\n });\r\n document.querySelectorAll('body > div[id^=\"dstandalone-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > div[id^=\"dmermaid\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > div[id^=\"standalone-mermaid-\"]').forEach((el) => el.remove());\r\n};\r\n\r\nexport const MermaidNode = Node.create({\r\n name: 'mermaid',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n code: { default: 'graph TD; A-->B;' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"mermaid\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'mermaid' })];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let editMode = false;\r\n\r\n const dom = document.createElement('div');\r\n dom.classList.add('mermaid-node');\r\n\r\n // View mode: SVG preview + hint\r\n const viewContainer = document.createElement('div');\r\n viewContainer.className = 'mermaid-view';\r\n viewContainer.contentEditable = 'false';\r\n\r\n const preview = document.createElement('div');\r\n preview.className = 'mermaid-preview';\r\n preview.contentEditable = 'false';\r\n\r\n const viewHint = document.createElement('div');\r\n viewHint.className = 'mermaid-view-hint';\r\n\r\n viewContainer.append(preview, viewHint);\r\n\r\n // Edit mode: textarea + toolbar\r\n const editContainer = document.createElement('div');\r\n editContainer.className = 'mermaid-edit';\r\n\r\n const textarea = document.createElement('textarea');\r\n textarea.className = 'mermaid-editor-textarea';\r\n textarea.spellcheck = false;\r\n\r\n const toolbar = document.createElement('div');\r\n toolbar.className = 'mermaid-edit-toolbar';\r\n\r\n const errorMsg = document.createElement('span');\r\n errorMsg.className = 'mermaid-error-msg';\r\n\r\n const cancelBtn = document.createElement('button');\r\n cancelBtn.className = 'mermaid-cancel-btn';\r\n cancelBtn.type = 'button';\r\n\r\n const saveBtn = document.createElement('button');\r\n saveBtn.className = 'mermaid-save-btn';\r\n saveBtn.type = 'button';\r\n\r\n toolbar.append(errorMsg, cancelBtn, saveBtn);\r\n editContainer.append(textarea, toolbar);\r\n\r\n dom.append(viewContainer, editContainer);\r\n\r\n // Helpers\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n let lastRenderedCode = '';\r\n\r\n const doRender = async (code: string) => {\r\n const trimmed = code.trim();\r\n if (trimmed === lastRenderedCode) return;\r\n if (!trimmed) {\r\n preview.innerHTML = '';\r\n lastRenderedCode = '';\r\n return;\r\n }\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `standalone-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n preview.innerHTML = svg;\r\n lastRenderedCode = trimmed;\r\n } catch {\r\n preview.innerHTML = '';\r\n lastRenderedCode = '';\r\n } finally {\r\n cleanupOrphans();\r\n }\r\n };\r\n\r\n const enterEditMode = () => {\r\n if (editMode) return;\r\n editMode = true;\r\n textarea.value = typeof currentNode.attrs.code === 'string' ? currentNode.attrs.code : '';\r\n errorMsg.textContent = '';\r\n errorMsg.style.display = 'none';\r\n renderUI();\r\n requestAnimationFrame(() => textarea.focus());\r\n };\r\n\r\n const exitEditMode = () => {\r\n editMode = false;\r\n renderUI();\r\n };\r\n\r\n const saveAndRender = async () => {\r\n const code = textarea.value;\r\n errorMsg.textContent = '';\r\n errorMsg.style.display = 'none';\r\n\r\n const trimmed = code.trim();\r\n if (trimmed) {\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `standalone-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n preview.innerHTML = svg;\r\n lastRenderedCode = trimmed;\r\n cleanupOrphans();\r\n } catch {\r\n cleanupOrphans();\r\n const language = useEditorStore.getState().editorLanguage;\r\n errorMsg.textContent = language === 'en'\r\n ? 'Mermaid syntax error, please fix and retry'\r\n : 'Mermaid 语法错误,请修正后重试';\r\n errorMsg.style.display = 'inline';\r\n return;\r\n }\r\n }\r\n\r\n setNodeAttrs({ code });\r\n editMode = false;\r\n renderUI();\r\n };\r\n\r\n viewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterEditMode();\r\n });\r\n\r\n saveBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n void saveAndRender();\r\n });\r\n\r\n cancelBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n exitEditMode();\r\n });\r\n\r\n textarea.addEventListener('mousedown', (e) => e.stopPropagation());\r\n textarea.addEventListener('keydown', (e) => e.stopPropagation());\r\n textarea.addEventListener('keypress', (e) => e.stopPropagation());\r\n\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const code = typeof currentNode.attrs.code === 'string' ? currentNode.attrs.code : '';\r\n\r\n viewContainer.style.display = !editMode ? 'block' : 'none';\r\n editContainer.style.display = editMode ? 'block' : 'none';\r\n\r\n saveBtn.textContent = (i18n.mermaidSaveAndRender as string) || '保存并渲染';\r\n cancelBtn.textContent = (i18n.mermaidCancel as string) || '取消';\r\n\r\n const hasCode = code.trim().length > 0;\r\n const hasSvg = preview.querySelector('svg') !== null;\r\n if (!editMode) {\r\n if (hasCode && hasSvg) {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n viewHint.className = 'mermaid-view-hint mermaid-view-hint--subtle';\r\n } else {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToCreate as string) || '双击编辑 Mermaid 图表';\r\n viewHint.className = 'mermaid-view-hint mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n if (!editMode && code.trim() !== lastRenderedCode) {\r\n void doRender(code);\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n stopEvent: (event: Event) => {\r\n const target = event.target;\r\n if (target === textarea) return true;\r\n if (editContainer.contains(target as globalThis.Node)) return true;\r\n return false;\r\n },\r\n ignoreMutation: () => true,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'mermaid') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n cleanupOrphans();\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { MermaidNode } from './mermaidNode';\r\n\r\nexport const MermaidPlugin: EditorPlugin = {\r\n name: 'mermaid',\r\n version: '1.0.0',\r\n extensions: [MermaidNode],\r\n toolbarItems: [\r\n {\r\n id: 'mermaid-insert',\r\n label: 'Mermaid',\r\n command: 'insert',\r\n group: 'technical',\r\n tooltip: 'Insert Mermaid diagram',\r\n icon: 'GitGraph',\r\n shortcut: 'Ctrl+Shift+M',\r\n },\r\n ],\r\n commands: {\r\n insert: {\r\n description: 'Insert Mermaid diagram block',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+M',\r\n isActive: ({ editor }) => editor.isActive('mermaid'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { code?: string }) : {};\r\n const code = data.code || 'graph TD; A-->B;';\r\n return editor.chain().focus().insertContent({ type: 'mermaid', attrs: { code } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport const DrawioNode = Node.create({\r\n name: 'drawio',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n xml: { default: '' },\r\n svg: { default: '' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"drawio\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'drawio' })];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let editMode = false;\r\n\r\n const dom = document.createElement('div');\r\n dom.classList.add('drawio-node');\r\n\r\n // View mode: image preview + hint\r\n const viewContainer = document.createElement('div');\r\n viewContainer.className = 'drawio-view';\r\n viewContainer.contentEditable = 'false';\r\n\r\n const previewImg = document.createElement('img');\r\n previewImg.className = 'drawio-preview-img';\r\n previewImg.style.display = 'none';\r\n\r\n const viewHint = document.createElement('div');\r\n viewHint.className = 'drawio-view-hint';\r\n\r\n viewContainer.append(previewImg, viewHint);\r\n dom.append(viewContainer);\r\n\r\n // Helpers\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n // Modal editing\r\n let drawioMessageHandler: ((ev: MessageEvent) => void) | null = null;\r\n let drawioModal: HTMLDivElement | null = null;\r\n let drawioIframe: HTMLIFrameElement | null = null;\r\n\r\n const enterEditMode = () => {\r\n if (editMode) return;\r\n editMode = true;\r\n\r\n drawioModal = document.createElement('div');\r\n drawioModal.className = 'drawio-modal-overlay';\r\n\r\n const modalContent = document.createElement('div');\r\n modalContent.className = 'drawio-modal-content';\r\n\r\n const modalHeader = document.createElement('div');\r\n modalHeader.className = 'drawio-modal-header';\r\n\r\n const language = useEditorStore.getState().editorLanguage;\r\n const modalTitle = document.createElement('span');\r\n modalTitle.textContent = language === 'en' ? 'Edit Draw.io Diagram' : '编辑 Draw.io 图表';\r\n modalTitle.className = 'drawio-modal-title';\r\n\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'drawio-modal-close-btn';\r\n closeBtn.textContent = '✕';\r\n closeBtn.type = 'button';\r\n closeBtn.addEventListener('click', () => exitEditMode());\r\n\r\n modalHeader.append(modalTitle, closeBtn);\r\n\r\n drawioIframe = document.createElement('iframe');\r\n drawioIframe.className = 'drawio-modal-iframe';\r\n drawioIframe.setAttribute('frameborder', '0');\r\n\r\n modalContent.append(modalHeader, drawioIframe);\r\n drawioModal.appendChild(modalContent);\r\n document.body.appendChild(drawioModal);\r\n\r\n const lang = language === 'en' ? 'en' : 'zh';\r\n drawioIframe.src = `https://embed.diagrams.net/?embed=1&proto=json&spin=1&lang=${lang}`;\r\n\r\n const iframeRef = drawioIframe;\r\n drawioMessageHandler = (ev: MessageEvent) => {\r\n if (!iframeRef || ev.source !== iframeRef.contentWindow) return;\r\n let msg: { event?: string; xml?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n const existingXml = typeof currentNode.attrs.xml === 'string' ? currentNode.attrs.xml : '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: existingXml || '' }), '*'\r\n );\r\n } else if (msg.event === 'save') {\r\n const xml = msg.xml || '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n setNodeAttrs({ xml });\r\n } else if (msg.event === 'export') {\r\n const svgData = msg.data || '';\r\n setNodeAttrs({ svg: svgData });\r\n exitEditMode();\r\n } else if (msg.event === 'exit') {\r\n exitEditMode();\r\n }\r\n };\r\n window.addEventListener('message', drawioMessageHandler);\r\n };\r\n\r\n const exitEditMode = () => {\r\n editMode = false;\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n renderUI();\r\n };\r\n\r\n viewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterEditMode();\r\n });\r\n\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const svgData = typeof currentNode.attrs.svg === 'string' ? currentNode.attrs.svg : '';\r\n\r\n if (svgData) {\r\n previewImg.src = svgData;\r\n previewImg.style.display = 'block';\r\n } else {\r\n previewImg.src = '';\r\n previewImg.style.display = 'none';\r\n }\r\n\r\n if (svgData) {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n viewHint.className = 'drawio-view-hint drawio-view-hint--subtle';\r\n } else {\r\n viewHint.textContent = (i18n.drawioDoubleClickToEdit as string) || '双击编辑 Draw.io 图表';\r\n viewHint.className = 'drawio-view-hint drawio-view-hint--empty';\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n ignoreMutation: () => true,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'drawio') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { DrawioNode } from './drawioNode';\r\n\r\nexport const DrawioPlugin: EditorPlugin = {\r\n name: 'drawio',\r\n version: '1.0.0',\r\n extensions: [DrawioNode],\r\n toolbarItems: [\r\n {\r\n id: 'drawio-insert',\r\n label: 'Draw.io',\r\n command: 'insert',\r\n group: 'technical',\r\n tooltip: 'Insert Draw.io diagram',\r\n icon: 'Workflow',\r\n shortcut: 'Ctrl+Shift+D',\r\n },\r\n ],\r\n commands: {\r\n insert: {\r\n description: 'Insert Draw.io diagram block',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+D',\r\n isActive: ({ editor }) => editor.isActive('drawio'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { xml?: string }) : {};\r\n const xml = data.xml || '';\r\n return editor.chain().focus().insertContent({ type: 'drawio', attrs: { xml } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { NodeViewProps, NodeViewWrapper } from '@tiptap/react';\r\nimport katex from 'katex';\r\nimport 'katex/dist/katex.min.css';\r\nimport 'mathlive';\r\nimport { MathfieldElement } from 'mathlive';\r\nimport { useCallback, useEffect, useRef, useState } from 'react';\r\n\r\ndeclare global {\r\n namespace JSX {\r\n interface IntrinsicElements {\r\n 'math-field': React.DetailedHTMLProps<\r\n React.HTMLAttributes<HTMLElement>,\r\n HTMLElement\r\n > & {\r\n ref?: React.Ref<MathfieldElement>;\r\n value?: string;\r\n };\r\n }\r\n }\r\n}\r\n\r\nexport const MathComponent = ({\r\n node,\r\n updateAttributes,\r\n selected,\r\n editor,\r\n}: NodeViewProps) => {\r\n const mfRef = useRef<MathfieldElement | null>(null);\r\n const [isEditing, setIsEditing] = useState(false);\r\n const isBlock = node.type.name === 'math_block';\r\n\r\n // Refs to latest values — prevent stale closures in callbacks\r\n const isEditingRef = useRef(false);\r\n const latestUpdateAttrs = useRef(updateAttributes);\r\n const latestLatex = useRef<string>(node.attrs.latex ?? '');\r\n useEffect(() => { latestUpdateAttrs.current = updateAttributes; }, [updateAttributes]);\r\n useEffect(() => { latestLatex.current = node.attrs.latex ?? ''; }, [node.attrs.latex]);\r\n\r\n // ── Enter edit mode ────────────────────────────────────────────\r\n const enterEdit = useCallback(() => {\r\n if (isEditingRef.current) return;\r\n isEditingRef.current = true;\r\n setIsEditing(true);\r\n }, []);\r\n\r\n // ── Exit edit mode: save current math-field value ──────────────\r\n const exitEdit = useCallback(() => {\r\n if (!isEditingRef.current) return;\r\n isEditingRef.current = false;\r\n const latex = mfRef.current?.value ?? latestLatex.current;\r\n latestUpdateAttrs.current({ latex });\r\n setIsEditing(false);\r\n (globalThis as unknown as {\r\n mathVirtualKeyboard?: { hide: (opts?: { animate?: boolean }) => void };\r\n }).mathVirtualKeyboard?.hide({ animate: true });\r\n }, []);\r\n\r\n // ── Use ProseMirror `selected` only to ENTER edit mode ─────────\r\n // Never use it to exit — that caused inline math to close after one keystroke\r\n // (updateAttributes dispatches a transaction that resets inline NodeSelection)\r\n useEffect(() => {\r\n const isCollapsed = Boolean(editor?.view?.state?.selection?.empty);\r\n if (selected && isCollapsed) {\r\n enterEdit();\r\n }\r\n }, [selected, enterEdit]);\r\n\r\n // ── Auto-focus + keyboard policy when edit starts ──────────────\r\n // Bug fix: requestAnimationFrame lets the math-field web component\r\n // finish its internal initialization before we call focus()\r\n useEffect(() => {\r\n if (!isEditing) return;\r\n requestAnimationFrame(() => {\r\n const mf = mfRef.current as unknown as {\r\n virtualKeyboardMode?: string;\r\n focus?: () => void;\r\n } | null;\r\n if (!mf) return;\r\n mf.virtualKeyboardMode = 'onfocus';\r\n mf.focus?.();\r\n });\r\n }, [isEditing]);\r\n\r\n // ── Exit via focusout (blur away from math-field AND keyboard) ──\r\n useEffect(() => {\r\n if (!isEditing) return;\r\n const mf = mfRef.current;\r\n if (!mf) return;\r\n\r\n const onFocusOut = () => {\r\n setTimeout(() => {\r\n if (!isEditingRef.current) return;\r\n const active = document.activeElement;\r\n // Stay in edit mode if focus moved to math-field or MathLive keyboard\r\n if (\r\n active?.tagName === 'MATH-FIELD' ||\r\n active?.closest?.('math-field') ||\r\n active?.closest?.('.ML__keyboard') ||\r\n document.querySelector('.ML__keyboard')?.contains(active as globalThis.Node)\r\n ) return;\r\n exitEdit();\r\n }, 300);\r\n };\r\n\r\n const onKeyDown = (e: Event) => {\r\n if ((e as KeyboardEvent).key === 'Escape') exitEdit();\r\n };\r\n\r\n mf.addEventListener('focusout', onFocusOut);\r\n mf.addEventListener('keydown', onKeyDown);\r\n return () => {\r\n mf.removeEventListener('focusout', onFocusOut);\r\n mf.removeEventListener('keydown', onKeyDown);\r\n };\r\n }, [isEditing, exitEdit]);\r\n\r\n // ── Sync external latex changes into math-field (when not editing) ──\r\n useEffect(() => {\r\n if (!isEditing && mfRef.current && mfRef.current.value !== node.attrs.latex) {\r\n mfRef.current.value = node.attrs.latex ?? '';\r\n }\r\n }, [node.attrs.latex, isEditing]);\r\n\r\n // ── KaTeX preview ───────────────────────────────────────────────\r\n let markup = '';\r\n try {\r\n markup = katex.renderToString(node.attrs.latex || '', {\r\n throwOnError: false,\r\n displayMode: isBlock,\r\n });\r\n } catch {\r\n markup = node.attrs.latex || '';\r\n }\r\n\r\n return (\r\n <NodeViewWrapper\r\n as={isBlock ? 'div' : 'span'}\r\n className={isBlock ? 'math-block' : 'math-inline'}\r\n >\r\n {isEditing ? (\r\n <math-field\r\n ref={mfRef as React.Ref<MathfieldElement>}\r\n className={isBlock ? 'math-live-field math-live-field--block' : 'math-live-field'}\r\n >\r\n {node.attrs.latex}\r\n </math-field>\r\n ) : (\r\n <span className=\"math-preview\" onClick={enterEdit}>\r\n <span dangerouslySetInnerHTML={{ __html: markup }} />\r\n <span className=\"math-tooltip\">点击编辑</span>\r\n </span>\r\n )}\r\n </NodeViewWrapper>\r\n );\r\n};\r\n","import { Node, mergeAttributes, ReactNodeViewRenderer } from '@tiptap/react';\r\nimport { MathComponent } from './MathComponent';\r\n\r\nexport const MathInline = Node.create({\r\n name: 'math_inline',\r\n group: 'inline',\r\n inline: true,\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n latex: { default: 'E = mc^2' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [\r\n { tag: 'span[data-type=\"math_inline\"]' },\r\n {\r\n tag: 'span',\r\n getAttrs: (node) => {\r\n const el = node as HTMLElement;\r\n if (!el.hasAttribute('data-math')) return false;\r\n return { latex: (el.getAttribute('latex') || '').trim() };\r\n },\r\n },\r\n ];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'math_inline' })];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(MathComponent, {\r\n stopEvent: ({ event }) => {\r\n const target = event.target as HTMLElement;\r\n return (\r\n target.tagName.toLowerCase() === 'math-field' ||\r\n target.closest('math-field') !== null\r\n );\r\n },\r\n });\r\n },\r\n});\r\n\r\nexport const MathBlock = Node.create({\r\n name: 'math_block',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n latex: { default: '\\\\sum_{i=1}^n i = \\\\frac{n(n+1)}{2}' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"math_block\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'math_block' })];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(MathComponent, {\r\n stopEvent: ({ event }) => {\r\n const target = event.target as HTMLElement;\r\n return (\r\n target.tagName.toLowerCase() === 'math-field' ||\r\n target.closest('math-field') !== null\r\n );\r\n },\r\n });\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { MathInline, MathBlock } from './mathNode';\r\nimport 'katex/dist/katex.min.css';\r\nexport const MathPlugin: EditorPlugin = {\r\n name: 'math',\r\n version: '1.0.0',\r\n extensions: [MathInline, MathBlock],\r\n toolbarItems: [\r\n {\r\n id: 'math-inline-insert',\r\n label: 'Math Inline',\r\n command: 'insertInline',\r\n group: 'technical',\r\n tooltip: 'Insert inline math',\r\n icon: 'Sigma',\r\n shortcut: 'Ctrl+M',\r\n },\r\n {\r\n id: 'math-block-insert',\r\n label: 'Math Block',\r\n command: 'insertBlock',\r\n group: 'technical',\r\n tooltip: 'Insert math block',\r\n icon: 'FunctionSquare',\r\n shortcut: 'Ctrl+Shift+M',\r\n },\r\n ],\r\n commands: {\r\n insertInline: {\r\n description: 'Insert inline math formula',\r\n category: 'technical',\r\n shortcut: 'Ctrl+M',\r\n isActive: ({ editor }) => editor.isActive('math_inline'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { latex?: string }) : {};\r\n const latex = data.latex || 'E = mc^2';\r\n return editor.chain().focus().insertContent({ type: 'math_inline', attrs: { latex } }).run();\r\n },\r\n },\r\n insertBlock: {\r\n description: 'Insert block math formula',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+M',\r\n isActive: ({ editor }) => editor.isActive('math_block'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { latex?: string }) : {};\r\n const latex = data.latex || '\\\\sum_{i=1}^n i = \\\\frac{n(n+1)}{2}';\r\n return editor.chain().focus().insertContent({ type: 'math_block', attrs: { latex } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\r\n\r\nexport interface NodeMatch {\r\n node: ProseMirrorNode;\r\n pos: number;\r\n}\r\n\r\nexport interface NodeQueryScope {\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport const findNodeByType = (editor: Editor, typeName: string, scope: NodeQueryScope = {}): NodeMatch | null => {\r\n const from = scope.from ?? 0;\r\n const to = scope.to ?? editor.state.doc.content.size;\r\n let matched: NodeMatch | null = null;\r\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\r\n if (matched) {\r\n return false;\r\n }\r\n if (node.type.name === typeName) {\r\n matched = { node, pos };\r\n return false;\r\n }\r\n return true;\r\n });\r\n return matched;\r\n};\r\n\r\nexport const findNodesByPredicate = (\r\n editor: Editor,\r\n predicate: (node: ProseMirrorNode, pos: number) => boolean,\r\n scope: NodeQueryScope = {}\r\n): NodeMatch[] => {\r\n const from = scope.from ?? 0;\r\n const to = scope.to ?? editor.state.doc.content.size;\r\n const matches: NodeMatch[] = [];\r\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\r\n if (predicate(node, pos)) {\r\n matches.push({ node, pos });\r\n }\r\n return true;\r\n });\r\n return matches;\r\n};\r\n\r\nexport const findAncestorNode = (\r\n editor: Editor,\r\n predicate: string | ((node: ProseMirrorNode) => boolean)\r\n): NodeMatch | null => {\r\n const { $from } = editor.state.selection;\r\n for (let depth = $from.depth; depth >= 0; depth -= 1) {\r\n const node = $from.node(depth);\r\n const matched = typeof predicate === 'string' ? node.type.name === predicate : predicate(node);\r\n if (matched) {\r\n return {\r\n node,\r\n pos: depth === 0 ? 0 : $from.before(depth),\r\n };\r\n }\r\n }\r\n return null;\r\n};\r\n\r\nexport const findCurrentBlock = (editor: Editor): NodeMatch | null => {\r\n const { $from } = editor.state.selection;\r\n for (let depth = $from.depth; depth >= 0; depth -= 1) {\r\n const node = $from.node(depth);\r\n if (node.isBlock) {\r\n return {\r\n node,\r\n pos: depth === 0 ? 0 : $from.before(depth),\r\n };\r\n }\r\n }\r\n return null;\r\n};\r\n","import { Editor, JSONContent } from '@tiptap/react';\r\nimport { NodeType } from '@tiptap/pm/model';\r\nimport { findWrapping } from '@tiptap/pm/transform';\r\nimport { findNodeByType } from './nodeQueries';\r\n\r\ntype JSONBlockContent = JSONContent | JSONContent[];\r\n\r\ninterface InsertNodeInput {\r\n type: string;\r\n attrs?: Record<string, unknown>;\r\n content?: JSONBlockContent;\r\n position?: number;\r\n}\r\n\r\ninterface UpdateNodeAttrsInput {\r\n type?: string;\r\n position?: number;\r\n attrs: Record<string, unknown>;\r\n}\r\n\r\ninterface RemoveNodeInput {\r\n type?: string;\r\n position?: number;\r\n}\r\n\r\ninterface WrapSelectionInput {\r\n type: string;\r\n attrs?: Record<string, unknown>;\r\n}\r\n\r\ntype BatchOperation =\r\n | { type: 'insertNode'; payload: InsertNodeInput }\r\n | { type: 'updateNodeAttrs'; payload: UpdateNodeAttrsInput }\r\n | { type: 'removeNode'; payload: RemoveNodeInput }\r\n | { type: 'wrapSelection'; payload: WrapSelectionInput };\r\n\r\nconst getNodeType = (editor: Editor, name: string): NodeType | null => {\r\n return editor.state.schema.nodes[name] || null;\r\n};\r\n\r\nconst buildNodeContent = (input: InsertNodeInput): JSONContent => {\r\n const normalizedContent = Array.isArray(input.content)\r\n ? input.content\r\n : input.content\r\n ? [input.content]\r\n : undefined;\r\n return {\r\n type: input.type,\r\n attrs: input.attrs,\r\n content: normalizedContent,\r\n };\r\n};\r\n\r\nexport const insertNode = (editor: Editor, input: InsertNodeInput): boolean => {\r\n const content = buildNodeContent(input);\r\n if (typeof input.position === 'number') {\r\n return editor.chain().focus().insertContentAt(input.position, content).run();\r\n }\r\n return editor.chain().focus().insertContent(content).run();\r\n};\r\n\r\nexport const updateNodeAttrs = (editor: Editor, input: UpdateNodeAttrsInput): boolean => {\r\n if (typeof input.position !== 'number' && !input.type) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const targetPos =\r\n typeof input.position === 'number' ? input.position : findNodeByType(editor, input.type || '')?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const node = state.doc.nodeAt(targetPos);\r\n if (!node) {\r\n return false;\r\n }\r\n if (input.type && node.type.name !== input.type) {\r\n return false;\r\n }\r\n const attrs = { ...node.attrs, ...input.attrs };\r\n tr.setNodeMarkup(targetPos, undefined, attrs);\r\n if (dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport const removeNode = (editor: Editor, input: RemoveNodeInput): boolean => {\r\n if (typeof input.position !== 'number' && !input.type) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const targetPos =\r\n typeof input.position === 'number' ? input.position : findNodeByType(editor, input.type || '')?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const node = state.doc.nodeAt(targetPos);\r\n if (!node) {\r\n return false;\r\n }\r\n if (input.type && node.type.name !== input.type) {\r\n return false;\r\n }\r\n tr.delete(targetPos, targetPos + node.nodeSize);\r\n if (dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport const wrapSelection = (editor: Editor, input: WrapSelectionInput): boolean => {\r\n const nodeType = getNodeType(editor, input.type);\r\n if (!nodeType) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const { from, to } = state.selection;\r\n const range = state.selection.$from.blockRange(state.selection.$to);\r\n if (!range) {\r\n return false;\r\n }\r\n const wrapping = findWrapping(range, nodeType, input.attrs);\r\n if (!wrapping) {\r\n return false;\r\n }\r\n tr.wrap(range, wrapping);\r\n if (dispatch) {\r\n dispatch(tr.scrollIntoView());\r\n }\r\n return from <= to;\r\n });\r\n};\r\n\r\nexport const applyTransactionBatch = (editor: Editor, operations: BatchOperation[]): boolean => {\r\n if (operations.length === 0) {\r\n return false;\r\n }\r\n const snapshot = editor.getJSON();\r\n for (const operation of operations) {\r\n const success =\r\n operation.type === 'insertNode'\r\n ? insertNode(editor, operation.payload)\r\n : operation.type === 'updateNodeAttrs'\r\n ? updateNodeAttrs(editor, operation.payload)\r\n : operation.type === 'removeNode'\r\n ? removeNode(editor, operation.payload)\r\n : wrapSelection(editor, operation.payload);\r\n if (!success) {\r\n editor.commands.setContent(snapshot);\r\n return false;\r\n }\r\n }\r\n return true;\r\n};\r\n\r\nexport type { BatchOperation, InsertNodeInput, RemoveNodeInput, UpdateNodeAttrsInput, WrapSelectionInput };\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { TextSelection } from '@tiptap/pm/state';\r\nimport type { ResolvedPos } from '@tiptap/pm/model';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nconst createClaimId = () =>\r\n `claim_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\r\n\r\nexport const ClaimNode = Node.create({\r\n name: 'claim',\r\n group: 'block',\r\n content: 'inline*',\r\n draggable: false,\r\n\r\n addAttributes() {\r\n return {\r\n number: { default: 1 },\r\n claimId: { default: null },\r\n dependsOn: { default: [] },\r\n dependsOnClaimIds: { default: [] },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'p[data-type=\"claim\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'p',\r\n mergeAttributes(HTMLAttributes, { 'data-type': 'claim', class: 'claim-line' }),\r\n 0,\r\n ];\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n Enter: () => {\r\n const { state, dispatch } = this.editor.view;\r\n const { $from, empty } = state.selection;\r\n\r\n const claimDepth = findClaimDepth($from);\r\n if (claimDepth === null) return false;\r\n\r\n const claimNode = $from.node(claimDepth);\r\n const claimStart = $from.before(claimDepth);\r\n const claimEnd = claimStart + claimNode.nodeSize;\r\n\r\n // Only create a new claim when cursor is at the very end of the claim content\r\n if (!empty || $from.pos !== claimEnd - 1) return false;\r\n\r\n const afterClaim = claimEnd;\r\n\r\n let claimCount = 0;\r\n state.doc.descendants((n) => {\r\n if (n.type.name === 'claim') claimCount++;\r\n return true;\r\n });\r\n\r\n const newClaim = state.schema.nodes.claim.create(\r\n {\r\n number: claimCount + 1,\r\n claimId: createClaimId(),\r\n dependsOn: [],\r\n dependsOnClaimIds: [],\r\n },\r\n );\r\n\r\n const tr = state.tr.insert(afterClaim, newClaim);\r\n const cursorPos = afterClaim + 1;\r\n tr.setSelection(TextSelection.create(tr.doc, cursorPos));\r\n dispatch(tr);\r\n return true;\r\n },\r\n\r\n Backspace: () => {\r\n const { state, dispatch } = this.editor.view;\r\n const { $from, empty } = state.selection;\r\n if (!empty) return false;\r\n\r\n const claimDepth = findClaimDepth($from);\r\n if (claimDepth === null) return false;\r\n\r\n const claimNode = $from.node(claimDepth);\r\n if (claimNode.content.size > 0) return false;\r\n\r\n let claimCount = 0;\r\n state.doc.descendants((n) => {\r\n if (n.type.name === 'claim') claimCount++;\r\n return true;\r\n });\r\n if (claimCount <= 1) return false;\r\n\r\n const claimStart = $from.before(claimDepth);\r\n const claimEnd = claimStart + claimNode.nodeSize;\r\n const tr = state.tr.delete(claimStart, claimEnd);\r\n\r\n const newPos = Math.min(claimStart, tr.doc.content.size);\r\n const $newPos = tr.doc.resolve(newPos);\r\n tr.setSelection(TextSelection.near($newPos));\r\n dispatch(tr);\r\n return true;\r\n },\r\n };\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n\r\n const dom = document.createElement('p');\r\n dom.setAttribute('data-type', 'claim');\r\n dom.className = 'claim-line';\r\n\r\n const label = document.createElement('span');\r\n label.className = 'claim-label';\r\n label.contentEditable = 'false';\r\n\r\n const contentDOM = document.createElement('span');\r\n contentDOM.className = 'claim-body';\r\n\r\n const render = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language);\r\n const number = Number(currentNode.attrs.number || 1);\r\n label.textContent = `${i18n.claimLabel(number)}. `;\r\n\r\n const hasContent = currentNode.content.size > 0;\r\n if (!hasContent) {\r\n contentDOM.setAttribute('data-placeholder', language === 'en'\r\n ? 'Type claim content... (Enter to add next)'\r\n : '输入权利要求内容… (Enter 添加下一条)');\r\n dom.classList.add('claim-line--empty');\r\n } else {\r\n contentDOM.removeAttribute('data-placeholder');\r\n dom.classList.remove('claim-line--empty');\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n render();\r\n }\r\n });\r\n\r\n dom.addEventListener('mousedown', (event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) return;\r\n if (target === contentDOM || contentDOM.contains(target)) return;\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n const end = pos + currentNode.nodeSize - 1;\r\n const selection = TextSelection.create(editor.state.doc, end);\r\n editor.view.dispatch(editor.state.tr.setSelection(selection));\r\n });\r\n\r\n dom.append(label, contentDOM);\r\n render();\r\n\r\n return {\r\n dom,\r\n contentDOM,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'claim') return false;\r\n currentNode = updatedNode;\r\n render();\r\n return true;\r\n },\r\n destroy: () => unsub(),\r\n };\r\n };\r\n },\r\n});\r\n\r\nfunction findClaimDepth($pos: ResolvedPos): number | null {\r\n for (let d = $pos.depth; d >= 0; d--) {\r\n if ($pos.node(d).type.name === 'claim') return d;\r\n }\r\n return null;\r\n}\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { TextSelection } from '@tiptap/pm/state';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport type FigureContentType = 'image' | 'mermaid' | 'drawio';\r\n\r\nlet mermaidIdCounter = 0;\r\n\r\n// ====== Drawio auto-SVG generation queue ======\r\n// Reuses a single hidden diagrams.net iframe to avoid repeated resource loads\r\n// (e.g. dia_zh.txt). Also caches XML→SVG results to skip duplicate exports.\r\ntype SvgGenTask = { xml: string; callback: (svg: string) => void };\r\nconst _svgGenQueue: SvgGenTask[] = [];\r\nlet _svgGenBusy = false;\r\nconst _SVG_GEN_TIMEOUT_MS = 20000;\r\nconst _IDLE_DESTROY_MS = 60000;\r\n\r\nlet _sharedIframe: HTMLIFrameElement | null = null;\r\nlet _sharedIframeReady = false;\r\nlet _currentMsgHandler: ((ev: MessageEvent) => void) | null = null;\r\nlet _idleTimer: ReturnType<typeof setTimeout> | null = null;\r\nconst _svgCache = new Map<string, string>();\r\n\r\nfunction _destroySharedIframe() {\r\n if (_currentMsgHandler) {\r\n window.removeEventListener('message', _currentMsgHandler);\r\n _currentMsgHandler = null;\r\n }\r\n if (_sharedIframe) {\r\n _sharedIframe.src = 'about:blank';\r\n _sharedIframe.remove();\r\n _sharedIframe = null;\r\n }\r\n _sharedIframeReady = false;\r\n}\r\n\r\nfunction queueDrawioSvgGen(xml: string, callback: (svg: string) => void) {\r\n const cached = _svgCache.get(xml);\r\n if (cached) { callback(cached); return; }\r\n _svgGenQueue.push({ xml, callback });\r\n _processNextSvgGen();\r\n}\r\n\r\nfunction _processNextSvgGen() {\r\n if (_svgGenBusy || _svgGenQueue.length === 0) return;\r\n _svgGenBusy = true;\r\n if (_idleTimer) { clearTimeout(_idleTimer); _idleTimer = null; }\r\n\r\n const { xml, callback } = _svgGenQueue.shift()!;\r\n const cached = _svgCache.get(xml);\r\n if (cached) {\r\n callback(cached);\r\n _svgGenBusy = false;\r\n _idleTimer = setTimeout(_destroySharedIframe, _IDLE_DESTROY_MS);\r\n _processNextSvgGen();\r\n return;\r\n }\r\n\r\n if (_currentMsgHandler) {\r\n window.removeEventListener('message', _currentMsgHandler);\r\n _currentMsgHandler = null;\r\n }\r\n\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n\r\n const done = (svg: string) => {\r\n if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; }\r\n if (svg) _svgCache.set(xml, svg);\r\n callback(svg);\r\n _svgGenBusy = false;\r\n _idleTimer = setTimeout(_destroySharedIframe, _IDLE_DESTROY_MS);\r\n _processNextSvgGen();\r\n };\r\n\r\n const sendLoad = () => {\r\n _sharedIframe!.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: xml || '' }), '*'\r\n );\r\n };\r\n\r\n _currentMsgHandler = (ev: MessageEvent) => {\r\n if (!_sharedIframe || ev.source !== _sharedIframe.contentWindow) return;\r\n let msg: { event?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n _sharedIframeReady = true;\r\n sendLoad();\r\n } else if (msg.event === 'load') {\r\n setTimeout(() => {\r\n _sharedIframe?.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n }, 1500);\r\n } else if (msg.event === 'export') {\r\n done(msg.data || '');\r\n }\r\n };\r\n\r\n window.addEventListener('message', _currentMsgHandler);\r\n timeoutId = setTimeout(() => done(''), _SVG_GEN_TIMEOUT_MS);\r\n\r\n if (!_sharedIframe) {\r\n _sharedIframe = document.createElement('iframe');\r\n _sharedIframe.style.cssText = 'position:fixed;left:-9999px;top:-9999px;width:1920px;height:1080px;opacity:0;pointer-events:none;';\r\n document.body.appendChild(_sharedIframe);\r\n _sharedIframeReady = false;\r\n _sharedIframe.src = 'https://embed.diagrams.net/?embed=1&proto=json&spin=0&chrome=0';\r\n } else if (_sharedIframeReady) {\r\n sendLoad();\r\n }\r\n}\r\n\r\nconst cleanupMermaidOrphans = () => {\r\n document.querySelectorAll('body > svg[id^=\"fig-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > svg[id^=\"d\"]').forEach((el) => {\r\n if (el.id.startsWith('dmermaid') || el.id.startsWith('dfi')) el.remove();\r\n });\r\n document.querySelectorAll('body > #dmermaid-svg').forEach((el) => el.remove());\r\n document.querySelectorAll('body > style[data-mermaid-style]').forEach((el) => el.remove());\r\n};\r\n\r\nexport const FigureNode = Node.create({\r\n name: 'figure',\r\n group: 'block',\r\n content: 'inline*',\r\n draggable: true,\r\n isolating: true,\r\n\r\n addAttributes() {\r\n return {\r\n id: { default: null },\r\n contentType: { default: 'image' as FigureContentType },\r\n imageSrc: { default: '' },\r\n mermaidCode: { default: '' },\r\n drawioXml: { default: '' },\r\n drawioSvg: { default: '' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'figure[data-type=\"figure\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'figure',\r\n mergeAttributes(HTMLAttributes, { 'data-type': 'figure', class: 'figure-block' }),\r\n ['figcaption', { class: 'figure-caption' }, 0],\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let mermaidEditMode = false;\r\n let drawioEditMode = false;\r\n\r\n const dom = document.createElement('figure');\r\n dom.setAttribute('data-type', 'figure');\r\n dom.className = 'figure-block';\r\n\r\n // --- Visual area (non-editable, managed by NodeView) ---\r\n const visual = document.createElement('div');\r\n visual.className = 'figure-visual';\r\n visual.contentEditable = 'false';\r\n visual.setAttribute('spellcheck', 'false');\r\n\r\n // ====== Image elements ======\r\n const imgEl = document.createElement('img');\r\n imgEl.className = 'figure-img-preview';\r\n\r\n const uploadArea = document.createElement('div');\r\n uploadArea.className = 'figure-upload-area';\r\n\r\n const uploadHint = document.createElement('span');\r\n uploadHint.className = 'figure-upload-hint';\r\n\r\n const fileInput = document.createElement('input');\r\n fileInput.type = 'file';\r\n fileInput.accept = 'image/*';\r\n fileInput.style.display = 'none';\r\n\r\n const replaceBtn = document.createElement('button');\r\n replaceBtn.className = 'figure-replace-btn';\r\n\r\n uploadArea.append(uploadHint, fileInput);\r\n\r\n // ====== Mermaid elements ======\r\n // View mode: preview area (rendered SVG or placeholder)\r\n const mermaidViewContainer = document.createElement('div');\r\n mermaidViewContainer.className = 'figure-mermaid-view';\r\n mermaidViewContainer.contentEditable = 'false';\r\n mermaidViewContainer.setAttribute('spellcheck', 'false');\r\n\r\n const mermaidPreview = document.createElement('div');\r\n mermaidPreview.className = 'figure-mermaid-preview';\r\n mermaidPreview.contentEditable = 'false';\r\n\r\n const mermaidViewHint = document.createElement('div');\r\n mermaidViewHint.className = 'figure-mermaid-view-hint';\r\n\r\n mermaidViewContainer.append(mermaidPreview, mermaidViewHint);\r\n\r\n // Edit mode: textarea + toolbar\r\n const mermaidEditContainer = document.createElement('div');\r\n mermaidEditContainer.className = 'figure-mermaid-edit';\r\n\r\n const mermaidEditor = document.createElement('textarea');\r\n mermaidEditor.className = 'figure-mermaid-editor';\r\n mermaidEditor.spellcheck = false;\r\n\r\n const mermaidToolbar = document.createElement('div');\r\n mermaidToolbar.className = 'figure-mermaid-toolbar';\r\n\r\n const mermaidSaveBtn = document.createElement('button');\r\n mermaidSaveBtn.className = 'figure-mermaid-save-btn';\r\n mermaidSaveBtn.type = 'button';\r\n\r\n const mermaidCancelBtn = document.createElement('button');\r\n mermaidCancelBtn.className = 'figure-mermaid-cancel-btn';\r\n mermaidCancelBtn.type = 'button';\r\n\r\n const mermaidErrorMsg = document.createElement('span');\r\n mermaidErrorMsg.className = 'figure-mermaid-error-inline';\r\n\r\n mermaidToolbar.append(mermaidErrorMsg, mermaidCancelBtn, mermaidSaveBtn);\r\n mermaidEditContainer.append(mermaidEditor, mermaidToolbar);\r\n\r\n // ====== DrawIO elements ======\r\n // View mode: image preview + hint\r\n const drawioViewContainer = document.createElement('div');\r\n drawioViewContainer.className = 'figure-drawio-view';\r\n drawioViewContainer.contentEditable = 'false';\r\n\r\n const drawioPreviewImg = document.createElement('img');\r\n drawioPreviewImg.className = 'figure-drawio-preview-img';\r\n drawioPreviewImg.style.display = 'none';\r\n\r\n const drawioViewHint = document.createElement('div');\r\n drawioViewHint.className = 'figure-drawio-view-hint';\r\n\r\n drawioViewContainer.append(drawioPreviewImg, drawioViewHint);\r\n\r\n // Assemble visual\r\n visual.append(imgEl, uploadArea, replaceBtn);\r\n visual.append(mermaidViewContainer, mermaidEditContainer);\r\n visual.append(drawioViewContainer);\r\n\r\n // ====== Caption ======\r\n const caption = document.createElement('figcaption');\r\n caption.className = 'figure-caption';\r\n\r\n const idLabel = document.createElement('span');\r\n idLabel.className = 'figure-id-label';\r\n idLabel.contentEditable = 'false';\r\n\r\n const captionContent = document.createElement('span');\r\n captionContent.className = 'figure-caption-content';\r\n\r\n caption.append(idLabel, captionContent);\r\n dom.append(visual, caption);\r\n\r\n // ====== Helpers ======\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n const handleFiles = (files: FileList | null) => {\r\n if (!files || files.length === 0) return;\r\n const file = files[0];\r\n if (!file.type.startsWith('image/')) return;\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n if (typeof reader.result === 'string') {\r\n setNodeAttrs({ imageSrc: reader.result });\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n };\r\n\r\n // ====== Image events ======\r\n fileInput.addEventListener('change', () => handleFiles(fileInput.files));\r\n uploadArea.addEventListener('click', () => fileInput.click());\r\n replaceBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n fileInput.click();\r\n });\r\n\r\n visual.addEventListener('dragover', (e) => {\r\n if (currentNode.attrs.contentType !== 'image') return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n uploadArea.classList.add('figure-upload-area--dragover');\r\n });\r\n visual.addEventListener('dragleave', () => {\r\n uploadArea.classList.remove('figure-upload-area--dragover');\r\n });\r\n visual.addEventListener('drop', (e) => {\r\n uploadArea.classList.remove('figure-upload-area--dragover');\r\n if (currentNode.attrs.contentType !== 'image') return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n handleFiles(e.dataTransfer?.files ?? null);\r\n });\r\n\r\n // ====== Mermaid: double-click to edit, save to render ======\r\n const enterMermaidEditMode = () => {\r\n if (mermaidEditMode) return;\r\n mermaidEditMode = true;\r\n mermaidEditor.value = typeof currentNode.attrs.mermaidCode === 'string'\r\n ? currentNode.attrs.mermaidCode : '';\r\n mermaidErrorMsg.textContent = '';\r\n mermaidErrorMsg.style.display = 'none';\r\n renderUI();\r\n requestAnimationFrame(() => mermaidEditor.focus());\r\n };\r\n\r\n const exitMermaidEditMode = () => {\r\n mermaidEditMode = false;\r\n renderUI();\r\n };\r\n\r\n const saveMermaidAndRender = async () => {\r\n const code = mermaidEditor.value;\r\n mermaidErrorMsg.textContent = '';\r\n mermaidErrorMsg.style.display = 'none';\r\n\r\n // Validate by trying to render first (don't save bad code to attrs)\r\n const trimmed = code.trim();\r\n if (trimmed) {\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `fig-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n mermaidPreview.innerHTML = svg;\r\n cleanupMermaidOrphans();\r\n } catch {\r\n cleanupMermaidOrphans();\r\n const language = useEditorStore.getState().editorLanguage;\r\n mermaidErrorMsg.textContent = language === 'en'\r\n ? 'Mermaid syntax error, please fix and retry'\r\n : 'Mermaid 语法错误,请修正后重试';\r\n mermaidErrorMsg.style.display = 'inline';\r\n return;\r\n }\r\n }\r\n\r\n setNodeAttrs({ mermaidCode: code });\r\n mermaidEditMode = false;\r\n renderUI();\r\n };\r\n\r\n mermaidViewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterMermaidEditMode();\r\n });\r\n\r\n mermaidSaveBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n void saveMermaidAndRender();\r\n });\r\n\r\n mermaidCancelBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n exitMermaidEditMode();\r\n });\r\n\r\n // Prevent ProseMirror from stealing textarea events\r\n mermaidEditor.addEventListener('mousedown', (e) => e.stopPropagation());\r\n mermaidEditor.addEventListener('keydown', (e) => e.stopPropagation());\r\n mermaidEditor.addEventListener('keypress', (e) => e.stopPropagation());\r\n\r\n // ====== DrawIO: double-click to edit via full-screen modal ======\r\n let drawioMessageHandler: ((ev: MessageEvent) => void) | null = null;\r\n let drawioModal: HTMLDivElement | null = null;\r\n let drawioIframe: HTMLIFrameElement | null = null;\r\n\r\n const enterDrawioEditMode = () => {\r\n if (drawioEditMode) return;\r\n drawioEditMode = true;\r\n renderUI();\r\n\r\n // Create full-screen modal overlay\r\n drawioModal = document.createElement('div');\r\n drawioModal.className = 'drawio-modal-overlay';\r\n\r\n const modalContent = document.createElement('div');\r\n modalContent.className = 'drawio-modal-content';\r\n\r\n const modalHeader = document.createElement('div');\r\n modalHeader.className = 'drawio-modal-header';\r\n\r\n const modalTitle = document.createElement('span');\r\n const language = useEditorStore.getState().editorLanguage;\r\n modalTitle.textContent = language === 'en' ? 'Edit Draw.io Diagram' : '编辑 Draw.io 图表';\r\n modalTitle.className = 'drawio-modal-title';\r\n\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'drawio-modal-close-btn';\r\n closeBtn.textContent = '✕';\r\n closeBtn.type = 'button';\r\n closeBtn.addEventListener('click', () => exitDrawioEditMode());\r\n\r\n modalHeader.append(modalTitle, closeBtn);\r\n\r\n drawioIframe = document.createElement('iframe');\r\n drawioIframe.className = 'drawio-modal-iframe';\r\n drawioIframe.setAttribute('frameborder', '0');\r\n\r\n modalContent.append(modalHeader, drawioIframe);\r\n drawioModal.appendChild(modalContent);\r\n document.body.appendChild(drawioModal);\r\n\r\n const lang = language === 'en' ? 'en' : 'zh';\r\n drawioIframe.src = `https://embed.diagrams.net/?embed=1&proto=json&spin=1&lang=${lang}`;\r\n\r\n const iframeRef = drawioIframe;\r\n drawioMessageHandler = (ev: MessageEvent) => {\r\n if (!iframeRef || ev.source !== iframeRef.contentWindow) return;\r\n let msg: { event?: string; xml?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n const existingXml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: existingXml || '' }), '*'\r\n );\r\n } else if (msg.event === 'save') {\r\n const xml = msg.xml || '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n setNodeAttrs({ drawioXml: xml });\r\n } else if (msg.event === 'export') {\r\n const svgData = msg.data || '';\r\n setNodeAttrs({ drawioSvg: svgData });\r\n exitDrawioEditMode();\r\n } else if (msg.event === 'exit') {\r\n exitDrawioEditMode();\r\n }\r\n };\r\n window.addEventListener('message', drawioMessageHandler);\r\n };\r\n\r\n const exitDrawioEditMode = () => {\r\n drawioEditMode = false;\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n renderUI();\r\n };\r\n\r\n drawioViewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterDrawioEditMode();\r\n });\r\n\r\n // ====== Click non-editable -> focus caption ======\r\n dom.addEventListener('mousedown', (event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) return;\r\n if (target === captionContent || captionContent.contains(target)) return;\r\n if (target === mermaidEditor) return;\r\n if (mermaidEditContainer.contains(target)) return;\r\n if (target === uploadArea || uploadArea.contains(target)) return;\r\n if (target === replaceBtn) return;\r\n if (target === fileInput) return;\r\n // Don't steal focus if double-clicking mermaid/drawio view\r\n if (mermaidViewContainer.contains(target)) return;\r\n if (drawioViewContainer.contains(target)) return;\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n const end = pos + currentNode.nodeSize - 1;\r\n const sel = TextSelection.create(editor.state.doc, end);\r\n editor.view.dispatch(editor.state.tr.setSelection(sel));\r\n });\r\n\r\n // ====== DrawIO: auto-generate SVG if missing ======\r\n let drawioSvgGenQueued = false;\r\n let drawioSvgDebounceTimer: ReturnType<typeof setTimeout> | null = null;\r\n let drawioSvgRetryTimer: ReturnType<typeof setTimeout> | null = null;\r\n let drawioSvgRetries = 0;\r\n const _MAX_SVG_RETRIES = 2;\r\n const _SVG_DEBOUNCE_MS = 1500;\r\n const _SVG_RETRY_DELAY_MS = 3000;\r\n\r\n // ====== Mermaid initial render (from saved attrs, view mode only) ======\r\n let lastRenderedMermaidCode = '';\r\n\r\n const doInitialMermaidRender = async (code: string) => {\r\n const trimmed = code.trim();\r\n if (trimmed === lastRenderedMermaidCode) return;\r\n\r\n if (!trimmed) {\r\n mermaidPreview.innerHTML = '';\r\n lastRenderedMermaidCode = '';\r\n return;\r\n }\r\n\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `fig-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n mermaidPreview.innerHTML = svg;\r\n lastRenderedMermaidCode = trimmed;\r\n } catch {\r\n mermaidPreview.innerHTML = '';\r\n lastRenderedMermaidCode = '';\r\n } finally {\r\n cleanupMermaidOrphans();\r\n }\r\n };\r\n\r\n // ====== renderUI ======\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const contentType: FigureContentType = (['image', 'mermaid', 'drawio'].includes(currentNode.attrs.contentType))\r\n ? currentNode.attrs.contentType as FigureContentType\r\n : 'image';\r\n const figureId = typeof currentNode.attrs.id === 'string' ? currentNode.attrs.id.trim() : '';\r\n const imageSrc = typeof currentNode.attrs.imageSrc === 'string' ? currentNode.attrs.imageSrc : '';\r\n const mermaidCode = typeof currentNode.attrs.mermaidCode === 'string' ? currentNode.attrs.mermaidCode : '';\r\n\r\n // ID label\r\n if (figureId) {\r\n idLabel.textContent = `[${figureId}] `;\r\n idLabel.style.display = 'inline';\r\n } else {\r\n idLabel.textContent = '';\r\n idLabel.style.display = 'none';\r\n }\r\n\r\n const isImage = contentType === 'image';\r\n const isMermaid = contentType === 'mermaid';\r\n const isDrawio = contentType === 'drawio';\r\n\r\n // Image visibility\r\n imgEl.style.display = isImage && imageSrc ? 'block' : 'none';\r\n uploadArea.style.display = isImage && !imageSrc ? 'flex' : 'none';\r\n replaceBtn.style.display = isImage && imageSrc ? 'block' : 'none';\r\n\r\n // Mermaid: view / edit mode\r\n mermaidViewContainer.style.display = isMermaid && !mermaidEditMode ? 'block' : 'none';\r\n mermaidEditContainer.style.display = isMermaid && mermaidEditMode ? 'block' : 'none';\r\n\r\n // DrawIO: view mode only (edit is in modal)\r\n drawioViewContainer.style.display = isDrawio ? 'flex' : 'none';\r\n\r\n // Image src\r\n if (isImage && imageSrc) {\r\n imgEl.src = imageSrc;\r\n }\r\n\r\n // DrawIO image preview (drawioSvg is a data URI like \"data:image/svg+xml;base64,...\")\r\n const drawioSvg = typeof currentNode.attrs.drawioSvg === 'string' ? currentNode.attrs.drawioSvg : '';\r\n if (isDrawio) {\r\n if (drawioSvg) {\r\n drawioPreviewImg.src = drawioSvg;\r\n drawioPreviewImg.style.display = 'block';\r\n } else {\r\n drawioPreviewImg.src = '';\r\n drawioPreviewImg.style.display = 'none';\r\n }\r\n }\r\n\r\n // i18n texts\r\n uploadHint.textContent = (i18n.figureUploadHint as string) || '点击上传或拖拽图片';\r\n replaceBtn.textContent = (i18n.figureReplaceImage as string) || '更换图片';\r\n mermaidSaveBtn.textContent = (i18n.mermaidSaveAndRender as string) || '保存并渲染';\r\n mermaidCancelBtn.textContent = (i18n.mermaidCancel as string) || '取消';\r\n\r\n // Mermaid view mode hint\r\n const hasCode = mermaidCode.trim().length > 0;\r\n const hasSvg = mermaidPreview.querySelector('svg') !== null;\r\n if (isMermaid && !mermaidEditMode) {\r\n if (hasCode && hasSvg) {\r\n mermaidViewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n mermaidViewHint.className = 'figure-mermaid-view-hint figure-mermaid-view-hint--subtle';\r\n } else {\r\n mermaidViewHint.textContent = (i18n.mermaidDoubleClickToCreate as string) || '双击编辑 Mermaid 图表';\r\n mermaidViewHint.className = 'figure-mermaid-view-hint figure-mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n // DrawIO view hint\r\n if (isDrawio && !drawioEditMode) {\r\n if (drawioSvg) {\r\n drawioViewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n drawioViewHint.className = 'figure-drawio-view-hint figure-mermaid-view-hint--subtle';\r\n } else {\r\n drawioViewHint.textContent = (i18n.drawioDoubleClickToEdit as string) || '双击编辑 Draw.io 图表';\r\n drawioViewHint.className = 'figure-drawio-view-hint figure-mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n // Trigger initial mermaid render in view mode if code exists\r\n if (isMermaid && !mermaidEditMode && mermaidCode.trim() !== lastRenderedMermaidCode) {\r\n void doInitialMermaidRender(mermaidCode);\r\n }\r\n\r\n // Auto-generate SVG for drawio figures that have XML but no SVG.\r\n // Debounced to avoid wasted attempts during rapid SSE streaming updates,\r\n // with retry on failure (e.g. iframe timeout).\r\n const drawioXml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n if (isDrawio && drawioXml && !drawioSvg && !drawioSvgGenQueued && !drawioEditMode) {\r\n if (drawioSvgDebounceTimer) clearTimeout(drawioSvgDebounceTimer);\r\n drawioSvgDebounceTimer = setTimeout(() => {\r\n drawioSvgDebounceTimer = null;\r\n const xml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n const svg = typeof currentNode.attrs.drawioSvg === 'string' ? currentNode.attrs.drawioSvg : '';\r\n if (!xml || svg || drawioSvgGenQueued) return;\r\n drawioSvgGenQueued = true;\r\n queueDrawioSvgGen(xml, (result) => {\r\n drawioSvgGenQueued = false;\r\n if (result) {\r\n drawioSvgRetries = 0;\r\n setNodeAttrs({ drawioSvg: result });\r\n } else if (drawioSvgRetries < _MAX_SVG_RETRIES) {\r\n drawioSvgRetries++;\r\n drawioSvgRetryTimer = setTimeout(() => {\r\n drawioSvgRetryTimer = null;\r\n renderUI();\r\n }, _SVG_RETRY_DELAY_MS * drawioSvgRetries);\r\n }\r\n });\r\n }, _SVG_DEBOUNCE_MS);\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n contentDOM: captionContent,\r\n stopEvent: (event: Event) => {\r\n const target = event.target;\r\n if (target === mermaidEditor) return true;\r\n if (mermaidEditContainer.contains(target as globalThis.Node)) return true;\r\n if (target === fileInput) return true;\r\n return false;\r\n },\r\n ignoreMutation: (mutation: MutationRecord | { type: 'selection'; target: Element }) => {\r\n const target = mutation.target as unknown as globalThis.Node;\r\n if (visual.contains(target)) return true;\r\n if (idLabel.contains(target)) return true;\r\n return false;\r\n },\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'figure') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n if (drawioSvgDebounceTimer) { clearTimeout(drawioSvgDebounceTimer); drawioSvgDebounceTimer = null; }\r\n if (drawioSvgRetryTimer) { clearTimeout(drawioSvgRetryTimer); drawioSvgRetryTimer = null; }\r\n unsub();\r\n cleanupMermaidOrphans();\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport const ReferenceNode = Node.create({\r\n name: 'reference',\r\n group: 'inline',\r\n inline: true,\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n targetType: {\r\n default: 'claim',\r\n },\r\n target: {\r\n default: null,\r\n },\r\n targetClaimId: {\r\n default: null,\r\n },\r\n targetFigureId: {\r\n default: null,\r\n },\r\n displayText: {\r\n default: null,\r\n },\r\n resolvedNumber: {\r\n default: null,\r\n },\r\n resolvedFigureId: {\r\n default: null,\r\n },\r\n lang: {\r\n default: 'zh',\r\n },\r\n invalid: {\r\n default: false,\r\n },\r\n highlight: {\r\n default: false,\r\n },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: 'span[data-type=\"reference\"]',\r\n },\r\n ];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n const language = HTMLAttributes.lang === 'en' ? 'en' : 'zh';\r\n const targetType = HTMLAttributes.targetType === 'figure' ? 'figure' : 'claim';\r\n const fallback = targetType === 'figure'\r\n ? (HTMLAttributes.resolvedFigureId || (language === 'en' ? 'Figure ?' : '附图?'))\r\n : (language === 'en'\r\n ? `Claim ${HTMLAttributes.resolvedNumber ? String(HTMLAttributes.resolvedNumber) : '?'}`\r\n : `权利要求${HTMLAttributes.resolvedNumber ? String(HTMLAttributes.resolvedNumber) : '?'}`);\r\n const text = HTMLAttributes.displayText || fallback;\r\n return [\r\n 'span',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'reference',\r\n class: `reference-link${HTMLAttributes.invalid ? ' reference-link-invalid' : ''}`,\r\n }),\r\n text,\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ node, editor }) => {\r\n let currentNode = node;\r\n const dom = document.createElement('span');\r\n const rerender = () => {\r\n const language = currentNode.attrs.lang === 'en' ? 'en' : 'zh';\r\n const i18n = getEditorText(language);\r\n const targetType = currentNode.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n const resolvedNumber = Number(currentNode.attrs.resolvedNumber);\r\n const resolvedFigureId =\r\n typeof currentNode.attrs.resolvedFigureId === 'string' && currentNode.attrs.resolvedFigureId\r\n ? currentNode.attrs.resolvedFigureId\r\n : null;\r\n const fallback = targetType === 'figure'\r\n ? (resolvedFigureId || (language === 'en' ? 'Figure ?' : '附图?'))\r\n : (Number.isFinite(resolvedNumber)\r\n ? i18n.claimLabel(resolvedNumber)\r\n : (language === 'en' ? 'Claim ?' : '权利要求?'));\r\n const text = currentNode.attrs.displayText || fallback;\r\n dom.textContent = text;\r\n dom.className = `reference-link${currentNode.attrs.invalid ? ' reference-link-invalid' : ''}`;\r\n dom.setAttribute('data-type', 'reference');\r\n dom.setAttribute('data-highlight', currentNode.attrs.highlight ? 'true' : 'false');\r\n dom.title = currentNode.attrs.invalid\r\n ? i18n.referenceNavigateDisabledTitle\r\n : targetType === 'figure'\r\n ? i18n.figureReferenceNavigateTitle\r\n : i18n.referenceNavigateTitle;\r\n };\r\n rerender();\r\n dom.addEventListener('click', () => {\r\n const targetType = currentNode.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n if (currentNode.attrs.invalid) {\r\n return;\r\n }\r\n // Defer navigation so it runs after ProseMirror's own atom-node\r\n // selection handling; otherwise the NodeSelection may overwrite ours.\r\n setTimeout(() => {\r\n let targetPos: number | null = null;\r\n if (targetType === 'figure') {\r\n const targetFigureId =\r\n typeof currentNode.attrs.targetFigureId === 'string' ? currentNode.attrs.targetFigureId : '';\r\n if (!targetFigureId) {\r\n return;\r\n }\r\n editor.state.doc.descendants((descendant, pos) => {\r\n if (targetPos !== null) return false;\r\n if (descendant.type.name === 'figure' && descendant.attrs.id === targetFigureId) {\r\n targetPos = pos;\r\n return false;\r\n }\r\n return true;\r\n });\r\n } else {\r\n if (!currentNode.attrs.targetClaimId) {\r\n return;\r\n }\r\n editor.state.doc.descendants((descendant, pos) => {\r\n if (targetPos !== null) return false;\r\n if (descendant.type.name === 'claim' && descendant.attrs.claimId === currentNode.attrs.targetClaimId) {\r\n targetPos = pos;\r\n return false;\r\n }\r\n return true;\r\n });\r\n }\r\n if (typeof targetPos === 'number') {\r\n editor.chain().focus().setTextSelection(targetPos + 1).scrollIntoView().run();\r\n }\r\n }, 0);\r\n });\r\n return {\r\n dom,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== this.name) {\r\n return false;\r\n }\r\n currentNode = updatedNode;\r\n rerender();\r\n return true;\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Slice, Fragment, Node as PMNode } from '@tiptap/pm/model';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport type PatentSectionType =\r\n // Invention & Utility Model\r\n | 'technical_field'\r\n | 'background_art'\r\n | 'summary'\r\n | 'drawing_description'\r\n | 'detailed_description'\r\n | 'claims'\r\n | 'abstract'\r\n | 'abstract_drawing'\r\n | 'drawing_figures'\r\n // Design Patent\r\n | 'design_product_name'\r\n | 'design_usage'\r\n | 'design_description'\r\n | 'design_views'\r\n | 'design_brief';\r\n\r\n\r\nconst SECTION_TITLE_I18N_KEYS: Record<PatentSectionType, string> = {\r\n technical_field: 'sectionTitle_technical_field',\r\n background_art: 'sectionTitle_background_art',\r\n summary: 'sectionTitle_summary',\r\n drawing_description: 'sectionTitle_drawing_description',\r\n detailed_description: 'sectionTitle_detailed_description',\r\n claims: 'sectionTitle_claims',\r\n abstract: 'sectionTitle_abstract',\r\n abstract_drawing: 'sectionTitle_abstract_drawing',\r\n drawing_figures: 'sectionTitle_drawing_figures',\r\n design_product_name: 'sectionTitle_design_product_name',\r\n design_usage: 'sectionTitle_design_usage',\r\n design_description: 'sectionTitle_design_description',\r\n design_views: 'sectionTitle_design_views',\r\n design_brief: 'sectionTitle_design_brief',\r\n};\r\n\r\n/** Sections that are top-level \"books\" in the CNIPA five-book structure */\r\nconst BOOK_LEVEL_SECTIONS = new Set<PatentSectionType>([\r\n 'abstract', 'abstract_drawing', 'claims', 'drawing_figures',\r\n // Design patent sections are also book-level\r\n 'design_product_name', 'design_usage', 'design_description', 'design_views', 'design_brief',\r\n]);\r\n\r\n/** Sub-sections that belong under 说明书 */\r\nconst DESCRIPTION_SUB_SECTIONS = new Set<PatentSectionType>([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\nconst hasMeaningfulContent = (node: PMNode): boolean => {\r\n if (node.isText) {\r\n return (node.text ?? '').trim().length > 0;\r\n }\r\n\r\n if (node.isAtom || node.isLeaf) {\r\n return true;\r\n }\r\n\r\n if (!['patent_section', 'patent_title', 'paragraph'].includes(node.type.name)) {\r\n return true;\r\n }\r\n\r\n let found = false;\r\n node.forEach((child) => {\r\n if (!found && hasMeaningfulContent(child)) {\r\n found = true;\r\n }\r\n });\r\n return found;\r\n};\r\n\r\n/* ──── Patent Title Node (standalone editable title, under 说明书) ──── */\r\n\r\nexport const PatentTitleNode = Node.create({\r\n name: 'patent_title',\r\n group: 'block',\r\n content: 'inline*',\r\n defining: true,\r\n isolating: true,\r\n draggable: false,\r\n\r\n parseHTML() {\r\n return [{ tag: 'h1[data-type=\"patent-title\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'h1',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'patent-title',\r\n class: 'patent-title',\r\n }),\r\n 0,\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n\r\n const dom = document.createElement('div');\r\n dom.className = 'pt-title';\r\n dom.setAttribute('data-type', 'patent-title');\r\n\r\n // \"说明书\" book-level header\r\n const bookHeading = document.createElement('div');\r\n bookHeading.className = 'pb-heading';\r\n bookHeading.contentEditable = 'false';\r\n\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'ps-placeholder';\r\n placeholder.contentEditable = 'false';\r\n\r\n const contentArea = document.createElement('h1');\r\n contentArea.className = 'pt-title-content';\r\n\r\n dom.append(bookHeading, placeholder, contentArea);\r\n\r\n const getNodePos = (): number | null => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n return typeof pos === 'number' ? pos : null;\r\n };\r\n\r\n const activateTitle = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n useEditorStore.getState().setActiveSection('patent_title', pos);\r\n };\r\n\r\n const onPlaceholderClick = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n useEditorStore.getState().openDraftingPanel('patent_title', pos);\r\n editor.commands.focus(pos + 1);\r\n };\r\n\r\n placeholder.addEventListener('click', onPlaceholderClick);\r\n contentArea.addEventListener('focusin', activateTitle);\r\n contentArea.addEventListener('click', activateTitle);\r\n\r\n const render = () => {\r\n const state = useEditorStore.getState();\r\n const i18n = getEditorText(state.editorLanguage) as Record<string, unknown>;\r\n\r\n const bookLabel = (typeof i18n['bookTitle_description'] === 'string'\r\n ? i18n['bookTitle_description'] : '说明书') as string;\r\n const titleLabel = (typeof i18n['patentTitlePlaceholder'] === 'string'\r\n ? i18n['patentTitlePlaceholder'] : '专利名称') as string;\r\n\r\n bookHeading.textContent = bookLabel;\r\n\r\n const hasContent = hasMeaningfulContent(currentNode);\r\n const isActive = state.rightPanel.activeSectionPos === getNodePos();\r\n\r\n placeholder.textContent = `[${titleLabel}]`;\r\n placeholder.style.display = hasContent ? 'none' : '';\r\n placeholder.classList.toggle('ps-placeholder--active', isActive && !hasContent);\r\n contentArea.classList.toggle('pt-title-content--has-content', hasContent);\r\n };\r\n\r\n let prevLang = useEditorStore.getState().editorLanguage;\r\n let prevActivePos = useEditorStore.getState().rightPanel.activeSectionPos;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n const langChanged = state.editorLanguage !== prevLang;\r\n const posChanged = state.rightPanel.activeSectionPos !== prevActivePos;\r\n prevLang = state.editorLanguage;\r\n prevActivePos = state.rightPanel.activeSectionPos;\r\n if (langChanged || posChanged) render();\r\n });\r\n\r\n render();\r\n\r\n return {\r\n dom,\r\n contentDOM: contentArea,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'patent_title') return false;\r\n currentNode = updatedNode;\r\n render();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n placeholder.removeEventListener('click', onPlaceholderClick);\r\n contentArea.removeEventListener('focusin', activateTitle);\r\n contentArea.removeEventListener('click', activateTitle);\r\n },\r\n };\r\n };\r\n },\r\n});\r\n\r\n/* ──── Patent Section Node ──── */\r\n\r\nexport const PatentSectionNode = Node.create({\r\n name: 'patent_section',\r\n group: 'block',\r\n content: 'block+',\r\n defining: true,\r\n isolating: true,\r\n draggable: false,\r\n\r\n addAttributes() {\r\n return {\r\n sectionType: { default: 'technical_field' as PatentSectionType },\r\n collapsed: { default: false },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'section[data-type=\"patent-section\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'section',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'patent-section',\r\n 'data-section-type': HTMLAttributes.sectionType,\r\n class: 'patent-section',\r\n }),\r\n 0,\r\n ];\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n const stripSectionWrappers = (fragment: Fragment): Fragment => {\r\n const nodes: PMNode[] = [];\r\n fragment.forEach((node) => {\r\n if (node.type.name === 'patent_section' || node.type.name === 'patent_title') {\r\n // Unwrap: push the children instead of the wrapper\r\n const inner = stripSectionWrappers(node.content);\r\n inner.forEach((child) => nodes.push(child));\r\n } else {\r\n // Recurse into other block nodes that might contain nested sections\r\n if (node.isBlock && node.content.size > 0) {\r\n nodes.push(node.copy(stripSectionWrappers(node.content)));\r\n } else {\r\n nodes.push(node);\r\n }\r\n }\r\n });\r\n return Fragment.from(nodes);\r\n };\r\n\r\n return [\r\n new Plugin({\r\n key: new PluginKey('patentSectionLock'),\r\n props: {\r\n transformPasted: (slice) => {\r\n const cleaned = stripSectionWrappers(slice.content);\r\n return new Slice(cleaned, slice.openStart, slice.openEnd);\r\n },\r\n },\r\n filterTransaction: (tr, state) => {\r\n if (!tr.docChanged) return true;\r\n const oldOrder: string[] = [];\r\n const newOrder: string[] = [];\r\n state.doc.forEach((node) => {\r\n if (node.type.name === 'patent_section') {\r\n oldOrder.push(node.attrs.sectionType);\r\n }\r\n });\r\n tr.doc.forEach((node) => {\r\n if (node.type.name === 'patent_section') {\r\n newOrder.push(node.attrs.sectionType);\r\n }\r\n });\r\n if (oldOrder.length !== newOrder.length) return true;\r\n for (let i = 0; i < oldOrder.length; i++) {\r\n if (oldOrder[i] !== newOrder[i]) return false;\r\n }\r\n return true;\r\n },\r\n }),\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n\r\n const dom = document.createElement('section');\r\n dom.setAttribute('data-type', 'patent-section');\r\n\r\n const heading = document.createElement('div');\r\n heading.contentEditable = 'false';\r\n\r\n const body = document.createElement('div');\r\n body.className = 'ps-body';\r\n\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'ps-placeholder';\r\n placeholder.contentEditable = 'false';\r\n\r\n const contentArea = document.createElement('div');\r\n contentArea.className = 'ps-content';\r\n\r\n body.append(placeholder, contentArea);\r\n dom.append(heading, body);\r\n\r\n const getNodePos = (): number | null => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n return typeof pos === 'number' ? pos : null;\r\n };\r\n\r\n const activateSection = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n const store = useEditorStore.getState();\r\n store.setActiveSection(currentNode.attrs.sectionType, pos);\r\n };\r\n\r\n const openDraftingForSection = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n const store = useEditorStore.getState();\r\n store.openDraftingPanel(currentNode.attrs.sectionType, pos);\r\n editor.commands.focus(pos + 1);\r\n };\r\n\r\n placeholder.addEventListener('click', openDraftingForSection);\r\n contentArea.addEventListener('focusin', activateSection);\r\n contentArea.addEventListener('click', activateSection);\r\n\r\n const render = () => {\r\n const state = useEditorStore.getState();\r\n const i18n = getEditorText(state.editorLanguage) as Record<string, unknown>;\r\n\r\n const sectionType: PatentSectionType =\r\n (Object.keys(SECTION_TITLE_I18N_KEYS).includes(currentNode.attrs.sectionType))\r\n ? currentNode.attrs.sectionType as PatentSectionType\r\n : 'technical_field';\r\n\r\n const isBook = BOOK_LEVEL_SECTIONS.has(sectionType);\r\n const isSub = DESCRIPTION_SUB_SECTIONS.has(sectionType);\r\n const titleKey = SECTION_TITLE_I18N_KEYS[sectionType];\r\n const sectionTitle = (typeof i18n[titleKey] === 'string' ? i18n[titleKey] : sectionType) as string;\r\n\r\n const hasContent = hasMeaningfulContent(currentNode);\r\n const isActive = state.rightPanel.activeSectionPos === getNodePos();\r\n\r\n dom.className = `ps${hasContent ? '' : ' ps--empty'}${isSub ? ' ps--sub' : ''}`;\r\n dom.setAttribute('data-section-type', sectionType);\r\n\r\n heading.className = isBook ? 'pb-heading' : 'ps-heading ps-heading--sub';\r\n heading.textContent = sectionTitle;\r\n\r\n placeholder.textContent = `[${sectionTitle}]`;\r\n placeholder.style.display = hasContent ? 'none' : '';\r\n placeholder.classList.toggle('ps-placeholder--active', isActive && !hasContent);\r\n contentArea.classList.toggle('ps-content--has-content', hasContent);\r\n\r\n };\r\n\r\n let prevLang = useEditorStore.getState().editorLanguage;\r\n let prevActivePos = useEditorStore.getState().rightPanel.activeSectionPos;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n const langChanged = state.editorLanguage !== prevLang;\r\n const posChanged = state.rightPanel.activeSectionPos !== prevActivePos;\r\n prevLang = state.editorLanguage;\r\n prevActivePos = state.rightPanel.activeSectionPos;\r\n if (langChanged || posChanged) render();\r\n });\r\n\r\n render();\r\n\r\n return {\r\n dom,\r\n contentDOM: contentArea,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'patent_section') return false;\r\n currentNode = updatedNode;\r\n render();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n placeholder.removeEventListener('click', openDraftingForSection);\r\n contentArea.removeEventListener('focusin', activateSection);\r\n contentArea.removeEventListener('click', activateSection);\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import type { JSONContent } from '@tiptap/react';\r\nimport type { PatentSectionType } from './sectionNode';\r\n\r\nexport type PatentType = 'invention' | 'utility_model' | 'design';\r\n\r\n/** Sections BEFORE 说明书 (patent_title inserted between these and description sub-sections) */\r\nconst PRE_DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'abstract', // 说明书摘要\r\n 'abstract_drawing', // 摘要附图\r\n];\r\n\r\n/** 说明书 sub-sections (patent_title is first, then these, then drawing_figures) */\r\nconst DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'technical_field',\r\n 'background_art',\r\n 'summary',\r\n 'drawing_description',\r\n 'detailed_description',\r\n];\r\n\r\n/** Sections AFTER 说明书 */\r\nconst POST_DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'drawing_figures', // 说明书附图\r\n];\r\n\r\nconst DESIGN_SECTIONS: PatentSectionType[] = [\r\n 'design_product_name',\r\n 'design_usage',\r\n 'design_description',\r\n 'design_views',\r\n 'design_brief',\r\n];\r\n\r\nconst buildSectionNode = (sectionType: PatentSectionType): JSONContent => ({\r\n type: 'patent_section',\r\n attrs: {\r\n sectionType,\r\n collapsed: false,\r\n },\r\n content: [\r\n {\r\n type: 'paragraph',\r\n },\r\n ],\r\n});\r\n\r\nconst buildTitleNode = (): JSONContent => ({\r\n type: 'patent_title',\r\n content: [],\r\n});\r\n\r\nconst buildInventionContent = (): JSONContent[] => [\r\n ...PRE_DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n buildTitleNode(),\r\n ...DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n ...POST_DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n];\r\n\r\nconst buildDesignContent = (): JSONContent[] => [\r\n buildTitleNode(),\r\n ...DESIGN_SECTIONS.map(buildSectionNode),\r\n];\r\n\r\nexport const buildPatentDocument = (patentType: PatentType = 'invention'): JSONContent => {\r\n const content = patentType === 'design' ? buildDesignContent() : buildInventionContent();\r\n return { type: 'doc', content };\r\n};\r\n\r\nexport const buildPatentSections = (patentType: PatentType = 'invention'): JSONContent[] => {\r\n return patentType === 'design' ? buildDesignContent() : buildInventionContent();\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\r\nimport { findAncestorNode, findNodesByPredicate, insertNode, removeNode, updateNodeAttrs } from '../../commands';\r\nimport { EditorPlugin } from '../../../types/plugin';\r\nimport { ClaimNode } from './claimNode';\r\nimport { FigureNode, FigureContentType } from './figureNode';\r\nimport { ReferenceNode } from './referenceNode';\r\nimport { PatentSectionNode, PatentTitleNode, PatentSectionType } from './sectionNode';\r\nimport { buildPatentDocument, PatentType } from './patentDocTemplate';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { formatClaimGraphIssueMessage, getEditorText } from '../../../lib/editorI18n';\r\n\r\ntype ReferenceLanguage = 'zh' | 'en';\r\ntype ReferenceTargetType = 'claim' | 'figure';\r\n\r\ninterface InsertClaimPayload {\r\n number?: number;\r\n text?: string;\r\n placement?: 'current' | 'end';\r\n}\r\n\r\ninterface UpdateClaimPayload {\r\n position?: number;\r\n number?: number;\r\n text?: string;\r\n}\r\n\r\ninterface DeleteClaimPayload {\r\n position?: number;\r\n}\r\n\r\ninterface InsertReferencePayload {\r\n targetType?: ReferenceTargetType;\r\n targetClaimId?: string;\r\n targetFigureId?: string;\r\n displayText?: string;\r\n lang?: ReferenceLanguage;\r\n target?: string;\r\n}\r\n\r\ninterface RepairReferencesPayload {\r\n targetClaimId: string;\r\n}\r\n\r\ninterface SetClaimDependencyPayload {\r\n position?: number;\r\n dependsOn?: number[];\r\n}\r\n\r\ninterface SetReferenceLanguagePayload {\r\n lang: ReferenceLanguage;\r\n scope?: 'all' | 'current';\r\n}\r\n\r\ninterface UpdateFigurePayload {\r\n position?: number;\r\n id?: string | null;\r\n caption?: string;\r\n contentType?: FigureContentType;\r\n imageSrc?: string;\r\n mermaidCode?: string;\r\n drawioXml?: string;\r\n}\r\n\r\ninterface InsertFigurePayload {\r\n id?: string;\r\n contentType?: FigureContentType;\r\n captionText?: string;\r\n}\r\n\r\ninterface InsertPatentDocumentPayload {\r\n patentType?: PatentType;\r\n}\r\n\r\n\r\ninterface ToggleSectionCollapsePayload {\r\n position?: number;\r\n}\r\n\r\ninterface InvalidReferenceContext {\r\n targetType: ReferenceTargetType;\r\n targetClaimId: string | null;\r\n targetFigureId: string | null;\r\n position: number;\r\n}\r\n\r\ninterface ClaimGraphIssue {\r\n claimId: string;\r\n code: 'forward_reference' | 'self_reference' | 'cycle_dependency';\r\n claimNumber: number;\r\n targetNumber?: number;\r\n message: string;\r\n}\r\n\r\ninterface ClaimGraphValidationContext {\r\n issues: ClaimGraphIssue[];\r\n}\r\n\r\ninterface ClaimItem {\r\n claimId: string;\r\n number: number;\r\n dependsOnClaimIds: string[];\r\n pos: number;\r\n}\r\n\r\nconst CLAIM_CONTENT_LIMIT = 400;\r\n\r\n// 插件运行时状态,统一管理,不再散落为多个模块级变量\r\nconst pluginState = {\r\n lastClaimWarningSignature: '',\r\n lastInvalidReferenceSignature: '',\r\n lastClaimGraphSignature: '',\r\n invalidReferenceHandler: null as ((context: InvalidReferenceContext) => void) | null,\r\n claimGraphHandler: null as ((context: ClaimGraphValidationContext) => void) | null,\r\n};\r\n\r\nconst getClaimNodes = (editor: Editor) => {\r\n return findNodesByPredicate(editor, (node) => node.type.name === 'claim');\r\n};\r\n\r\nconst getFigureNodes = (editor: Editor) => {\r\n return findNodesByPredicate(editor, (node) => node.type.name === 'figure');\r\n};\r\n\r\nconst createClaimId = () => {\r\n return `claim_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\r\n};\r\n\r\nconst normalizeFigureId = (value: unknown) => {\r\n if (typeof value !== 'string') {\r\n return '';\r\n }\r\n return value.trim();\r\n};\r\n\r\nconst suggestNextFigureId = (editor: Editor) => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const prefix = language === 'en' ? 'Fig.' : '图';\r\n const used = new Set<string>();\r\n getFigureNodes(editor).forEach((item) => {\r\n const id = normalizeFigureId(item.node.attrs.id);\r\n if (id) {\r\n used.add(id);\r\n }\r\n });\r\n let index = 1;\r\n while (used.has(`${prefix}${index}`)) {\r\n index += 1;\r\n }\r\n return `${prefix}${index}`;\r\n};\r\n\r\nconst FIGURE_ID_PATTERN = /^(Fig\\.|图)(\\d+)$/;\r\n\r\nconst syncFigureOrder = (editor: Editor) => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const prefix = language === 'en' ? 'Fig.' : '图';\r\n const figures = getFigureNodes(editor);\r\n if (figures.length === 0) return;\r\n\r\n const updates: { pos: number; expectedId: string; currentId: string }[] = [];\r\n let seqIndex = 1;\r\n\r\n for (const fig of figures) {\r\n const currentId = normalizeFigureId(fig.node.attrs.id);\r\n const match = FIGURE_ID_PATTERN.exec(currentId);\r\n if (!match) continue;\r\n\r\n const expectedId = `${prefix}${seqIndex}`;\r\n if (currentId !== expectedId) {\r\n updates.push({ pos: fig.pos, expectedId, currentId });\r\n }\r\n seqIndex++;\r\n }\r\n\r\n if (updates.length === 0) return;\r\n\r\n const { tr } = editor.state;\r\n for (const u of updates) {\r\n const node = tr.doc.nodeAt(u.pos);\r\n if (!node || node.type.name !== 'figure') continue;\r\n tr.setNodeMarkup(u.pos, undefined, { ...node.attrs, id: u.expectedId });\r\n }\r\n if (tr.steps.length > 0) {\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n }\r\n};\r\n\r\nconst normalizeNumberArray = (value: unknown): number[] => {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const numbers = value\r\n .map(item => Number(item))\r\n .filter(item => Number.isFinite(item) && item > 0);\r\n return Array.from(new Set(numbers)).sort((a, b) => a - b);\r\n};\r\n\r\nconst normalizeStringArray = (value: unknown): string[] => {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const items = value\r\n .map(item => (typeof item === 'string' ? item.trim() : ''))\r\n .filter(Boolean);\r\n return Array.from(new Set(items));\r\n};\r\n\r\nconst sameArray = (a: unknown[], b: unknown[]) => {\r\n if (a.length !== b.length) {\r\n return false;\r\n }\r\n for (let i = 0; i < a.length; i += 1) {\r\n if (a[i] !== b[i]) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n};\r\n\r\nconst buildReferenceText = (\r\n lang: ReferenceLanguage,\r\n targetType: ReferenceTargetType,\r\n resolvedNumber: number | null,\r\n resolvedFigureId: string | null,\r\n invalid: boolean\r\n) => {\r\n const i18n = getEditorText(lang);\r\n if (invalid) {\r\n return targetType === 'figure'\r\n ? i18n.invalidFigureReference\r\n : i18n.invalidClaimReference;\r\n }\r\n if (targetType === 'figure') {\r\n if (resolvedFigureId) {\r\n return resolvedFigureId;\r\n }\r\n return lang === 'en' ? 'Figure ?' : '附图?';\r\n }\r\n if (typeof resolvedNumber !== 'number') {\r\n return i18n.invalidClaimReference;\r\n }\r\n return i18n.claimLabel(resolvedNumber);\r\n};\r\n\r\nconst getGlobalReferenceLanguage = (): ReferenceLanguage => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n return language === 'en' ? 'en' : 'zh';\r\n};\r\n\r\nconst validateClaimGraph = (claims: ClaimItem[]): ClaimGraphIssue[] => {\r\n const issues: ClaimGraphIssue[] = [];\r\n const language = getGlobalReferenceLanguage();\r\n const numberMap = new Map(claims.map(item => [item.claimId, item.number]));\r\n claims.forEach((claim) => {\r\n claim.dependsOnClaimIds.forEach((dependencyId) => {\r\n const targetNumber = numberMap.get(dependencyId);\r\n if (dependencyId === claim.claimId) {\r\n issues.push({\r\n claimId: claim.claimId,\r\n code: 'self_reference',\r\n claimNumber: claim.number,\r\n message: formatClaimGraphIssueMessage(language, 'self_reference', claim.number),\r\n });\r\n }\r\n if (typeof targetNumber === 'number' && targetNumber >= claim.number) {\r\n issues.push({\r\n claimId: claim.claimId,\r\n code: 'forward_reference',\r\n claimNumber: claim.number,\r\n targetNumber,\r\n message: formatClaimGraphIssueMessage(language, 'forward_reference', claim.number, targetNumber),\r\n });\r\n }\r\n });\r\n });\r\n\r\n const adjacency = new Map(claims.map(item => [item.claimId, item.dependsOnClaimIds]));\r\n const visited = new Set<string>();\r\n const inStack = new Set<string>();\r\n const cycleNodes = new Set<string>();\r\n\r\n const dfs = (nodeId: string) => {\r\n if (inStack.has(nodeId)) {\r\n cycleNodes.add(nodeId);\r\n return;\r\n }\r\n if (visited.has(nodeId)) {\r\n return;\r\n }\r\n visited.add(nodeId);\r\n inStack.add(nodeId);\r\n const deps = adjacency.get(nodeId) || [];\r\n deps.forEach(depId => dfs(depId));\r\n inStack.delete(nodeId);\r\n };\r\n\r\n claims.forEach(item => dfs(item.claimId));\r\n cycleNodes.forEach((nodeId) => {\r\n const claim = claims.find(item => item.claimId === nodeId);\r\n if (!claim) {\r\n return;\r\n }\r\n issues.push({\r\n claimId: nodeId,\r\n code: 'cycle_dependency',\r\n claimNumber: claim.number,\r\n message: formatClaimGraphIssueMessage(language, 'cycle_dependency', claim.number),\r\n });\r\n });\r\n return issues;\r\n};\r\n\r\nconst syncClaimState = (editor: Editor) => {\r\n const claimNodes = getClaimNodes(editor);\r\n const usedClaimIds = new Set<string>();\r\n const baseClaims = claimNodes.map((match, index) => {\r\n const rawClaimId = typeof match.node.attrs.claimId === 'string' ? match.node.attrs.claimId : '';\r\n const claimId = rawClaimId && !usedClaimIds.has(rawClaimId) ? rawClaimId : createClaimId();\r\n usedClaimIds.add(claimId);\r\n return { pos: match.pos, node: match.node, claimId, number: index + 1 };\r\n });\r\n\r\n const numberToId = new Map<number, string>();\r\n const idToNumber = new Map<string, number>();\r\n baseClaims.forEach(item => {\r\n numberToId.set(item.number, item.claimId);\r\n idToNumber.set(item.claimId, item.number);\r\n });\r\n\r\n const normalizedClaims = baseClaims.map((item): ClaimItem & { attrs: Record<string, unknown> } => {\r\n const currentDependsOnIds = normalizeStringArray(item.node.attrs.dependsOnClaimIds);\r\n const currentDependsOnNumbers = normalizeNumberArray(item.node.attrs.dependsOn);\r\n const fallbackIds = currentDependsOnNumbers\r\n .map(number => numberToId.get(number))\r\n .filter((id): id is string => typeof id === 'string');\r\n const dependsOnIdsSource = currentDependsOnIds.length > 0 ? currentDependsOnIds : fallbackIds;\r\n const dependsOnClaimIds = dependsOnIdsSource\r\n .filter((id, index, source) => source.indexOf(id) === index)\r\n .filter(id => id !== item.claimId && idToNumber.has(id));\r\n const dependsOn = dependsOnClaimIds\r\n .map(id => idToNumber.get(id))\r\n .filter((number): number is number => typeof number === 'number')\r\n .sort((a, b) => a - b);\r\n const attrs = {\r\n ...item.node.attrs,\r\n claimId: item.claimId,\r\n number: item.number,\r\n dependsOn,\r\n dependsOnClaimIds,\r\n };\r\n return { claimId: item.claimId, number: item.number, dependsOnClaimIds, pos: item.pos, attrs };\r\n });\r\n\r\n const issues = validateClaimGraph(normalizedClaims);\r\n\r\n const updated = editor.commands.command(({ tr, dispatch }) => {\r\n let changed = false;\r\n normalizedClaims.forEach((claim) => {\r\n const currentNode = editor.state.doc.nodeAt(claim.pos);\r\n if (!currentNode || currentNode.type.name !== 'claim') {\r\n return;\r\n }\r\n const nextAttrs: Record<string, unknown> = { ...claim.attrs };\r\n const attrChanged =\r\n currentNode.attrs.number !== nextAttrs['number'] ||\r\n currentNode.attrs.claimId !== nextAttrs['claimId'] ||\r\n !sameArray(normalizeNumberArray(currentNode.attrs.dependsOn), normalizeNumberArray(nextAttrs['dependsOn'])) ||\r\n !sameArray(\r\n normalizeStringArray(currentNode.attrs.dependsOnClaimIds),\r\n normalizeStringArray(nextAttrs['dependsOnClaimIds'])\r\n );\r\n if (attrChanged) {\r\n tr.setNodeMarkup(claim.pos, undefined, nextAttrs);\r\n changed = true;\r\n }\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n\r\n const signature = issues.map(issue => `${issue.claimId}:${issue.code}`).join('|');\r\n if (signature !== pluginState.lastClaimGraphSignature) {\r\n pluginState.lastClaimGraphSignature = signature;\r\n if (pluginState.claimGraphHandler) {\r\n pluginState.claimGraphHandler({ issues });\r\n }\r\n if (issues.length > 0) {\r\n console.warn(`Claim graph validation found ${issues.length} issue(s).`);\r\n }\r\n }\r\n return updated;\r\n};\r\n\r\nconst getClaimIndex = (editor: Editor) => {\r\n const claimIndex = new Map<string, { number: number; claimId: string; pos: number }>();\r\n getClaimNodes(editor).forEach((match) => {\r\n const claimId = typeof match.node.attrs.claimId === 'string' ? match.node.attrs.claimId : '';\r\n const numberValue = Number(match.node.attrs.number);\r\n if (!claimId || Number.isNaN(numberValue)) {\r\n return;\r\n }\r\n claimIndex.set(claimId, {\r\n number: numberValue,\r\n claimId,\r\n pos: match.pos,\r\n });\r\n });\r\n return claimIndex;\r\n};\r\n\r\nconst getFigureIndex = (editor: Editor) => {\r\n const figureIndex = new Map<string, { id: string; pos: number }>();\r\n getFigureNodes(editor).forEach((match) => {\r\n const id = normalizeFigureId(match.node.attrs.id);\r\n if (!id) {\r\n return;\r\n }\r\n figureIndex.set(id, {\r\n id,\r\n pos: match.pos,\r\n });\r\n });\r\n return figureIndex;\r\n};\r\n\r\nconst syncReferenceState = (editor: Editor) => {\r\n const claimIndex = getClaimIndex(editor);\r\n const figureIndex = getFigureIndex(editor);\r\n const invalidRefs: InvalidReferenceContext[] = [];\r\n const globalLanguage = getGlobalReferenceLanguage();\r\n const updated = editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference') {\r\n return true;\r\n }\r\n const targetType: ReferenceTargetType = node.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n const targetClaimId =\r\n typeof node.attrs.targetClaimId === 'string' && node.attrs.targetClaimId\r\n ? node.attrs.targetClaimId\r\n : null;\r\n const targetFigureId =\r\n typeof node.attrs.targetFigureId === 'string' && node.attrs.targetFigureId\r\n ? normalizeFigureId(node.attrs.targetFigureId)\r\n : null;\r\n const matchedClaim = targetType === 'claim' && targetClaimId ? claimIndex.get(targetClaimId) : undefined;\r\n const matchedFigure = targetType === 'figure' && targetFigureId ? figureIndex.get(targetFigureId) : undefined;\r\n const resolvedNumber = matchedClaim ? matchedClaim.number : null;\r\n const resolvedFigureId = matchedFigure ? matchedFigure.id : null;\r\n const invalid = targetType === 'figure' ? !matchedFigure : !matchedClaim;\r\n const displayText = buildReferenceText(globalLanguage, targetType, resolvedNumber, resolvedFigureId, invalid);\r\n const legacyTarget = targetType === 'figure'\r\n ? (resolvedFigureId || node.attrs.target || targetFigureId || null)\r\n : (matchedClaim ? String(matchedClaim.number) : node.attrs.target || targetClaimId || null);\r\n const nextAttrs = {\r\n ...node.attrs,\r\n targetType,\r\n targetClaimId,\r\n targetFigureId,\r\n resolvedNumber,\r\n resolvedFigureId,\r\n invalid,\r\n lang: globalLanguage,\r\n displayText,\r\n target: legacyTarget,\r\n };\r\n const hasChanged = Object.keys(nextAttrs).some(\r\n key => nextAttrs[key as keyof typeof nextAttrs] !== node.attrs[key]\r\n );\r\n if (hasChanged) {\r\n tr.setNodeMarkup(pos, undefined, nextAttrs);\r\n changed = true;\r\n }\r\n if (invalid) {\r\n invalidRefs.push({ targetType, targetClaimId, targetFigureId, position: pos });\r\n }\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n if (!updated) {\r\n return false;\r\n }\r\n const signature = invalidRefs\r\n .map(item => `${item.position}:${item.targetType}:${item.targetClaimId || item.targetFigureId || 'null'}`)\r\n .join('|');\r\n if (signature !== pluginState.lastInvalidReferenceSignature) {\r\n pluginState.lastInvalidReferenceSignature = signature;\r\n invalidRefs.forEach((item) => {\r\n if (pluginState.invalidReferenceHandler) {\r\n pluginState.invalidReferenceHandler(item);\r\n }\r\n });\r\n }\r\n return true;\r\n};\r\n\r\nconst syncReferenceHighlightState = (editor: Editor) => {\r\n const activeClaim = findAncestorNode(editor, 'claim');\r\n const activeClaimId =\r\n activeClaim && typeof activeClaim.node.attrs.claimId === 'string' ? activeClaim.node.attrs.claimId : null;\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference') {\r\n return true;\r\n }\r\n const nextHighlight =\r\n node.attrs.targetType !== 'figure' &&\r\n !!activeClaimId &&\r\n node.attrs.targetClaimId === activeClaimId &&\r\n !node.attrs.invalid;\r\n if (node.attrs.highlight !== nextHighlight) {\r\n tr.setNodeMarkup(pos, undefined, { ...node.attrs, highlight: nextHighlight });\r\n changed = true;\r\n }\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nconst warnClaimContentLength = (editor: Editor) => {\r\n const overLimit = getClaimNodes(editor)\r\n .map(match => ({ pos: match.pos, length: match.node.textContent.length }))\r\n .filter(item => item.length > CLAIM_CONTENT_LIMIT);\r\n const signature = overLimit.map(item => `${item.pos}:${item.length}`).join('|');\r\n if (signature === pluginState.lastClaimWarningSignature) {\r\n return;\r\n }\r\n pluginState.lastClaimWarningSignature = signature;\r\n if (overLimit.length === 0) {\r\n return;\r\n }\r\n console.warn(`Claim content is too long for ${overLimit.length} block(s). Suggested max: ${CLAIM_CONTENT_LIMIT}.`);\r\n};\r\n\r\nconst resolveClaimPos = (editor: Editor, position?: number) => {\r\n if (typeof position === 'number') {\r\n return position;\r\n }\r\n const currentClaim = findAncestorNode(editor, 'claim');\r\n if (currentClaim) {\r\n return currentClaim.pos;\r\n }\r\n const firstClaim = getClaimNodes(editor)[0];\r\n return firstClaim ? firstClaim.pos : null;\r\n};\r\n\r\nconst updateClaimText = (editor: Editor, position: number, text: string) => {\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const claimNode = state.doc.nodeAt(position);\r\n if (!claimNode || claimNode.type.name !== 'claim') {\r\n return false;\r\n }\r\n const contentFrom = position + 1;\r\n const contentTo = position + claimNode.nodeSize - 1;\r\n if (text.trim().length === 0) {\r\n tr.delete(contentFrom, contentTo);\r\n } else {\r\n tr.replaceWith(contentFrom, contentTo, state.schema.text(text));\r\n }\r\n if (dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\n\r\nexport const PatentPlugin: EditorPlugin = {\r\n name: 'patent',\r\n version: '1.0.0',\r\n extensions: [ClaimNode, FigureNode, ReferenceNode, PatentTitleNode, PatentSectionNode],\r\n toolbarItems: [\r\n {\r\n id: 'patent-claim-insert',\r\n label: 'Claim',\r\n command: 'insertClaim',\r\n group: 'patent',\r\n tooltip: 'Insert claim block',\r\n icon: 'Box',\r\n shortcut: 'Ctrl+Shift+C',\r\n },\r\n {\r\n id: 'patent-figure-insert',\r\n label: 'Figure',\r\n command: 'insertFigure',\r\n group: 'patent',\r\n tooltip: 'Insert figure block',\r\n icon: 'Image',\r\n shortcut: 'Ctrl+Shift+F',\r\n },\r\n ],\r\n commands: {\r\n insertClaim: {\r\n description: 'Insert patent claim block',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+C',\r\n isActive: ({ editor }) => editor.isActive('claim'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertClaimPayload) : {};\r\n const placement = data.placement || 'current';\r\n const text = typeof data.text === 'string' ? data.text : '';\r\n const claimCount = getClaimNodes(editor).length;\r\n const claimAttrs = {\r\n number: data.number || claimCount + 1,\r\n claimId: createClaimId(),\r\n dependsOn: [],\r\n dependsOnClaimIds: [],\r\n };\r\n const claimBody = text ? [{ type: 'text', text }] : [];\r\n let inserted: boolean;\r\n if (placement === 'end') {\r\n const lastClaim = getClaimNodes(editor).at(-1);\r\n const position = lastClaim ? lastClaim.pos + lastClaim.node.nodeSize : editor.state.doc.content.size;\r\n inserted = insertNode(editor, { type: 'claim', position, attrs: claimAttrs, content: claimBody });\r\n } else {\r\n inserted = insertNode(editor, { type: 'claim', attrs: claimAttrs, content: claimBody });\r\n }\r\n if (!inserted) {\r\n return false;\r\n }\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n updateClaim: {\r\n description: 'Update claim attrs and content',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as UpdateClaimPayload) : {};\r\n const targetPos = resolveClaimPos(editor, data.position);\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const attrsPatch: Record<string, unknown> = {};\r\n if (typeof data.number === 'number') {\r\n attrsPatch.number = data.number;\r\n }\r\n const attrsUpdated = Object.keys(attrsPatch).length === 0\r\n ? true\r\n : updateNodeAttrs(editor, { type: 'claim', position: targetPos, attrs: attrsPatch });\r\n if (!attrsUpdated) {\r\n return false;\r\n }\r\n const textUpdated = typeof data.text === 'string' ? updateClaimText(editor, targetPos, data.text) : true;\r\n if (!textUpdated) {\r\n return false;\r\n }\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n setClaimDependency: {\r\n description: 'Set claim dependency and regenerate prefix',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as SetClaimDependencyPayload) : {};\r\n const targetPos = resolveClaimPos(editor, data.position);\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const targetNode = editor.state.doc.nodeAt(targetPos);\r\n if (!targetNode || targetNode.type.name !== 'claim') {\r\n return false;\r\n }\r\n const currentNumber = Number(targetNode.attrs.number);\r\n const targetClaimId = typeof targetNode.attrs.claimId === 'string' ? targetNode.attrs.claimId : '';\r\n const numberToId = new Map<number, string>();\r\n getClaimNodes(editor).forEach((match) => {\r\n const numberValue = Number(match.node.attrs.number);\r\n const claimId = typeof match.node.attrs.claimId === 'string' ? match.node.attrs.claimId : '';\r\n if (Number.isFinite(numberValue) && numberValue > 0 && claimId) {\r\n numberToId.set(numberValue, claimId);\r\n }\r\n });\r\n const dependsOn = normalizeNumberArray(data.dependsOn).filter(\r\n item => Number.isFinite(currentNumber) && item > 0 && item < currentNumber\r\n );\r\n const dependsOnClaimIds = dependsOn\r\n .map(number => numberToId.get(number))\r\n .filter((id): id is string => typeof id === 'string' && id.length > 0 && id !== targetClaimId);\r\n const updated = updateNodeAttrs(editor, {\r\n type: 'claim',\r\n position: targetPos,\r\n attrs: { dependsOn, dependsOnClaimIds },\r\n });\r\n if (!updated) {\r\n return false;\r\n }\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n setReferenceLanguage: {\r\n description: 'Set reference language for current or all references',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as SetReferenceLanguagePayload) : null;\r\n if (!data?.lang) {\r\n return false;\r\n }\r\n const lang: ReferenceLanguage = data.lang === 'en' ? 'en' : 'zh';\r\n useEditorStore.getState().setEditorLanguage(lang);\r\n const scope = data.scope || 'all';\r\n const currentReference = scope === 'current' ? findAncestorNode(editor, 'reference') : null;\r\n const updated = editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference') {\r\n return true;\r\n }\r\n if (currentReference && pos !== currentReference.pos) {\r\n return true;\r\n }\r\n if (node.attrs.lang !== lang) {\r\n tr.setNodeMarkup(pos, undefined, {\r\n ...node.attrs,\r\n lang,\r\n });\r\n changed = true;\r\n }\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n if (!updated) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n validateClaimGraph: {\r\n description: 'Validate claim dependency graph',\r\n category: 'patent',\r\n execute: ({ editor }) => {\r\n const synced = syncClaimState(editor);\r\n if (!synced) {\r\n return false;\r\n }\r\n return pluginState.lastClaimGraphSignature.length === 0;\r\n },\r\n },\r\n deleteClaim: {\r\n description: 'Delete claim node and reorder numbers',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as DeleteClaimPayload) : {};\r\n const targetPos = resolveClaimPos(editor, data.position);\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const deleted = removeNode(editor, { type: 'claim', position: targetPos });\r\n if (!deleted) {\r\n return false;\r\n }\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n reorderClaims: {\r\n description: 'Reorder all claim numbers by document order',\r\n category: 'patent',\r\n execute: ({ editor }) => {\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n normalizeClaims: {\r\n description: 'Normalize claim ids, numbering, dependencies and references',\r\n category: 'patent',\r\n execute: ({ editor }) => {\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n insertFigure: {\r\n description: 'Insert patent figure block',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+F',\r\n isActive: ({ editor }) => editor.isActive('figure'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertFigurePayload) : {};\r\n const id = normalizeFigureId(data.id) || suggestNextFigureId(editor);\r\n const contentType: FigureContentType =\r\n data.contentType && ['image', 'mermaid', 'drawio'].includes(data.contentType)\r\n ? data.contentType : 'image';\r\n return editor.chain().focus().insertContent({\r\n type: 'figure',\r\n attrs: { id, contentType, imageSrc: '', mermaidCode: '', drawioXml: '' },\r\n content: data.captionText ? [{ type: 'text', text: data.captionText }] : [],\r\n }).run();\r\n },\r\n },\r\n updateFigure: {\r\n description: 'Update figure attributes',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as UpdateFigurePayload) : {};\r\n const figureNode = findAncestorNode(editor, 'figure');\r\n const targetPos = typeof data.position === 'number' ? data.position : figureNode?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const target = editor.state.doc.nodeAt(targetPos);\r\n if (!target || target.type.name !== 'figure') {\r\n return false;\r\n }\r\n const nextId = typeof data.id === 'string' ? normalizeFigureId(data.id) : normalizeFigureId(target.attrs.id);\r\n const candidateId = nextId || suggestNextFigureId(editor);\r\n const duplicated = getFigureNodes(editor).some((item) => {\r\n if (item.pos === targetPos) {\r\n return false;\r\n }\r\n return normalizeFigureId(item.node.attrs.id) === candidateId;\r\n });\r\n if (duplicated) {\r\n return false;\r\n }\r\n const attrsPatch: Record<string, unknown> = { id: candidateId };\r\n if (typeof data.contentType === 'string' && ['image', 'mermaid', 'drawio'].includes(data.contentType)) {\r\n attrsPatch.contentType = data.contentType;\r\n }\r\n if (typeof data.imageSrc === 'string') {\r\n attrsPatch.imageSrc = data.imageSrc;\r\n }\r\n if (typeof data.mermaidCode === 'string') {\r\n attrsPatch.mermaidCode = data.mermaidCode;\r\n }\r\n if (typeof data.drawioXml === 'string') {\r\n attrsPatch.drawioXml = data.drawioXml;\r\n }\r\n return updateNodeAttrs(editor, {\r\n type: 'figure',\r\n position: targetPos,\r\n attrs: attrsPatch,\r\n });\r\n },\r\n },\r\n validateFigureIds: {\r\n description: 'Validate figure id uniqueness',\r\n category: 'patent',\r\n execute: ({ editor }) => {\r\n const used = new Set<string>();\r\n let duplicated = false;\r\n getFigureNodes(editor).forEach((item) => {\r\n const id = normalizeFigureId(item.node.attrs.id);\r\n if (!id) {\r\n return;\r\n }\r\n if (used.has(id)) {\r\n duplicated = true;\r\n return;\r\n }\r\n used.add(id);\r\n });\r\n return !duplicated;\r\n },\r\n },\r\n insertReference: {\r\n description: 'Insert patent reference inline node',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+R',\r\n isActive: ({ editor }) => editor.isActive('reference'),\r\n canExecute: (_, payload) => {\r\n if (!payload || typeof payload !== 'object') {\r\n return false;\r\n }\r\n const data = payload as InsertReferencePayload;\r\n return typeof data.targetClaimId === 'string' && data.targetClaimId.trim().length > 0;\r\n },\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertReferencePayload) : {};\r\n const claimIndex = getClaimIndex(editor);\r\n const normalizedClaimId = typeof data.targetClaimId === 'string' ? data.targetClaimId.trim() : '';\r\n if (!normalizedClaimId) {\r\n return false;\r\n }\r\n const matchedClaim = claimIndex.get(normalizedClaimId);\r\n if (!matchedClaim) {\r\n return false;\r\n }\r\n const resolvedNumber = matchedClaim.number;\r\n const language: ReferenceLanguage = data.lang || getGlobalReferenceLanguage();\r\n const displayText = data.displayText || buildReferenceText(language, 'claim', resolvedNumber, null, false);\r\n const inserted = editor.chain().focus().insertContent({\r\n type: 'reference',\r\n attrs: {\r\n targetType: 'claim',\r\n targetClaimId: normalizedClaimId,\r\n targetFigureId: null,\r\n resolvedNumber,\r\n resolvedFigureId: null,\r\n lang: language,\r\n invalid: false,\r\n displayText,\r\n target: data.target || String(resolvedNumber),\r\n highlight: false,\r\n },\r\n }).run();\r\n if (!inserted) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n insertFigureReference: {\r\n description: 'Insert patent figure reference inline node',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+G',\r\n isActive: ({ editor }) => editor.isActive('reference'),\r\n canExecute: (_, payload) => {\r\n if (!payload || typeof payload !== 'object') {\r\n return false;\r\n }\r\n const data = payload as InsertReferencePayload;\r\n return typeof data.targetFigureId === 'string' && data.targetFigureId.trim().length > 0;\r\n },\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertReferencePayload) : {};\r\n const figureIndex = getFigureIndex(editor);\r\n const figureId = typeof data.targetFigureId === 'string' ? normalizeFigureId(data.targetFigureId) : '';\r\n if (!figureId) {\r\n return false;\r\n }\r\n const matchedFigure = figureIndex.get(figureId);\r\n if (!matchedFigure) {\r\n return false;\r\n }\r\n const language: ReferenceLanguage = data.lang || getGlobalReferenceLanguage();\r\n const displayText = data.displayText || buildReferenceText(language, 'figure', null, matchedFigure.id, false);\r\n const inserted = editor.chain().focus().insertContent({\r\n type: 'reference',\r\n attrs: {\r\n targetType: 'figure',\r\n targetClaimId: null,\r\n targetFigureId: matchedFigure.id,\r\n resolvedNumber: null,\r\n resolvedFigureId: matchedFigure.id,\r\n lang: language,\r\n invalid: false,\r\n displayText,\r\n target: data.target || matchedFigure.id,\r\n highlight: false,\r\n },\r\n }).run();\r\n if (!inserted) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n repairReferences: {\r\n description: 'Repair invalid references with a selected claim target',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as RepairReferencesPayload) : null;\r\n if (!data?.targetClaimId) {\r\n return false;\r\n }\r\n const repaired = editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference' || !node.attrs.invalid) {\r\n return true;\r\n }\r\n tr.setNodeMarkup(pos, undefined, {\r\n ...node.attrs,\r\n targetType: 'claim',\r\n targetClaimId: data.targetClaimId,\r\n targetFigureId: null,\r\n invalid: false,\r\n });\r\n changed = true;\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return changed;\r\n });\r\n if (!repaired) {\r\n return false;\r\n }\r\n return syncReferenceState(editor);\r\n },\r\n },\r\n setInvalidReferenceHandler: {\r\n description: 'Set callback for invalid claim references',\r\n category: 'patent',\r\n execute: (_, payload) => {\r\n if (typeof payload !== 'function') {\r\n return false;\r\n }\r\n pluginState.invalidReferenceHandler = payload as (context: InvalidReferenceContext) => void;\r\n return true;\r\n },\r\n },\r\n setClaimGraphIssueHandler: {\r\n description: 'Set callback for claim graph validation result',\r\n category: 'patent',\r\n execute: (_, payload) => {\r\n if (typeof payload !== 'function') {\r\n return false;\r\n }\r\n pluginState.claimGraphHandler = payload as (context: ClaimGraphValidationContext) => void;\r\n return true;\r\n },\r\n },\r\n insertPatentDocument: {\r\n description: 'Insert patent document skeleton with all sections',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertPatentDocumentPayload) : {};\r\n const patentType: PatentType = data.patentType === 'utility_model' ? 'utility_model' : data.patentType === 'design' ? 'design' : 'invention';\r\n const doc = buildPatentDocument(patentType);\r\n return editor.commands.setContent(doc);\r\n },\r\n },\r\n toggleSectionCollapse: {\r\n description: 'Toggle patent section collapse state',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as ToggleSectionCollapsePayload) : {};\r\n const sectionNode = findAncestorNode(editor, 'patent_section');\r\n const targetPos = typeof data.position === 'number' ? data.position : sectionNode?.pos;\r\n if (typeof targetPos !== 'number') return false;\r\n const target = editor.state.doc.nodeAt(targetPos);\r\n if (!target || target.type.name !== 'patent_section') return false;\r\n return updateNodeAttrs(editor, {\r\n type: 'patent_section',\r\n position: targetPos,\r\n attrs: { collapsed: !target.attrs.collapsed },\r\n });\r\n },\r\n },\r\n },\r\n onStateChange: (editor) => {\r\n const claimSynced = syncClaimState(editor);\r\n if (!claimSynced) {\r\n return;\r\n }\r\n void syncReferenceState(editor);\r\n void syncReferenceHighlightState(editor);\r\n warnClaimContentLength(editor);\r\n syncFigureOrder(editor);\r\n },\r\n onSelectionChange: (editor) => {\r\n void syncReferenceHighlightState(editor);\r\n },\r\n};\r\n","import { MermaidPlugin } from './mermaid';\r\nimport { DrawioPlugin } from './drawio';\r\nimport { MathPlugin } from './math';\r\nimport { PatentPlugin } from './patent';\r\n\r\nexport const plugins = [MermaidPlugin, DrawioPlugin, MathPlugin, PatentPlugin];\r\n","import { Editor, EditorOptions } from '@tiptap/react';\r\nimport { schemaExtensions } from '../schema/schema';\r\nimport { pluginManager } from './PluginManager';\r\nimport { plugins as defaultPlugins } from '../plugins';\r\nimport { CommandExecutionContext, CommandExecutionOptions } from '../../types/plugin';\r\nimport {\r\n applyTransactionBatch,\r\n findAncestorNode,\r\n findCurrentBlock,\r\n findNodeByType,\r\n findNodesByPredicate,\r\n insertNode,\r\n removeNode,\r\n updateNodeAttrs,\r\n wrapSelection,\r\n} from '../commands';\r\nimport { useEditorStore } from '../../store/editorStore';\r\n\r\ndefaultPlugins.forEach(plugin => pluginManager.register(plugin));\r\n\r\nexport const createEditorConfig = (options: Partial<EditorOptions> = {}): Partial<EditorOptions> => {\r\n const extensions = [\r\n ...schemaExtensions,\r\n ...pluginManager.getExtensions(),\r\n ...(options.extensions || []),\r\n ];\r\n\r\n return {\r\n ...options,\r\n extensions,\r\n };\r\n};\r\n\r\nconst createCommandContext = (editor: Editor): CommandExecutionContext => {\r\n const { from, to } = editor.state.selection;\r\n return {\r\n editor,\r\n selection: { from, to },\r\n store: useEditorStore.getState(),\r\n };\r\n};\r\n\r\nexport const createCommandExecutor = (editor: Editor) => {\r\n return {\r\n execCommand: (name: string, payload?: unknown, options?: CommandExecutionOptions) => {\r\n return pluginManager.executeCommand(name, createCommandContext(editor), payload, options);\r\n },\r\n canExecCommand: (name: string, payload?: unknown) => {\r\n return pluginManager.canExecuteCommand(name, createCommandContext(editor), payload);\r\n },\r\n isCommandActive: (name: string) => {\r\n return pluginManager.isCommandActive(name, createCommandContext(editor));\r\n },\r\n listCommands: () => {\r\n return pluginManager.getCommandNames();\r\n },\r\n insertNode: (input: Parameters<typeof insertNode>[1]) => {\r\n return insertNode(editor, input);\r\n },\r\n updateNodeAttrs: (input: Parameters<typeof updateNodeAttrs>[1]) => {\r\n return updateNodeAttrs(editor, input);\r\n },\r\n removeNode: (input: Parameters<typeof removeNode>[1]) => {\r\n return removeNode(editor, input);\r\n },\r\n wrapSelection: (input: Parameters<typeof wrapSelection>[1]) => {\r\n return wrapSelection(editor, input);\r\n },\r\n applyTransactionBatch: (operations: Parameters<typeof applyTransactionBatch>[1]) => {\r\n return applyTransactionBatch(editor, operations);\r\n },\r\n findNodeByType: (typeName: Parameters<typeof findNodeByType>[1], scope?: Parameters<typeof findNodeByType>[2]) => {\r\n return findNodeByType(editor, typeName, scope);\r\n },\r\n findAncestorNode: (predicate: Parameters<typeof findAncestorNode>[1]) => {\r\n return findAncestorNode(editor, predicate);\r\n },\r\n findCurrentBlock: () => {\r\n return findCurrentBlock(editor);\r\n },\r\n findNodesByPredicate: (\r\n predicate: Parameters<typeof findNodesByPredicate>[1],\r\n scope?: Parameters<typeof findNodesByPredicate>[2]\r\n ) => {\r\n return findNodesByPredicate(editor, predicate, scope);\r\n },\r\n };\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport {\r\n Document,\r\n Packer,\r\n Paragraph,\r\n TextRun,\r\n AlignmentType,\r\n convertMillimetersToTwip,\r\n ISectionOptions,\r\n} from 'docx';\r\nimport { saveAs } from 'file-saver';\r\nimport { getEditorText } from '../../lib/editorI18n';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\n\r\n/** Sections that are top-level \"books\" */\r\nconst BOOK_SECTIONS = new Set([\r\n 'abstract', 'abstract_drawing', 'claims', 'drawing_figures',\r\n]);\r\n\r\n/** Sub-sections under 说明书 */\r\nconst DESCRIPTION_SUBS = new Set([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\ninterface DocNode {\r\n type: 'patent_title' | 'patent_section';\r\n sectionType: string;\r\n title: string;\r\n paragraphs: string[];\r\n}\r\n\r\nfunction extractDocNodes(editor: Editor, language: EditorLanguage): DocNode[] {\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const nodes: DocNode[] = [];\r\n\r\n editor.state.doc.descendants((node) => {\r\n if (node.type.name === 'patent_title') {\r\n const text = node.textContent.trim();\r\n nodes.push({\r\n type: 'patent_title',\r\n sectionType: 'patent_title',\r\n title: '',\r\n paragraphs: text ? [text] : [],\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const titleKey = `sectionTitle_${sectionType}`;\r\n const title = (typeof i18n[titleKey] === 'string' ? i18n[titleKey] : sectionType) as string;\r\n const paragraphs: string[] = [];\r\n\r\n node.forEach((child) => {\r\n const text = child.textContent.trim();\r\n if (text) paragraphs.push(text);\r\n });\r\n\r\n nodes.push({ type: 'patent_section', sectionType, title, paragraphs });\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n return nodes;\r\n}\r\n\r\n/** Book-level heading: centered, 三号黑体 (16pt = size 32 half-points) */\r\nfunction bookHeading(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 32, font: '黑体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 400, after: 200 },\r\n });\r\n}\r\n\r\n/** Sub-section heading: centered, 四号黑体 (14pt = size 28 half-points) */\r\nfunction subSectionHeading(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 28, font: '黑体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 240, after: 120 },\r\n });\r\n}\r\n\r\n/** Patent title: centered, 二号宋体 bold (18pt = size 36 half-points) */\r\nfunction patentTitleParagraph(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 36, font: '宋体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 200, after: 200 },\r\n });\r\n}\r\n\r\n/** Body paragraph: 宋体 小四 (12pt = size 24), first-line indent ~2字符 */\r\nfunction bodyParagraph(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, size: 24, font: '宋体' })],\r\n spacing: { line: 360 },\r\n indent: { firstLine: convertMillimetersToTwip(7) },\r\n });\r\n}\r\n\r\nfunction buildDocxParagraphs(nodes: DocNode[], language: EditorLanguage): Paragraph[] {\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const paragraphs: Paragraph[] = [];\r\n let descriptionBookInserted = false;\r\n\r\n for (const node of nodes) {\r\n // Book-level sections: add book heading + content\r\n if (BOOK_SECTIONS.has(node.sectionType)) {\r\n paragraphs.push(bookHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Patent title: insert \"说明书\" book heading first, then title\r\n if (node.type === 'patent_title') {\r\n if (!descriptionBookInserted) {\r\n const bookLabel = (typeof i18n['bookTitle_description'] === 'string'\r\n ? i18n['bookTitle_description'] : '说明书') as string;\r\n paragraphs.push(bookHeading(bookLabel));\r\n descriptionBookInserted = true;\r\n }\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(patentTitleParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Description sub-sections: sub-heading + content\r\n if (DESCRIPTION_SUBS.has(node.sectionType)) {\r\n paragraphs.push(subSectionHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Fallback: treat as section heading + content\r\n paragraphs.push(subSectionHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n }\r\n\r\n return paragraphs;\r\n}\r\n\r\nexport async function exportToWord(editor: Editor, language: EditorLanguage): Promise<void> {\r\n const nodes = extractDocNodes(editor, language);\r\n const paragraphs = buildDocxParagraphs(nodes, language);\r\n\r\n const patentTitle = nodes.find(n => n.type === 'patent_title');\r\n const fileName = patentTitle?.paragraphs[0]\r\n ? `${patentTitle.paragraphs[0]}.docx`\r\n : 'patent-document.docx';\r\n\r\n const sectionOptions: ISectionOptions = {\r\n properties: {\r\n page: {\r\n margin: {\r\n top: convertMillimetersToTwip(25),\r\n bottom: convertMillimetersToTwip(25),\r\n left: convertMillimetersToTwip(25),\r\n right: convertMillimetersToTwip(20),\r\n },\r\n },\r\n },\r\n children: paragraphs,\r\n };\r\n\r\n const doc = new Document({\r\n sections: [sectionOptions],\r\n });\r\n\r\n const blob = await Packer.toBlob(doc);\r\n saveAs(blob, fileName);\r\n}\r\n\r\nexport async function exportToPdf(editor: Editor): Promise<void> {\r\n window.print();\r\n}\r\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { Editor } from '@tiptap/react';\r\nimport {\r\n AlignCenter,\r\n AlignJustify,\r\n AlignLeft,\r\n AlignRight,\r\n Bold,\r\n Box,\r\n CheckSquare,\r\n ChevronDown,\r\n Code,\r\n Download,\r\n FileText,\r\n FileCode2,\r\n FunctionSquare,\r\n GitGraph,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n Image,\r\n Italic,\r\n Link2,\r\n List,\r\n ListOrdered,\r\n LucideIcon,\r\n Minus,\r\n Pilcrow,\r\n Quote,\r\n Redo2,\r\n Sigma,\r\n Square,\r\n Strikethrough,\r\n Subscript,\r\n Superscript,\r\n Table as TableIcon,\r\n Underline,\r\n Undo2,\r\n Workflow,\r\n} from 'lucide-react';\r\nimport clsx from 'clsx';\r\nimport { createCommandExecutor } from '../editor/core/EditorCore';\r\nimport { pluginManager } from '../editor/core/PluginManager';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport { exportToWord, exportToPdf } from '../editor/export';\r\n\r\ninterface ToolbarProps {\r\n editor: Editor | null;\r\n groupOrder?: string[];\r\n collapsibleGroups?: boolean;\r\n defaultCollapsedGroups?: string[];\r\n}\r\n\r\ninterface ToolbarButton {\r\n id: string;\r\n label: string;\r\n group: string;\r\n icon: LucideIcon;\r\n tooltip: string;\r\n isActive: boolean;\r\n disabled: boolean;\r\n run: () => void;\r\n}\r\n\r\nconst defaultGroupOrder = ['history', 'text', 'structure', 'format', 'technical', 'patent'];\r\n\r\nconst formatGroupLabel = (group: string) => {\r\n return group\r\n .split('_')\r\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\r\n .join(' ');\r\n};\r\n\r\nconst DropdownButton: React.FC<{\r\n btn: ToolbarButton;\r\n items: { label: string; onClick: () => void }[];\r\n}> = ({ btn, items }) => {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const [pos, setPos] = useState({ top: 0, left: 0 });\r\n\r\n const updatePosition = useCallback(() => {\r\n if (!triggerRef.current) return;\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n setPos({ top: rect.bottom + 4, left: rect.left });\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n updatePosition();\r\n const handleClickOutside = (e: MouseEvent) => {\r\n const target = e.target as Node;\r\n if (\r\n triggerRef.current?.contains(target) ||\r\n menuRef.current?.contains(target)\r\n ) return;\r\n setOpen(false);\r\n };\r\n const handleScroll = () => updatePosition();\r\n document.addEventListener('mousedown', handleClickOutside);\r\n window.addEventListener('scroll', handleScroll, true);\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n window.removeEventListener('scroll', handleScroll, true);\r\n };\r\n }, [open, updatePosition]);\r\n\r\n return (\r\n <div className=\"flex items-center\">\r\n <button\r\n onClick={btn.run}\r\n disabled={btn.disabled}\r\n className={clsx(\r\n 'p-2 rounded-l transition-colors',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200',\r\n btn.isActive ? 'bg-gray-300 text-blue-600' : 'text-gray-700'\r\n )}\r\n title={btn.tooltip}\r\n >\r\n <btn.icon size={18} />\r\n </button>\r\n <button\r\n ref={triggerRef}\r\n onClick={() => setOpen((v) => !v)}\r\n className={clsx(\r\n 'px-1 py-2 rounded-r transition-colors border-l border-gray-200',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200 text-gray-500'\r\n )}\r\n disabled={btn.disabled}\r\n >\r\n <ChevronDown size={12} />\r\n </button>\r\n {open && createPortal(\r\n <div\r\n ref={menuRef}\r\n className=\"bg-white border border-gray-200 rounded shadow-lg min-w-[160px] py-1\"\r\n style={{ position: 'fixed', top: pos.top, left: pos.left, zIndex: 9999 }}\r\n >\r\n {items.map((item, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => {\r\n item.onClick();\r\n setOpen(false);\r\n }}\r\n className=\"block w-full text-left px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100\"\r\n >\r\n {item.label}\r\n </button>\r\n ))}\r\n </div>,\r\n document.body\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport const Toolbar: React.FC<ToolbarProps> = ({\r\n editor,\r\n groupOrder = defaultGroupOrder,\r\n collapsibleGroups = true,\r\n defaultCollapsedGroups = [],\r\n}) => {\r\n const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(() => new Set(defaultCollapsedGroups));\r\n const { editorLanguage, setEditorLanguage } = useEditorStore();\r\n const i18n = getEditorText(editorLanguage);\r\n\r\n if (!editor) {\r\n return null;\r\n }\r\n\r\n const commandExecutor = createCommandExecutor(editor);\r\n const zh = editorLanguage === 'zh';\r\n\r\n const coreButtons: ToolbarButton[] = [\r\n {\r\n id: 'core-undo',\r\n label: 'Undo',\r\n group: 'history',\r\n icon: Undo2,\r\n tooltip: 'Undo (Ctrl+Z)',\r\n isActive: false,\r\n disabled: !editor.can().chain().focus().undo().run(),\r\n run: () => {\r\n editor.chain().focus().undo().run();\r\n },\r\n },\r\n {\r\n id: 'core-redo',\r\n label: 'Redo',\r\n group: 'history',\r\n icon: Redo2,\r\n tooltip: 'Redo (Ctrl+Y)',\r\n isActive: false,\r\n disabled: !editor.can().chain().focus().redo().run(),\r\n run: () => {\r\n editor.chain().focus().redo().run();\r\n },\r\n },\r\n {\r\n id: 'core-bold',\r\n label: 'Bold',\r\n group: 'text',\r\n icon: Bold,\r\n tooltip: 'Bold',\r\n isActive: editor.isActive('bold'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBold().run();\r\n },\r\n },\r\n {\r\n id: 'core-italic',\r\n label: 'Italic',\r\n group: 'text',\r\n icon: Italic,\r\n tooltip: 'Italic',\r\n isActive: editor.isActive('italic'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleItalic().run();\r\n },\r\n },\r\n {\r\n id: 'core-underline',\r\n label: 'Underline',\r\n group: 'text',\r\n icon: Underline,\r\n tooltip: 'Underline',\r\n isActive: editor.isActive('underline'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleUnderline().run();\r\n },\r\n },\r\n {\r\n id: 'core-strike',\r\n label: 'Strike',\r\n group: 'text',\r\n icon: Strikethrough,\r\n tooltip: 'Strike',\r\n isActive: editor.isActive('strike'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleStrike().run();\r\n },\r\n },\r\n {\r\n id: 'core-code',\r\n label: 'Code',\r\n group: 'text',\r\n icon: Code,\r\n tooltip: 'Code',\r\n isActive: editor.isActive('code'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleCode().run();\r\n },\r\n },\r\n {\r\n id: 'core-superscript',\r\n label: 'Superscript',\r\n group: 'text',\r\n icon: Superscript,\r\n tooltip: 'Superscript (Ctrl+.)',\r\n isActive: editor.isActive('superscript'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleSuperscript().run();\r\n },\r\n },\r\n {\r\n id: 'core-subscript',\r\n label: 'Subscript',\r\n group: 'text',\r\n icon: Subscript,\r\n tooltip: 'Subscript (Ctrl+,)',\r\n isActive: editor.isActive('subscript'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleSubscript().run();\r\n },\r\n },\r\n {\r\n id: 'core-paragraph',\r\n label: 'Paragraph',\r\n group: 'structure',\r\n icon: Pilcrow,\r\n tooltip: 'Paragraph',\r\n isActive: editor.isActive('paragraph'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().setParagraph().run();\r\n },\r\n },\r\n {\r\n id: 'core-heading1',\r\n label: 'H1',\r\n group: 'structure',\r\n icon: Heading1,\r\n tooltip: 'Heading 1',\r\n isActive: editor.isActive('heading', { level: 1 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 1 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-heading2',\r\n label: 'H2',\r\n group: 'structure',\r\n icon: Heading2,\r\n tooltip: 'Heading 2',\r\n isActive: editor.isActive('heading', { level: 2 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 2 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-heading3',\r\n label: 'H3',\r\n group: 'structure',\r\n icon: Heading3,\r\n tooltip: 'Heading 3',\r\n isActive: editor.isActive('heading', { level: 3 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 3 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-align-left',\r\n label: zh ? '左对齐' : 'Align Left',\r\n group: 'format',\r\n icon: AlignLeft,\r\n tooltip: zh ? '左对齐' : 'Align Left',\r\n isActive: editor.isActive({ textAlign: 'left' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('left').run(); },\r\n },\r\n {\r\n id: 'core-align-center',\r\n label: zh ? '居中' : 'Center',\r\n group: 'format',\r\n icon: AlignCenter,\r\n tooltip: zh ? '居中对齐' : 'Align Center',\r\n isActive: editor.isActive({ textAlign: 'center' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('center').run(); },\r\n },\r\n {\r\n id: 'core-align-right',\r\n label: zh ? '右对齐' : 'Align Right',\r\n group: 'format',\r\n icon: AlignRight,\r\n tooltip: zh ? '右对齐' : 'Align Right',\r\n isActive: editor.isActive({ textAlign: 'right' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('right').run(); },\r\n },\r\n {\r\n id: 'core-align-justify',\r\n label: zh ? '两端对齐' : 'Justify',\r\n group: 'format',\r\n icon: AlignJustify,\r\n tooltip: zh ? '两端对齐' : 'Justify',\r\n isActive: editor.isActive({ textAlign: 'justify' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('justify').run(); },\r\n },\r\n {\r\n id: 'core-bullet-list',\r\n label: 'Bullet List',\r\n group: 'structure',\r\n icon: List,\r\n tooltip: 'Bullet List',\r\n isActive: editor.isActive('bulletList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBulletList().run();\r\n },\r\n },\r\n {\r\n id: 'core-ordered-list',\r\n label: 'Ordered List',\r\n group: 'structure',\r\n icon: ListOrdered,\r\n tooltip: 'Ordered List',\r\n isActive: editor.isActive('orderedList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleOrderedList().run();\r\n },\r\n },\r\n {\r\n id: 'core-blockquote',\r\n label: 'Blockquote',\r\n group: 'structure',\r\n icon: Quote,\r\n tooltip: 'Blockquote',\r\n isActive: editor.isActive('blockquote'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBlockquote().run();\r\n },\r\n },\r\n {\r\n id: 'core-code-block',\r\n label: 'Code Block',\r\n group: 'structure',\r\n icon: FileCode2,\r\n tooltip: 'Code Block',\r\n isActive: editor.isActive('codeBlock'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleCodeBlock().run();\r\n },\r\n },\r\n {\r\n id: 'core-table',\r\n label: 'Insert Table',\r\n group: 'structure',\r\n icon: TableIcon,\r\n tooltip: 'Insert Table',\r\n isActive: false,\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\r\n },\r\n },\r\n {\r\n id: 'core-horizontal-rule',\r\n label: 'Horizontal Rule',\r\n group: 'structure',\r\n icon: Minus,\r\n tooltip: 'Horizontal Rule',\r\n isActive: false,\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().setHorizontalRule().run();\r\n },\r\n },\r\n {\r\n id: 'core-task-list',\r\n label: 'Task List',\r\n group: 'structure',\r\n icon: CheckSquare,\r\n tooltip: 'Task List',\r\n isActive: editor.isActive('taskList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleTaskList().run();\r\n },\r\n },\r\n ];\r\n\r\n const iconMap: Record<string, LucideIcon> = {\r\n GitGraph,\r\n Sigma,\r\n FunctionSquare,\r\n Workflow,\r\n Box,\r\n FileText,\r\n Link2,\r\n Image,\r\n };\r\n\r\n const pluginButtons: ToolbarButton[] = pluginManager.getToolbarItems().map((item) => {\r\n const commandMeta = pluginManager.getCommandMeta(item.command);\r\n const tooltip = item.tooltip || commandMeta?.description || item.label;\r\n const shortcut = item.shortcut || commandMeta?.shortcut;\r\n const displayTooltip = shortcut ? `${tooltip} (${shortcut})` : tooltip;\r\n return {\r\n id: item.id,\r\n label: item.label,\r\n group: item.group || 'technical',\r\n icon: item.icon ? iconMap[item.icon] || Square : Square,\r\n isActive: commandExecutor.isCommandActive(item.command),\r\n disabled: !commandExecutor.canExecCommand(item.command),\r\n tooltip: displayTooltip,\r\n run: () => {\r\n void commandExecutor.execCommand(item.command);\r\n },\r\n };\r\n });\r\n\r\n const exportButton: ToolbarButton = {\r\n id: 'core-export',\r\n label: zh ? '导出' : 'Export',\r\n group: 'patent',\r\n icon: Download,\r\n tooltip: zh ? '导出文档' : 'Export Document',\r\n isActive: false,\r\n disabled: false,\r\n run: () => void exportToWord(editor, editorLanguage),\r\n };\r\n\r\n const exportDropdownItems = [\r\n { label: zh ? '导出 Word (.docx)' : 'Export Word (.docx)', onClick: () => void exportToWord(editor, editorLanguage) },\r\n { label: zh ? '导出 PDF (打印)' : 'Export PDF (Print)', onClick: () => void exportToPdf(editor) },\r\n ];\r\n\r\n const allButtons = [...coreButtons, ...pluginButtons, exportButton];\r\n const extraGroups = allButtons\r\n .map((button) => button.group)\r\n .filter((group, index, source) => source.indexOf(group) === index && !groupOrder.includes(group));\r\n const normalizedGroupOrder = [...groupOrder, ...extraGroups];\r\n\r\n const groupedButtons = normalizedGroupOrder\r\n .map((group) => ({\r\n group,\r\n items: allButtons.filter((item) => item.group === group),\r\n }))\r\n .filter((entry) => entry.items.length > 0);\r\n\r\n const toggleGroup = (group: string) => {\r\n setCollapsedGroups((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(group)) {\r\n next.delete(group);\r\n } else {\r\n next.add(group);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const tableDropdownItems = [\r\n { label: zh ? '插入表格 3×3' : 'Insert Table 3×3', onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run() },\r\n { label: zh ? '上方插入行' : 'Add Row Before', onClick: () => editor.chain().focus().addRowBefore().run() },\r\n { label: zh ? '下方插入行' : 'Add Row After', onClick: () => editor.chain().focus().addRowAfter().run() },\r\n { label: zh ? '左侧插入列' : 'Add Column Before', onClick: () => editor.chain().focus().addColumnBefore().run() },\r\n { label: zh ? '右侧插入列' : 'Add Column After', onClick: () => editor.chain().focus().addColumnAfter().run() },\r\n { label: zh ? '删除行' : 'Delete Row', onClick: () => editor.chain().focus().deleteRow().run() },\r\n { label: zh ? '删除列' : 'Delete Column', onClick: () => editor.chain().focus().deleteColumn().run() },\r\n { label: zh ? '合并单元格' : 'Merge Cells', onClick: () => editor.chain().focus().mergeCells().run() },\r\n { label: zh ? '拆分单元格' : 'Split Cell', onClick: () => editor.chain().focus().splitCell().run() },\r\n { label: zh ? '切换表头' : 'Toggle Header Row', onClick: () => editor.chain().focus().toggleHeaderRow().run() },\r\n { label: zh ? '删除表格' : 'Delete Table', onClick: () => editor.chain().focus().deleteTable().run() },\r\n ];\r\n\r\n const figureDropdownItems = [\r\n { label: i18n.insertImageFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'image' }) },\r\n { label: i18n.insertMermaidFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'mermaid' }) },\r\n { label: i18n.insertDrawioFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'drawio' }) },\r\n ];\r\n\r\n const renderButton = (btn: ToolbarButton) => {\r\n if (btn.id === 'core-table') {\r\n return <DropdownButton key={btn.id} btn={btn} items={tableDropdownItems} />;\r\n }\r\n if (btn.id === 'core-export') {\r\n return <DropdownButton key={btn.id} btn={btn} items={exportDropdownItems} />;\r\n }\r\n if (btn.id === 'patent-figure-insert') {\r\n return <DropdownButton key={btn.id} btn={btn} items={figureDropdownItems} />;\r\n }\r\n return (\r\n <button\r\n key={btn.id}\r\n onClick={btn.run}\r\n disabled={btn.disabled}\r\n className={clsx(\r\n 'p-2 rounded transition-colors',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200',\r\n btn.isActive ? 'bg-gray-300 text-blue-600' : 'text-gray-700'\r\n )}\r\n title={btn.tooltip}\r\n >\r\n <btn.icon size={18} />\r\n </button>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"border-b border-gray-200 bg-gray-50 sticky top-0 z-10 overflow-x-auto\">\r\n <div className=\"flex flex-nowrap md:flex-wrap gap-2 p-2 min-w-max md:min-w-0\">\r\n <div className=\"flex items-center gap-1 pr-2 mr-2 border-r border-gray-200\">\r\n <span className=\"text-xs text-gray-500\">{i18n.language}</span>\r\n <select\r\n value={editorLanguage}\r\n onChange={(event) => {\r\n setEditorLanguage(event.target.value === 'en' ? 'en' : 'zh');\r\n }}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white text-gray-700\"\r\n >\r\n <option value=\"zh\">中文</option>\r\n <option value=\"en\">English</option>\r\n </select>\r\n </div>\r\n {groupedButtons.map((entry) => {\r\n const collapsed = collapsedGroups.has(entry.group);\r\n return (\r\n <div key={entry.group} className=\"flex items-center gap-1 pr-2 mr-2 border-r border-gray-200 last:border-r-0 last:mr-0 last:pr-0\">\r\n {collapsibleGroups && (\r\n <button\r\n onClick={() => {\r\n toggleGroup(entry.group);\r\n }}\r\n className=\"px-2 py-1 text-xs rounded bg-gray-200 text-gray-700 hover:bg-gray-300\"\r\n title={collapsed ? `Expand ${formatGroupLabel(entry.group)}` : `Collapse ${formatGroupLabel(entry.group)}`}\r\n >\r\n {formatGroupLabel(entry.group)}\r\n </button>\r\n )}\r\n {(!collapsibleGroups || !collapsed) &&\r\n entry.items.map(renderButton)}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState, useRef } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { Link2, Image, Trash2, AlignLeft, AlignCenter, AlignRight } from 'lucide-react';\r\nimport { createCommandExecutor } from '../editor/core/EditorCore';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\n\r\ninterface NodeToolbarProps {\r\n editor: Editor | null;\r\n}\r\n\r\nexport const NodeToolbar: React.FC<NodeToolbarProps> = ({ editor }) => {\r\n const [version, setVersion] = useState(0);\r\n const [selectedClaimId, setSelectedClaimId] = useState<string>('');\r\n const [selectedFigureId, setSelectedFigureId] = useState<string>('');\r\n const editorLanguage = useEditorStore((state) => state.editorLanguage);\r\n const i18n = getEditorText(editorLanguage);\r\n\r\n useEffect(() => {\r\n if (!editor) return;\r\n const rerender = () => setVersion((v) => v + 1);\r\n editor.on('selectionUpdate', rerender);\r\n editor.on('update', rerender);\r\n return () => {\r\n editor.off('selectionUpdate', rerender);\r\n editor.off('update', rerender);\r\n };\r\n }, [editor]);\r\n\r\n if (!editor) return null;\r\n\r\n void version;\r\n\r\n const commandExecutor = createCommandExecutor(editor);\r\n\r\n // Collect all claims\r\n const claimOptions: { id: string; number: number; label: string }[] = [];\r\n editor.state.doc.descendants((node) => {\r\n if (node.type.name !== 'claim') return true;\r\n const claimId = typeof node.attrs.claimId === 'string' ? node.attrs.claimId : '';\r\n const numberValue = Number(node.attrs.number);\r\n if (!claimId || !Number.isFinite(numberValue)) return true;\r\n claimOptions.push({\r\n id: claimId,\r\n number: numberValue,\r\n label: editorLanguage === 'en' ? `Claim ${numberValue}` : `权利要求${numberValue}`,\r\n });\r\n return true;\r\n });\r\n\r\n // Collect all figures\r\n const figureOptions: { id: string; label: string }[] = [];\r\n editor.state.doc.descendants((node) => {\r\n if (node.type.name !== 'figure') return true;\r\n const figureId = typeof node.attrs.id === 'string' ? node.attrs.id.trim() : '';\r\n if (!figureId) return true;\r\n figureOptions.push({ id: figureId, label: figureId });\r\n return true;\r\n });\r\n\r\n // Active claim context\r\n const activeClaim = commandExecutor.findAncestorNode('claim');\r\n const activeClaimId = activeClaim && typeof activeClaim.node.attrs.claimId === 'string'\r\n ? activeClaim.node.attrs.claimId : '';\r\n const activeClaimNumber = Number(activeClaim?.node.attrs.number);\r\n const activeDependsOn: number[] = Array.isArray(activeClaim?.node.attrs.dependsOn)\r\n ? activeClaim.node.attrs.dependsOn.map((v: unknown) => Number(v)).filter((n: number) => Number.isFinite(n))\r\n : [];\r\n const dependencyCandidates = claimOptions.filter(\r\n (item) => Number.isFinite(activeClaimNumber) && item.number < activeClaimNumber\r\n );\r\n const activeDependsOnSet = new Set(activeDependsOn);\r\n const hasActiveClaim = Boolean(activeClaimId);\r\n\r\n const toggleDependency = (claimNumber: number) => {\r\n if (!hasActiveClaim) return;\r\n const next = activeDependsOnSet.has(claimNumber)\r\n ? activeDependsOn.filter((n) => n !== claimNumber)\r\n : [...activeDependsOn, claimNumber].sort((a, b) => a - b);\r\n void commandExecutor.execCommand('patent.setClaimDependency', { dependsOn: next });\r\n };\r\n\r\n // Active figure context\r\n const activeFigure = commandExecutor.findAncestorNode('figure');\r\n const hasActiveFigure = Boolean(activeFigure);\r\n const activeFigureId = activeFigure\r\n ? (typeof activeFigure.node.attrs.id === 'string' ? activeFigure.node.attrs.id.trim() : '')\r\n : '';\r\n const activeFigureContentType: string = activeFigure\r\n ? (typeof activeFigure.node.attrs.contentType === 'string' ? activeFigure.node.attrs.contentType : 'image')\r\n : 'image';\r\n\r\n const [editingFigureId, setEditingFigureId] = useState('');\r\n const figureIdInputRef = useRef<HTMLInputElement>(null);\r\n const prevActiveFigurePos = useRef<number | null>(null);\r\n\r\n const currentFigurePos = activeFigure?.pos ?? null;\r\n if (currentFigurePos !== prevActiveFigurePos.current) {\r\n prevActiveFigurePos.current = currentFigurePos;\r\n if (hasActiveFigure && activeFigureId !== editingFigureId) {\r\n setEditingFigureId(activeFigureId);\r\n }\r\n }\r\n\r\n const handleFigureTypeChange = (newType: string) => {\r\n if (!activeFigure) return;\r\n void commandExecutor.execCommand('patent.updateFigure', {\r\n position: activeFigure.pos,\r\n contentType: newType,\r\n });\r\n };\r\n\r\n const handleFigureIdCommit = () => {\r\n if (!activeFigure) return;\r\n const trimmed = editingFigureId.trim();\r\n if (trimmed === activeFigureId) return;\r\n void commandExecutor.execCommand('patent.updateFigure', {\r\n position: activeFigure.pos,\r\n id: trimmed,\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"border-b border-gray-200 bg-gray-50 p-2\">\r\n <div className=\"bg-white border border-gray-200 rounded-md px-2 py-2 flex flex-wrap items-center gap-2\">\r\n\r\n {/* Claim reference insert */}\r\n {claimOptions.length > 0 && (\r\n <>\r\n <span className=\"text-xs text-gray-500\">{i18n.referenceTarget}</span>\r\n <select\r\n value={selectedClaimId || '__none__'}\r\n onChange={(e) => setSelectedClaimId(e.target.value === '__none__' ? '' : e.target.value)}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white\"\r\n >\r\n <option value=\"__none__\">{i18n.referenceTargetPlaceholder}</option>\r\n {claimOptions.map((item) => (\r\n <option key={item.id} value={item.id}>{item.label}</option>\r\n ))}\r\n </select>\r\n <button\r\n onClick={() => {\r\n if (!selectedClaimId) return;\r\n void commandExecutor.execCommand('patent.insertReference', {\r\n targetType: 'claim',\r\n targetClaimId: selectedClaimId,\r\n });\r\n }}\r\n className=\"p-2 hover:bg-blue-50 text-blue-600 rounded\"\r\n title={i18n.insertReference}\r\n >\r\n <Link2 size={16} />\r\n </button>\r\n </>\r\n )}\r\n\r\n {/* Figure reference insert */}\r\n {figureOptions.length > 0 && (\r\n <>\r\n <span className=\"text-xs text-gray-500\">{i18n.figureReferenceTarget}</span>\r\n <select\r\n value={selectedFigureId || '__none__'}\r\n onChange={(e) => setSelectedFigureId(e.target.value === '__none__' ? '' : e.target.value)}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white\"\r\n >\r\n <option value=\"__none__\">{i18n.figureReferenceTargetPlaceholder}</option>\r\n {figureOptions.map((item) => (\r\n <option key={item.id} value={item.id}>{item.label}</option>\r\n ))}\r\n </select>\r\n <button\r\n onClick={() => {\r\n if (!selectedFigureId) return;\r\n void commandExecutor.execCommand('patent.insertFigureReference', {\r\n targetType: 'figure',\r\n targetFigureId: selectedFigureId,\r\n });\r\n }}\r\n className=\"p-2 hover:bg-blue-50 text-blue-600 rounded\"\r\n title={i18n.insertFigureReference}\r\n >\r\n <Image size={16} />\r\n </button>\r\n </>\r\n )}\r\n\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n\r\n {/* Active figure: ID + type switcher */}\r\n {hasActiveFigure && (\r\n <>\r\n <span className=\"text-xs font-medium text-gray-700\">\r\n {i18n.currentFigure}\r\n </span>\r\n <span className=\"text-xs text-gray-500\">{i18n.figureId}</span>\r\n <input\r\n ref={figureIdInputRef}\r\n type=\"text\"\r\n value={editingFigureId}\r\n onChange={(e) => setEditingFigureId(e.target.value)}\r\n onBlur={handleFigureIdCommit}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n handleFigureIdCommit();\r\n (e.target as HTMLInputElement).blur();\r\n }\r\n }}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white w-20\"\r\n placeholder={editorLanguage === 'en' ? 'Fig.1' : '图1'}\r\n />\r\n <span className=\"text-xs text-gray-500\">{i18n.switchFigureType}</span>\r\n <select\r\n value={activeFigureContentType}\r\n onChange={(e) => handleFigureTypeChange(e.target.value)}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white\"\r\n >\r\n <option value=\"image\">{i18n.figureContentTypeImage}</option>\r\n <option value=\"mermaid\">{i18n.figureContentTypeMermaid}</option>\r\n <option value=\"drawio\">{i18n.figureContentTypeDrawio}</option>\r\n </select>\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n </>\r\n )}\r\n\r\n {/* Active image: width/alignment controls */}\r\n {editor.isActive('image') && (() => {\r\n const attrs = editor.getAttributes('image');\r\n const currentWidth = attrs.width || '';\r\n const widths = ['25%', '50%', '75%', '100%'];\r\n return (\r\n <>\r\n <span className=\"text-xs font-medium text-gray-700\">\r\n {editorLanguage === 'zh' ? '图片' : 'Image'}\r\n </span>\r\n {widths.map((w) => (\r\n <button\r\n key={w}\r\n onClick={() => editor.chain().focus().updateAttributes('image', { width: w }).run()}\r\n className={`text-xs px-2 py-0.5 rounded border ${\r\n currentWidth === w\r\n ? 'bg-blue-50 text-blue-700 border-blue-200'\r\n : 'bg-white text-gray-600 border-gray-200 hover:bg-gray-50'\r\n }`}\r\n >\r\n {w}\r\n </button>\r\n ))}\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n </>\r\n );\r\n })()}\r\n\r\n {/* Active claim: dependency editing */}\r\n {hasActiveClaim ? (\r\n <>\r\n <span className=\"text-xs font-medium text-gray-700\">\r\n {i18n.currentClaim(activeClaimNumber)}\r\n </span>\r\n\r\n {dependencyCandidates.length > 0 && (\r\n <div className=\"flex flex-wrap gap-1 items-center\">\r\n <span className=\"text-xs text-gray-500\">{i18n.dependsOn}</span>\r\n {dependencyCandidates.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => toggleDependency(item.number)}\r\n className={`text-xs px-2 py-0.5 rounded border ${\r\n activeDependsOnSet.has(item.number)\r\n ? 'bg-blue-50 text-blue-700 border-blue-200'\r\n : 'bg-white text-gray-600 border-gray-200 hover:bg-gray-50'\r\n }`}\r\n >\r\n {item.number}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </>\r\n ) : !hasActiveFigure ? (\r\n <span className=\"text-xs text-gray-400\">{i18n.placeCursorToEditDependencies}</span>\r\n ) : null}\r\n\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n\r\n {/* Delete */}\r\n <button\r\n onClick={async () => {\r\n if (hasActiveClaim) {\r\n const removed = await commandExecutor.execCommand('patent.deleteClaim');\r\n if (removed) return;\r\n }\r\n if (editor.chain().focus().deleteSelection().run()) return;\r\n const { from } = editor.state.selection;\r\n if (from > 1) editor.chain().focus().deleteRange({ from: from - 1, to: from }).run();\r\n }}\r\n className=\"p-2 hover:bg-red-50 text-red-600 rounded\"\r\n title={i18n.deleteSelection}\r\n >\r\n <Trash2 size={16} />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\r\nimport type { EditorLanguage } from '../../../store/editorStore';\r\nimport { formatClaimGraphIssueMessage } from '../../../lib/editorI18n';\r\n\r\nexport interface ClaimSnapshot {\r\n claimId: string;\r\n number: number;\r\n dependsOn: number[];\r\n dependsOnClaimIds: string[];\r\n body: string;\r\n pos: number;\r\n}\r\n\r\nexport interface ClaimGraphIssue {\r\n claimId: string;\r\n code: 'forward_reference' | 'self_reference' | 'cycle_dependency' | 'too_many_independent' | 'multi_dependency_conflict';\r\n message: string;\r\n}\r\n\r\nexport interface ClaimTreeRow {\r\n claimId: string;\r\n number: number;\r\n depth: number;\r\n}\r\n\r\nconst normalizeNumberArray = (value: unknown): number[] => {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const numbers = value\r\n .map(item => Number(item))\r\n .filter(item => Number.isFinite(item) && item > 0);\r\n return Array.from(new Set(numbers)).sort((a, b) => a - b);\r\n};\r\n\r\nconst normalizeStringArray = (value: unknown): string[] => {\r\n if (!Array.isArray(value)) {\r\n return [];\r\n }\r\n const items = value\r\n .map(item => (typeof item === 'string' ? item.trim() : ''))\r\n .filter(Boolean);\r\n return Array.from(new Set(items));\r\n};\r\n\r\nexport const buildReferenceInlineText = (node: ProseMirrorNode) => {\r\n const language = node.attrs.lang === 'en' ? 'en' : 'zh';\r\n const targetType = node.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n const displayText = typeof node.attrs.displayText === 'string' ? node.attrs.displayText.trim() : '';\r\n if (displayText) {\r\n return displayText;\r\n }\r\n if (targetType === 'figure') {\r\n const resolvedFigureId =\r\n typeof node.attrs.resolvedFigureId === 'string' ? node.attrs.resolvedFigureId.trim() : '';\r\n if (resolvedFigureId) {\r\n return resolvedFigureId;\r\n }\r\n return language === 'en' ? 'Figure ?' : '附图?';\r\n }\r\n const resolvedNumber = Number(node.attrs.resolvedNumber);\r\n if (Number.isFinite(resolvedNumber)) {\r\n return language === 'en' ? `Claim ${resolvedNumber}` : `权利要求${resolvedNumber}`;\r\n }\r\n return language === 'en' ? 'Claim ?' : '权利要求?';\r\n};\r\n\r\nexport const serializeClaimBodyText = (node: ProseMirrorNode): string => {\r\n if (node.type.name === 'reference') {\r\n return buildReferenceInlineText(node);\r\n }\r\n if (node.type.name === 'hardBreak') {\r\n return '\\n';\r\n }\r\n if (node.isText) {\r\n return node.text || '';\r\n }\r\n let text = '';\r\n node.forEach((child) => {\r\n text += serializeClaimBodyText(child);\r\n });\r\n return text;\r\n};\r\n\r\nexport const extractClaimsFromEditor = (editor: Editor): ClaimSnapshot[] => {\r\n const claims: ClaimSnapshot[] = [];\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'claim') {\r\n return true;\r\n }\r\n const claimId = typeof node.attrs.claimId === 'string' && node.attrs.claimId ? node.attrs.claimId : `claim_${pos}`;\r\n const number = Number(node.attrs.number);\r\n if (!Number.isFinite(number) || number <= 0) {\r\n return true;\r\n }\r\n claims.push({\r\n claimId,\r\n number,\r\n dependsOn: normalizeNumberArray(node.attrs.dependsOn),\r\n dependsOnClaimIds: normalizeStringArray(node.attrs.dependsOnClaimIds),\r\n body: serializeClaimBodyText(node).trim(),\r\n pos,\r\n });\r\n return true;\r\n });\r\n\r\n const numberToId = new Map(claims.map(item => [item.number, item.claimId]));\r\n return claims.map((claim) => {\r\n const fallbackIds = claim.dependsOn\r\n .map(number => numberToId.get(number))\r\n .filter((id): id is string => typeof id === 'string');\r\n const resolvedIds = claim.dependsOnClaimIds.length > 0 ? claim.dependsOnClaimIds : fallbackIds;\r\n return {\r\n ...claim,\r\n dependsOnClaimIds: Array.from(new Set(resolvedIds)),\r\n };\r\n });\r\n};\r\n\r\nexport const validateClaimGraphIssues = (claims: ClaimSnapshot[], language: EditorLanguage = 'zh'): ClaimGraphIssue[] => {\r\n const issues: ClaimGraphIssue[] = [];\r\n const idToNumber = new Map(claims.map(item => [item.claimId, item.number]));\r\n\r\n claims.forEach((claim) => {\r\n claim.dependsOnClaimIds.forEach((dependencyId) => {\r\n const targetNumber = idToNumber.get(dependencyId);\r\n if (dependencyId === claim.claimId) {\r\n issues.push({\r\n claimId: claim.claimId,\r\n code: 'self_reference',\r\n message: formatClaimGraphIssueMessage(language, 'self_reference', claim.number),\r\n });\r\n }\r\n if (typeof targetNumber === 'number' && targetNumber >= claim.number) {\r\n issues.push({\r\n claimId: claim.claimId,\r\n code: 'forward_reference',\r\n message: formatClaimGraphIssueMessage(language, 'forward_reference', claim.number, targetNumber),\r\n });\r\n }\r\n });\r\n });\r\n\r\n const adjacency = new Map(claims.map(item => [item.claimId, item.dependsOnClaimIds]));\r\n const visited = new Set<string>();\r\n const inStack = new Set<string>();\r\n const cycleNodes = new Set<string>();\r\n\r\n const dfs = (nodeId: string) => {\r\n if (inStack.has(nodeId)) {\r\n cycleNodes.add(nodeId);\r\n return;\r\n }\r\n if (visited.has(nodeId)) {\r\n return;\r\n }\r\n visited.add(nodeId);\r\n inStack.add(nodeId);\r\n (adjacency.get(nodeId) || []).forEach(depId => dfs(depId));\r\n inStack.delete(nodeId);\r\n };\r\n\r\n claims.forEach(item => dfs(item.claimId));\r\n cycleNodes.forEach((claimId) => {\r\n const claim = claims.find(item => item.claimId === claimId);\r\n if (!claim) {\r\n return;\r\n }\r\n issues.push({\r\n claimId,\r\n code: 'cycle_dependency',\r\n message: formatClaimGraphIssueMessage(language, 'cycle_dependency', claim.number),\r\n });\r\n });\r\n\r\n const independentClaims = claims.filter(c => c.dependsOn.length === 0);\r\n if (independentClaims.length > 10) {\r\n issues.push({\r\n claimId: independentClaims[0].claimId,\r\n code: 'too_many_independent',\r\n message: language === 'en'\r\n ? `Too many independent claims (${independentClaims.length}), recommended ≤10`\r\n : `独立权利要求过多(${independentClaims.length}项),建议不超过10项`,\r\n });\r\n }\r\n\r\n claims.forEach((claim) => {\r\n if (claim.dependsOn.length > 1) {\r\n const multiDeps = claim.dependsOn;\r\n const hasIndependent = multiDeps.some(n => {\r\n const dep = claims.find(c => c.number === n);\r\n return dep && dep.dependsOn.length === 0;\r\n });\r\n const hasDependent = multiDeps.some(n => {\r\n const dep = claims.find(c => c.number === n);\r\n return dep && dep.dependsOn.length > 0;\r\n });\r\n if (hasIndependent && hasDependent) {\r\n issues.push({\r\n claimId: claim.claimId,\r\n code: 'multi_dependency_conflict',\r\n message: language === 'en'\r\n ? `Claim ${claim.number} depends on both independent and dependent claims (multi-dependency conflict)`\r\n : `权利要求${claim.number}同时引用独立项和从属项(多项从属冲突)`,\r\n });\r\n }\r\n }\r\n });\r\n\r\n return issues;\r\n};\r\n\r\nexport const buildClaimTreeRows = (claims: ClaimSnapshot[]): ClaimTreeRow[] => {\r\n const dependsMap = new Map(claims.map(item => [item.claimId, item.dependsOnClaimIds]));\r\n const childrenMap = new Map<string, string[]>();\r\n claims.forEach((claim) => {\r\n claim.dependsOnClaimIds.forEach((parentId) => {\r\n const current = childrenMap.get(parentId) || [];\r\n if (!current.includes(claim.claimId)) {\r\n current.push(claim.claimId);\r\n }\r\n childrenMap.set(parentId, current);\r\n });\r\n });\r\n const roots = claims\r\n .filter(item => (dependsMap.get(item.claimId) || []).length === 0)\r\n .sort((a, b) => a.number - b.number)\r\n .map(item => item.claimId);\r\n const allIds = claims.map(item => item.claimId);\r\n const orderedRoots = [...roots, ...allIds.filter(id => !roots.includes(id))];\r\n const idToClaim = new Map(claims.map(item => [item.claimId, item]));\r\n const rows: ClaimTreeRow[] = [];\r\n const appended = new Set<string>();\r\n\r\n const walk = (claimId: string, depth: number) => {\r\n if (appended.has(claimId)) {\r\n return;\r\n }\r\n appended.add(claimId);\r\n const claim = idToClaim.get(claimId);\r\n if (!claim) {\r\n return;\r\n }\r\n rows.push({\r\n claimId,\r\n number: claim.number,\r\n depth,\r\n });\r\n const children = (childrenMap.get(claimId) || [])\r\n .map(id => idToClaim.get(id))\r\n .filter((item): item is ClaimSnapshot => !!item)\r\n .sort((a, b) => a.number - b.number)\r\n .map(item => item.claimId);\r\n children.forEach(childId => walk(childId, depth + 1));\r\n };\r\n\r\n orderedRoots.forEach(rootId => walk(rootId, 0));\r\n return rows;\r\n};\r\n\r\nconst escapeXml = (value: string) => {\r\n return value\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n};\r\n\r\nexport const buildCnipaClaimsXml = (claims: ClaimSnapshot[]) => {\r\n const blocks = claims\r\n .sort((a, b) => a.number - b.number)\r\n .map((claim) => {\r\n return `<claim id=\"${claim.number}\"><claim-text>${escapeXml(claim.body)}</claim-text></claim>`;\r\n });\r\n return `<claims>${blocks.join('')}</claims>`;\r\n};\r\n\r\nexport const buildWordClaimsText = (claims: ClaimSnapshot[]) => {\r\n const rows = claims\r\n .sort((a, b) => a.number - b.number)\r\n .map(claim => `${claim.number}. ${claim.body}`);\r\n return ['Claims', '', ...rows].join('\\n');\r\n};\r\n","import React, { useMemo, useState } from 'react';\r\nimport { useEditorState } from '@tiptap/react';\r\nimport { Editor } from '@tiptap/react';\r\nimport {\r\n buildClaimTreeRows,\r\n buildCnipaClaimsXml,\r\n buildWordClaimsText,\r\n extractClaimsFromEditor,\r\n validateClaimGraphIssues,\r\n} from '../editor/plugins/patent/claimIndustrial';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\n\r\ninterface ClaimWorkspacePanelProps {\r\n editor: Editor;\r\n}\r\n\r\nconst downloadText = (filename: string, content: string, mimeType: string) => {\r\n const blob = new Blob([content], { type: mimeType });\r\n const url = URL.createObjectURL(blob);\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.download = filename;\r\n link.click();\r\n URL.revokeObjectURL(url);\r\n};\r\n\r\nexport const ClaimWorkspacePanel: React.FC<ClaimWorkspacePanelProps> = ({ editor }) => {\r\n const [showTree, setShowTree] = useState(false);\r\n const editorLanguage = useEditorStore((state) => state.editorLanguage);\r\n const i18n = getEditorText(editorLanguage);\r\n\r\n const claims = useEditorState({\r\n editor,\r\n selector: (ctx) => extractClaimsFromEditor(ctx.editor),\r\n });\r\n\r\n const issues = useMemo(\r\n () => validateClaimGraphIssues(claims, editorLanguage),\r\n [claims, editorLanguage]\r\n );\r\n\r\n const treeRows = useMemo(() => buildClaimTreeRows(claims), [claims]);\r\n\r\n const claimPosMap = useMemo(\r\n () => new Map(claims.map((item) => [item.claimId, item.pos])),\r\n [claims]\r\n );\r\n\r\n const jumpTo = (claimId: string) => {\r\n const pos = claimPosMap.get(claimId);\r\n if (typeof pos !== 'number') return;\r\n editor.chain().focus().setTextSelection(pos + 1).run();\r\n };\r\n\r\n return (\r\n <div className=\"border-b border-gray-200 bg-white px-3 py-2\">\r\n {/* 主操作行 */}\r\n <div className=\"flex flex-wrap items-center gap-2 text-xs\">\r\n <span className=\"font-medium text-gray-700\">{i18n.claimWorkspacePanel}</span>\r\n <span className=\"text-gray-400\">{i18n.totalCount(claims.length)}</span>\r\n <span className={issues.length === 0 ? 'text-emerald-600' : 'text-amber-600'}>\r\n {i18n.graphIssuesCount(issues.length)}\r\n </span>\r\n\r\n {/* 导出折叠到\"更多\"下拉 */}\r\n {/* <div className=\"relative group\">\r\n <button className=\"px-2 py-1 rounded border border-gray-200 hover:bg-gray-50 text-gray-700\">\r\n 更多 ▾\r\n </button>\r\n <div className=\"absolute left-0 top-full mt-1 hidden group-hover:flex flex-col bg-white border border-gray-200 rounded shadow-md z-10 min-w-max\">\r\n <button\r\n onClick={() => downloadText('claims-cnipa.xml', buildCnipaClaimsXml(claims), 'application/xml;charset=utf-8')}\r\n className=\"px-3 py-2 text-left text-xs hover:bg-gray-50 text-gray-700\"\r\n >\r\n {i18n.exportCnipaXml}\r\n </button>\r\n <button\r\n onClick={() => downloadText('claims-word-mapping.txt', buildWordClaimsText(claims), 'text/plain;charset=utf-8')}\r\n className=\"px-3 py-2 text-left text-xs hover:bg-gray-50 text-gray-700\"\r\n >\r\n {i18n.exportWordMapping}\r\n </button>\r\n </div>\r\n </div> */}\r\n\r\n {treeRows.length > 0 && (\r\n <button\r\n onClick={() => setShowTree((v) => !v)}\r\n className=\"px-2 py-1 rounded border border-gray-200 hover:bg-gray-50 text-gray-500\"\r\n >\r\n {showTree ? '收起依赖树' : '依赖树'}\r\n </button>\r\n )}\r\n\r\n </div>\r\n\r\n {/* 校验问题 */}\r\n {issues.length > 0 && (\r\n <div className=\"mt-2 flex flex-wrap gap-1\">\r\n {issues.map((issue, index) => (\r\n <button\r\n key={`${issue.claimId}-${issue.code}-${index}`}\r\n onClick={() => jumpTo(issue.claimId)}\r\n className=\"text-xs px-2 py-1 rounded bg-amber-50 border border-amber-200 text-amber-700 hover:bg-amber-100\"\r\n >\r\n {issue.message}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* 依赖树(按需展开) */}\r\n {showTree && treeRows.length > 0 && (\r\n <div className=\"mt-2 border border-gray-200 rounded p-2 bg-gray-50\">\r\n <div className=\"text-xs font-medium text-gray-600 mb-1\">{i18n.claimDependencyTree}</div>\r\n <div className=\"space-y-0.5\">\r\n {treeRows.map((row) => (\r\n <button\r\n key={row.claimId}\r\n onClick={() => jumpTo(row.claimId)}\r\n className=\"block text-left text-xs text-gray-700 hover:text-blue-600\"\r\n style={{ marginLeft: `${row.depth * 14}px` }}\r\n >\r\n {i18n.claimLabel(row.number)}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import type { PatentSectionType } from '../plugins/patent/sectionNode';\r\n\r\nexport const sectionContextDeps: Record<PatentSectionType, PatentSectionType[]> = {\r\n // Invention & Utility Model\r\n technical_field: [],\r\n background_art: ['technical_field'],\r\n summary: ['technical_field', 'background_art'],\r\n drawing_description: ['summary'],\r\n detailed_description: ['summary', 'claims', 'drawing_description'],\r\n claims: ['summary'],\r\n abstract: ['claims', 'summary'],\r\n abstract_drawing: ['drawing_description'],\r\n drawing_figures: ['drawing_description'],\r\n // Design Patent\r\n design_product_name: [],\r\n design_usage: ['design_product_name'],\r\n design_description: ['design_product_name', 'design_usage'],\r\n design_views: ['design_description'],\r\n design_brief: ['design_description', 'design_views'],\r\n};\r\n\r\nexport function getMissingSectionDeps(\r\n targetSection: PatentSectionType,\r\n completedSections: Set<PatentSectionType>\r\n): PatentSectionType[] {\r\n const deps = sectionContextDeps[targetSection] || [];\r\n return deps.filter(dep => !completedSections.has(dep));\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport type { PatentSectionType } from '../plugins/patent/sectionNode';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\nimport { useEditorStore } from '../../store/editorStore';\r\nimport { sectionContextDeps } from './sectionContextDeps';\r\n\r\nexport interface AIContext {\r\n scope: 'selection' | 'section' | 'document';\r\n sectionType?: PatentSectionType;\r\n targetSectionPos?: number;\r\n userInput?: string;\r\n selectedText?: string;\r\n dependencyContext?: {\r\n sectionType: PatentSectionType;\r\n content: string;\r\n }[];\r\n surroundingText?: string;\r\n language: EditorLanguage;\r\n}\r\n\r\nexport interface SectionInfo {\r\n sectionType: PatentSectionType;\r\n pos: number;\r\n content: string;\r\n}\r\n\r\nexport function getAllSections(editor: Editor): SectionInfo[] {\r\n const sections: SectionInfo[] = [];\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n sections.push({\r\n sectionType: 'patent_title' as unknown as PatentSectionType,\r\n pos,\r\n content: node.textContent || '',\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n sections.push({\r\n sectionType: node.attrs.sectionType as PatentSectionType,\r\n pos,\r\n content: node.textContent || '',\r\n });\r\n return false;\r\n }\r\n return true;\r\n });\r\n return sections;\r\n}\r\n\r\nexport function findSectionAtCursor(editor: Editor): SectionInfo | null {\r\n const { from } = editor.state.selection;\r\n const $pos = editor.state.doc.resolve(from);\r\n for (let depth = $pos.depth; depth >= 0; depth--) {\r\n const node = $pos.node(depth);\r\n if (node.type.name === 'patent_title') {\r\n return {\r\n sectionType: 'patent_title' as unknown as PatentSectionType,\r\n pos: $pos.before(depth),\r\n content: node.textContent || '',\r\n };\r\n }\r\n if (node.type.name === 'patent_section') {\r\n return {\r\n sectionType: node.attrs.sectionType as PatentSectionType,\r\n pos: $pos.before(depth),\r\n content: node.textContent || '',\r\n };\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nexport function serializeSectionContent(editor: Editor, sectionType: PatentSectionType): string {\r\n const sections = getAllSections(editor);\r\n const section = sections.find(s => s.sectionType === sectionType);\r\n if (!section) return '';\r\n return section.content.trim();\r\n}\r\n\r\nexport function buildDependencyContext(\r\n editor: Editor,\r\n targetSectionType: PatentSectionType\r\n): AIContext['dependencyContext'] {\r\n const deps = sectionContextDeps[targetSectionType];\r\n if (!deps || deps.length === 0) return [];\r\n\r\n const sections = getAllSections(editor);\r\n const sectionMap = new Map(sections.map(s => [s.sectionType, s]));\r\n\r\n return deps\r\n .map(depType => {\r\n const section = sectionMap.get(depType);\r\n if (!section || section.content.trim().length === 0) return null;\r\n return {\r\n sectionType: depType,\r\n content: section.content.trim(),\r\n };\r\n })\r\n .filter((item): item is NonNullable<typeof item> => item !== null && item.content.length > 0);\r\n}\r\n\r\nexport function buildAIContext(\r\n editor: Editor,\r\n options: {\r\n scope?: AIContext['scope'];\r\n sectionType?: PatentSectionType;\r\n targetSectionPos?: number;\r\n userInput?: string;\r\n } = {}\r\n): AIContext {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const { from, to } = editor.state.selection;\r\n const selectedText = from !== to\r\n ? editor.state.doc.textBetween(from, to, ' ', '\\0')\r\n : undefined;\r\n\r\n let sectionType = options.sectionType;\r\n let targetSectionPos = options.targetSectionPos;\r\n\r\n if (!sectionType) {\r\n const current = findSectionAtCursor(editor);\r\n if (current) {\r\n sectionType = current.sectionType;\r\n targetSectionPos = current.pos;\r\n }\r\n }\r\n\r\n const scope = options.scope || (sectionType ? 'section' : (selectedText ? 'selection' : 'document'));\r\n\r\n const dependencyContext = sectionType\r\n ? buildDependencyContext(editor, sectionType)\r\n : undefined;\r\n\r\n let surroundingText: string | undefined;\r\n if (scope === 'selection' && from !== to) {\r\n const contextRange = 200;\r\n const beforeFrom = Math.max(0, from - contextRange);\r\n const afterTo = Math.min(editor.state.doc.content.size, to + contextRange);\r\n const before = editor.state.doc.textBetween(beforeFrom, from, ' ', '\\0');\r\n const after = editor.state.doc.textBetween(to, afterTo, ' ', '\\0');\r\n surroundingText = `...${before}[SELECTED]${after}...`;\r\n }\r\n\r\n return {\r\n scope,\r\n sectionType,\r\n targetSectionPos,\r\n userInput: options.userInput,\r\n selectedText,\r\n dependencyContext,\r\n surroundingText,\r\n language,\r\n };\r\n}\r\n","import React from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { BubbleMenu as TiptapBubbleMenu } from '@tiptap/react/menus';\r\nimport {\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strikethrough,\r\n Code,\r\n Superscript,\r\n Subscript,\r\n Link2,\r\n Highlighter,\r\n Sparkles,\r\n} from 'lucide-react';\r\nimport clsx from 'clsx';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { findSectionAtCursor } from '../editor/ai/aiContext';\r\n\r\ninterface EditorBubbleMenuProps {\r\n editor: Editor;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport const EditorBubbleMenu: React.FC<EditorBubbleMenuProps> = ({ editor, onSelectionOptimize }) => {\r\n const { addChatReference, openChatPanel, editorLanguage } = useEditorStore();\r\n const zh = editorLanguage === 'zh';\r\n\r\n const btnClass = (active: boolean) =>\r\n clsx(\r\n 'p-1.5 rounded transition-colors',\r\n active ? 'bg-blue-100 text-blue-600' : 'text-gray-600 hover:bg-gray-100'\r\n );\r\n\r\n const handleAIOptimize = () => {\r\n const { from, to } = editor.state.selection;\r\n if (from === to) return;\r\n const selectedText = editor.state.doc.textBetween(from, to, ' ');\r\n const section = findSectionAtCursor(editor);\r\n if (onSelectionOptimize) {\r\n onSelectionOptimize({ text: selectedText, from, to, sectionType: section?.sectionType });\r\n return;\r\n }\r\n addChatReference({ text: selectedText, from, to, sectionType: section?.sectionType });\r\n openChatPanel();\r\n };\r\n\r\n const handleLink = () => {\r\n const prev = editor.getAttributes('link').href;\r\n const url = window.prompt('URL', prev || 'https://');\r\n if (url === null) return;\r\n if (url === '') {\r\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\r\n } else {\r\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\r\n }\r\n };\r\n\r\n return (\r\n <TiptapBubbleMenu\r\n editor={editor}\r\n shouldShow={({ editor, state }) => {\r\n const { from, to } = state.selection;\r\n if (from === to) return false;\r\n if (editor.isActive('codeBlock')) return false;\r\n return true;\r\n }}\r\n >\r\n <div className=\"bubble-menu\">\r\n <button\r\n onClick={() => editor.chain().focus().toggleBold().run()}\r\n className={btnClass(editor.isActive('bold'))}\r\n title=\"Bold\"\r\n >\r\n <Bold size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleItalic().run()}\r\n className={btnClass(editor.isActive('italic'))}\r\n title=\"Italic\"\r\n >\r\n <Italic size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleUnderline().run()}\r\n className={btnClass(editor.isActive('underline'))}\r\n title=\"Underline\"\r\n >\r\n <Underline size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleStrike().run()}\r\n className={btnClass(editor.isActive('strike'))}\r\n title=\"Strikethrough\"\r\n >\r\n <Strikethrough size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleCode().run()}\r\n className={btnClass(editor.isActive('code'))}\r\n title=\"Code\"\r\n >\r\n <Code size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleSuperscript().run()}\r\n className={btnClass(editor.isActive('superscript'))}\r\n title=\"Superscript\"\r\n >\r\n <Superscript size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleSubscript().run()}\r\n className={btnClass(editor.isActive('subscript'))}\r\n title=\"Subscript\"\r\n >\r\n <Subscript size={15} />\r\n </button>\r\n <div className=\"bubble-menu-divider\" />\r\n <button\r\n onClick={() => editor.chain().focus().toggleHighlight().run()}\r\n className={btnClass(editor.isActive('highlight'))}\r\n title=\"Highlight\"\r\n >\r\n <Highlighter size={15} />\r\n </button>\r\n <button\r\n onClick={handleLink}\r\n className={btnClass(editor.isActive('link'))}\r\n title=\"Link\"\r\n >\r\n <Link2 size={15} />\r\n </button>\r\n <div className=\"bubble-menu-divider\" />\r\n <button\r\n onClick={handleAIOptimize}\r\n className=\"p-1.5 rounded transition-colors text-purple-500 hover:bg-purple-50\"\r\n title={zh ? 'AI 优化' : 'AI Optimize'}\r\n >\r\n <Sparkles size={15} />\r\n </button>\r\n </div>\r\n </TiptapBubbleMenu>\r\n );\r\n};\r\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { X, ChevronUp, ChevronDown, Replace, ReplaceAll, CaseSensitive } from 'lucide-react';\r\nimport clsx from 'clsx';\r\n\r\ninterface FindReplaceProps {\r\n editor: Editor;\r\n}\r\n\r\nexport const FindReplace: React.FC<FindReplaceProps> = ({ editor }) => {\r\n const [visible, setVisible] = useState(false);\r\n const [showReplace, setShowReplace] = useState(false);\r\n const [searchTerm, setSearchTerm] = useState('');\r\n const [replaceTerm, setReplaceTerm] = useState('');\r\n const [caseSensitive, setCaseSensitive] = useState(false);\r\n const searchInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const storage = (editor.extensionStorage as any).searchReplace;\r\n const resultCount = storage?.results?.length ?? 0;\r\n const currentIndex = storage?.currentIndex ?? -1;\r\n\r\n useEffect(() => {\r\n const handler = (e: Event) => {\r\n setVisible(true);\r\n const detail = (e as CustomEvent).detail;\r\n if (detail?.replace) setShowReplace(true);\r\n requestAnimationFrame(() => searchInputRef.current?.focus());\r\n };\r\n window.addEventListener('editor:toggleSearch', handler);\r\n return () => window.removeEventListener('editor:toggleSearch', handler);\r\n }, []);\r\n\r\n const doSearch = useCallback(\r\n (term: string) => {\r\n setSearchTerm(term);\r\n (editor.commands as any).setSearchTerm(term);\r\n },\r\n [editor]\r\n );\r\n\r\n const close = useCallback(() => {\r\n setVisible(false);\r\n (editor.commands as any).clearSearch();\r\n editor.commands.focus();\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && visible) {\r\n close();\r\n }\r\n };\r\n window.addEventListener('keydown', handler);\r\n return () => window.removeEventListener('keydown', handler);\r\n }, [visible, close]);\r\n\r\n const toggleCaseSensitive = () => {\r\n const next = !caseSensitive;\r\n setCaseSensitive(next);\r\n (editor.commands as any).setCaseSensitive(next);\r\n };\r\n\r\n if (!visible) return null;\r\n\r\n return (\r\n <div className=\"find-replace-bar\">\r\n <div className=\"find-replace-row\">\r\n <div className=\"find-replace-input-group\">\r\n <input\r\n ref={searchInputRef}\r\n type=\"text\"\r\n value={searchTerm}\r\n onChange={(e) => doSearch(e.target.value)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n e.shiftKey\r\n ? (editor.commands as any).previousSearchResult()\r\n : (editor.commands as any).nextSearchResult();\r\n }\r\n }}\r\n placeholder=\"Find...\"\r\n className=\"find-replace-input\"\r\n />\r\n <span className=\"find-replace-count\">\r\n {resultCount > 0 ? `${currentIndex + 1}/${resultCount}` : searchTerm ? '0' : ''}\r\n </span>\r\n </div>\r\n <button\r\n onClick={toggleCaseSensitive}\r\n className={clsx('find-replace-btn', caseSensitive && 'find-replace-btn--active')}\r\n title=\"Case Sensitive\"\r\n >\r\n <CaseSensitive size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).previousSearchResult()} className=\"find-replace-btn\" title=\"Previous\">\r\n <ChevronUp size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).nextSearchResult()} className=\"find-replace-btn\" title=\"Next\">\r\n <ChevronDown size={15} />\r\n </button>\r\n <button\r\n onClick={() => setShowReplace((v) => !v)}\r\n className={clsx('find-replace-btn', showReplace && 'find-replace-btn--active')}\r\n title=\"Toggle Replace\"\r\n >\r\n <Replace size={15} />\r\n </button>\r\n <button onClick={close} className=\"find-replace-btn\" title=\"Close (Esc)\">\r\n <X size={15} />\r\n </button>\r\n </div>\r\n {showReplace && (\r\n <div className=\"find-replace-row\">\r\n <input\r\n type=\"text\"\r\n value={replaceTerm}\r\n onChange={(e) => {\r\n setReplaceTerm(e.target.value);\r\n (editor.commands as any).setReplaceTerm(e.target.value);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') (editor.commands as any).replaceCurrent();\r\n }}\r\n placeholder=\"Replace...\"\r\n className=\"find-replace-input\"\r\n />\r\n <button onClick={() => (editor.commands as any).replaceCurrent()} className=\"find-replace-btn\" title=\"Replace\">\r\n <Replace size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).replaceAll()} className=\"find-replace-btn\" title=\"Replace All\">\r\n <ReplaceAll size={15} />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useMemo } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { useEditorStore } from '../store/editorStore';\r\n\r\ninterface WordCountProps {\r\n editor: Editor;\r\n}\r\n\r\nexport const WordCount: React.FC<WordCountProps> = ({ editor }) => {\r\n const { editorLanguage } = useEditorStore();\r\n const zh = editorLanguage === 'zh';\r\n\r\n const stats = useMemo(() => {\r\n const state = editor.state;\r\n const docText = state.doc.textBetween(0, state.doc.content.size, ' ', '\\0');\r\n const charCount = docText.replace(/\\s/g, '').length;\r\n\r\n const { from, to } = state.selection;\r\n let selectionCount = 0;\r\n if (from !== to) {\r\n const selText = state.doc.textBetween(from, to, ' ', '\\0');\r\n selectionCount = selText.replace(/\\s/g, '').length;\r\n }\r\n\r\n return { charCount, selectionCount };\r\n }, [editor.state.doc, editor.state.selection]);\r\n\r\n return (\r\n <div className=\"word-count-bar\">\r\n <span>{zh ? '字数' : 'Characters'}: {stats.charCount}</span>\r\n {stats.selectionCount > 0 && (\r\n <span>{zh ? '选区' : 'Selected'}: {stats.selectionCount}</span>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState, useMemo } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { ChevronRight, ChevronDown, FileText, PanelLeftClose, PanelLeft } from 'lucide-react';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport clsx from 'clsx';\r\n\r\ninterface OutlinePanelProps {\r\n editor: Editor;\r\n}\r\n\r\ninterface OutlineItem {\r\n type: 'section' | 'heading' | 'book-group';\r\n pos: number;\r\n title: string;\r\n state?: string;\r\n level?: number;\r\n charCount: number;\r\n indent?: boolean;\r\n}\r\n\r\nconst STATE_ICONS: Record<string, string> = {\r\n empty: '○',\r\n filled: '●',\r\n};\r\n\r\nconst STATE_COLORS: Record<string, string> = {\r\n empty: 'text-gray-400',\r\n filled: 'text-green-500',\r\n};\r\n\r\nconst DESCRIPTION_SUB_TYPES = new Set([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\nexport const OutlinePanel: React.FC<OutlinePanelProps> = ({ editor }) => {\r\n const { editorLanguage } = useEditorStore();\r\n const i18n = getEditorText(editorLanguage);\r\n const [collapsed, setCollapsed] = useState(false);\r\n const [version, setVersion] = useState(0);\r\n\r\n useEffect(() => {\r\n const handler = () => setVersion((v) => v + 1);\r\n editor.on('update', handler);\r\n return () => { editor.off('update', handler); };\r\n }, [editor]);\r\n\r\n const items = useMemo(() => {\r\n void version;\r\n const result: OutlineItem[] = [];\r\n let descriptionGroupInserted = false;\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n // Insert \"说明书\" group header before the first title/sub-section\r\n if (!descriptionGroupInserted) {\r\n const bookLabel = (typeof (i18n as Record<string, unknown>)['bookTitle_description'] === 'string'\r\n ? (i18n as Record<string, unknown>)['bookTitle_description'] : '说明书') as string;\r\n result.push({\r\n type: 'book-group',\r\n pos,\r\n title: bookLabel,\r\n charCount: 0,\r\n });\r\n descriptionGroupInserted = true;\r\n }\r\n const text = node.textContent || '';\r\n const hasContent = text.trim().length > 0;\r\n const placeholder = (typeof i18n['patentTitlePlaceholder'] === 'string'\r\n ? i18n['patentTitlePlaceholder'] : 'Patent Title') as string;\r\n result.push({\r\n type: 'section',\r\n pos,\r\n title: hasContent ? text.trim() : placeholder,\r\n state: hasContent ? 'filled' : 'empty',\r\n charCount: text.replace(/\\s/g, '').length,\r\n indent: true,\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const isSub = DESCRIPTION_SUB_TYPES.has(sectionType);\r\n const key = `sectionTitle_${sectionType}` as keyof typeof i18n;\r\n const title = (typeof i18n[key] === 'string' ? i18n[key] : sectionType) as string;\r\n const text = node.textContent || '';\r\n const hasContent = text.trim().length > 0;\r\n result.push({\r\n type: 'section',\r\n pos,\r\n title,\r\n state: hasContent ? 'filled' : 'empty',\r\n charCount: text.replace(/\\s/g, '').length,\r\n indent: isSub,\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'heading') {\r\n const level = node.attrs.level as number;\r\n const text = node.textContent || '';\r\n if (text.trim()) {\r\n result.push({\r\n type: 'heading',\r\n pos,\r\n title: text,\r\n level,\r\n charCount: text.replace(/\\s/g, '').length,\r\n });\r\n }\r\n return false;\r\n }\r\n return true;\r\n });\r\n return result;\r\n }, [editor, version, i18n]);\r\n\r\n if (collapsed) {\r\n return (\r\n <div className=\"outline-panel outline-panel--collapsed\">\r\n <button\r\n onClick={() => setCollapsed(false)}\r\n className=\"outline-panel-toggle\"\r\n title={editorLanguage === 'zh' ? '展开大纲' : 'Expand Outline'}\r\n >\r\n <PanelLeft size={16} />\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"outline-panel\">\r\n <div className=\"outline-panel-header\">\r\n <FileText size={14} />\r\n <span>{editorLanguage === 'zh' ? '文档大纲' : 'Outline'}</span>\r\n <button\r\n onClick={() => setCollapsed(true)}\r\n className=\"outline-panel-toggle ml-auto\"\r\n title={editorLanguage === 'zh' ? '收起大纲' : 'Collapse Outline'}\r\n >\r\n <PanelLeftClose size={14} />\r\n </button>\r\n </div>\r\n <div className=\"outline-panel-list\">\r\n {items.length === 0 && (\r\n <div className=\"outline-panel-empty\">\r\n {editorLanguage === 'zh' ? '暂无章节' : 'No sections yet'}\r\n </div>\r\n )}\r\n {items.map((item, idx) => (\r\n <button\r\n key={`${item.pos}-${idx}`}\r\n className={clsx(\r\n 'outline-panel-item',\r\n item.type === 'heading' && `outline-panel-item--h${item.level}`,\r\n item.type === 'book-group' && 'outline-panel-item--book',\r\n item.indent && 'outline-panel-item--indent',\r\n )}\r\n onClick={() => {\r\n if (item.type === 'book-group') return;\r\n editor.chain().setTextSelection(item.pos + 1).focus().run();\r\n requestAnimationFrame(() => {\r\n const el = editor.view.nodeDOM(item.pos) as HTMLElement | null;\r\n el?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n });\r\n }}\r\n >\r\n {item.type === 'section' && item.state && (\r\n <span className={clsx('outline-item-state', STATE_COLORS[item.state])}>\r\n {STATE_ICONS[item.state] || '○'}\r\n </span>\r\n )}\r\n <span className=\"outline-item-title\">{item.title}</span>\r\n {item.type !== 'book-group' && (\r\n <span className=\"outline-item-count\">{item.charCount}</span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { Editor, EditorContent } from '@tiptap/react';\r\nimport clsx from 'clsx';\r\n\r\ntype RenderMode = 'edit' | 'readonly';\r\n\r\ninterface NodeRendererProps {\r\n editor: Editor;\r\n mode?: RenderMode;\r\n className?: string;\r\n}\r\n\r\nexport const NodeRenderer: React.FC<NodeRendererProps> = ({\r\n editor,\r\n mode = 'edit',\r\n className,\r\n}) => {\r\n useEffect(() => {\r\n editor.setEditable(mode === 'edit');\r\n }, [editor, mode]);\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n 'h-full',\r\n mode === 'readonly' ? 'cursor-default' : 'cursor-text',\r\n className\r\n )}\r\n >\r\n <EditorContent editor={editor} className=\"h-full\" />\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useRef, useCallback } from 'react';\r\nimport { useEditor, JSONContent, Editor } from '@tiptap/react';\r\nimport { createCommandExecutor, createEditorConfig } from '../editor/core/EditorCore';\r\nimport { pluginManager } from '../editor/core/PluginManager';\r\nimport { Toolbar } from './Toolbar';\r\nimport { NodeToolbar } from './NodeToolbar';\r\nimport { ClaimWorkspacePanel } from './ClaimWorkspacePanel';\r\nimport { EditorBubbleMenu } from './BubbleMenu';\r\nimport { FindReplace } from './FindReplace';\r\nimport { WordCount } from './WordCount';\r\nimport { OutlinePanel } from './OutlinePanel';\r\n\r\nimport { NodeRenderer } from '../editor/renderer';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport '../styles/editor.css';\r\n\r\nconst AUTO_SAVE_KEY = 'patent-editor-draft';\r\nconst AUTO_SAVE_DEBOUNCE_MS = 1500;\r\n\r\nconst loadDraftFromStorage = (): JSONContent | null => {\r\n try {\r\n const raw = localStorage.getItem(AUTO_SAVE_KEY);\r\n if (!raw) return null;\r\n return JSON.parse(raw) as JSONContent;\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\ninterface EditorViewProps {\r\n initialContent?: JSONContent;\r\n onChange?: (content: JSONContent) => void;\r\n className?: string;\r\n readOnly?: boolean;\r\n /** Disable content editing without hiding toolbar/UI (unlike readOnly). */\r\n editable?: boolean;\r\n onEditorReady?: (editor: Editor) => void;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport const EditorView: React.FC<EditorViewProps> = ({\r\n initialContent,\r\n onChange,\r\n className,\r\n readOnly = false,\r\n editable = true,\r\n onEditorReady,\r\n onSelectionOptimize,\r\n}) => {\r\n const { setEditor, setDocument, editorLanguage, autoSaveStatus, ai } = useEditorStore();\r\n const { setAutoSaveStatus, setLastSavedAt } = useEditorStore();\r\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const resolvedInitialContent = initialContent || (!onChange ? loadDraftFromStorage() : null) || {\r\n type: 'doc',\r\n content: [\r\n {\r\n type: 'paragraph',\r\n content: [{ type: 'text', text: '' }],\r\n },\r\n ],\r\n };\r\n\r\n const saveToStorage = useCallback((json: JSONContent) => {\r\n try {\r\n setAutoSaveStatus('saving');\r\n localStorage.setItem(AUTO_SAVE_KEY, JSON.stringify(json));\r\n setAutoSaveStatus('saved');\r\n setLastSavedAt(new Date());\r\n } catch {\r\n setAutoSaveStatus('error');\r\n }\r\n }, [setAutoSaveStatus, setLastSavedAt]);\r\n\r\n const editor = useEditor(\r\n createEditorConfig({\r\n content: resolvedInitialContent,\r\n onUpdate: ({ editor }) => {\r\n const json = editor.getJSON();\r\n setDocument(json);\r\n pluginManager.notifyStateChange(editor);\r\n if (onChange) {\r\n onChange(json);\r\n }\r\n if (!onChange) {\r\n if (debounceRef.current) {\r\n clearTimeout(debounceRef.current);\r\n }\r\n debounceRef.current = setTimeout(() => {\r\n saveToStorage(json);\r\n }, AUTO_SAVE_DEBOUNCE_MS);\r\n }\r\n },\r\n onCreate: ({ editor }) => {\r\n setEditor(editor);\r\n onEditorReady?.(editor);\r\n pluginManager.initializePlugins(editor);\r\n const executor = createCommandExecutor(editor);\r\n void executor.execCommand('patent.normalizeClaims');\r\n pluginManager.notifyStateChange(editor);\r\n },\r\n onSelectionUpdate: ({ editor }) => {\r\n pluginManager.notifySelectionChange(editor);\r\n },\r\n editorProps: {\r\n attributes: {\r\n class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none',\r\n },\r\n },\r\n })\r\n );\r\n\r\n const initialContentAppliedRef = useRef(false);\r\n useEffect(() => {\r\n if (!editor || !initialContent) return;\r\n if (!initialContentAppliedRef.current) {\r\n initialContentAppliedRef.current = true;\r\n return;\r\n }\r\n editor.commands.setContent(initialContent);\r\n }, [editor, initialContent]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (debounceRef.current) {\r\n clearTimeout(debounceRef.current);\r\n }\r\n if (editor) {\r\n pluginManager.destroyPlugins(editor);\r\n editor.destroy();\r\n }\r\n };\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n if (!editor) {\r\n return;\r\n }\r\n pluginManager.notifyStateChange(editor);\r\n }, [editor, editorLanguage]);\r\n\r\n if (!editor) {\r\n return null;\r\n }\r\n\r\n const i18n = getEditorText(editorLanguage);\r\n const saveLabel =\r\n autoSaveStatus === 'saving' ? i18n.autoSaveSaving :\r\n autoSaveStatus === 'saved' ? i18n.autoSaveSaved :\r\n autoSaveStatus === 'error' ? i18n.autoSaveError : '';\r\n\r\n return (\r\n <div className={`editor-container flex flex-col h-full ${className}`}>\r\n {!readOnly && (\r\n <div className=\"flex items-center\">\r\n <Toolbar editor={editor} />\r\n {saveLabel && (\r\n <span className={`auto-save-indicator auto-save-indicator--${autoSaveStatus} ml-2`}>\r\n {saveLabel}\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n {!readOnly && editor && <NodeToolbar editor={editor} />}\r\n {!readOnly && editor && <ClaimWorkspacePanel editor={editor} />}\r\n {!readOnly && editor && <EditorBubbleMenu editor={editor} onSelectionOptimize={onSelectionOptimize} />}\r\n {!readOnly && editor && <FindReplace editor={editor} />}\r\n <div className=\"flex flex-1 overflow-hidden\">\r\n {!readOnly && editor && <OutlinePanel editor={editor} />}\r\n <div className=\"flex-1 overflow-y-auto bg-white p-4 relative\">\r\n <NodeRenderer\r\n editor={editor}\r\n mode={readOnly || !editable || (ai.status === 'streaming' && ai.activeSectionType === 'claims') ? 'readonly' : 'edit'}\r\n />\r\n </div>\r\n </div>\r\n {!readOnly && <WordCount editor={editor} />}\r\n </div>\r\n );\r\n};\r\n","import type { PatentSectionType } from '../plugins/patent/sectionNode';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\n\r\n// ── AI Completion Request (stateless, for generate) ──\r\n\r\nexport type AIAction = 'generate';\r\n\r\nexport interface AIRequest {\r\n action: AIAction;\r\n sectionType?: PatentSectionType;\r\n instruction?: string;\r\n content?: string;\r\n dependencyContext?: { sectionType: string; content: string }[];\r\n language: EditorLanguage;\r\n}\r\n\r\n// ── Chat Session Types ──\r\n\r\nexport interface ChatReference {\r\n text: string;\r\n source?: string;\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport interface ChatMessageRequest {\r\n content: string;\r\n references?: ChatReference[];\r\n language: EditorLanguage;\r\n}\r\n\r\nexport interface ChatMessageResponse {\r\n messageId: string;\r\n sessionId: string;\r\n status: 'processing' | 'done' | 'error';\r\n}\r\n\r\nexport interface ChatSession {\r\n sessionId: string;\r\n patentId?: string;\r\n title: string;\r\n lastMessage?: string;\r\n messageCount: number;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\nexport interface ChatMessage {\r\n messageId: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n references?: ChatReference[];\r\n patches?: AIPatchData[];\r\n usage?: { tokens: number };\r\n status: 'processing' | 'done' | 'error';\r\n createdAt: string;\r\n}\r\n\r\n// ── Response events (SSE) ──\r\n\r\nexport interface AIPatchTarget {\r\n type: 'section' | 'ref' | 'search';\r\n sectionType?: PatentSectionType;\r\n refIndex?: number;\r\n searchText?: string;\r\n}\r\n\r\nexport interface AIPatchData {\r\n op: 'replace' | 'insert' | 'delete';\r\n target: AIPatchTarget;\r\n search?: string;\r\n content: string;\r\n reason?: string;\r\n // Legacy fields (backward compat with old protocol)\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport type AIResponseEvent =\r\n | { type: 'delta'; content: string }\r\n | { type: 'patch'; patch: AIPatchData }\r\n | { type: 'done'; usage?: { tokens: number } }\r\n | { type: 'error'; message: string };\r\n\r\n// ── Adapter interface ──\r\n\r\nexport interface AIServiceAdapter {\r\n request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>>;\r\n abort(): void;\r\n}\r\n\r\n// ── Chat Session API client ──\r\n\r\nexport interface ChatSessionAPI {\r\n createSession(patentId?: string, title?: string, language?: EditorLanguage): Promise<ChatSession>;\r\n listSessions(patentId?: string, page?: number, pageSize?: number): Promise<{ total: number; items: ChatSession[] }>;\r\n getMessages(sessionId: string, page?: number, pageSize?: number): Promise<{ total: number; items: ChatMessage[] }>;\r\n deleteSession(sessionId: string): Promise<void>;\r\n sendMessage(sessionId: string, req: ChatMessageRequest): Promise<ChatMessageResponse>;\r\n subscribeStream(sessionId: string, messageId: string): Promise<ReadableStream<AIResponseEvent>>;\r\n abort(): void;\r\n}\r\n\r\n// ── Default SSE implementation ──\r\n\r\nfunction parseSSEStream(body: ReadableStream<Uint8Array>): ReadableStream<AIResponseEvent> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n\r\n return new ReadableStream<AIResponseEvent>({\r\n async pull(controller) {\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) {\r\n controller.close();\r\n return;\r\n }\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n let currentEvent = '';\r\n\r\n for (const line of lines) {\r\n if (line.startsWith('event: ')) {\r\n currentEvent = line.slice(7).trim();\r\n continue;\r\n }\r\n\r\n if (!line.startsWith('data: ')) continue;\r\n const raw = line.slice(6).trim();\r\n if (raw === '[DONE]') {\r\n controller.enqueue({ type: 'done' });\r\n controller.close();\r\n return;\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(raw);\r\n const eventType = currentEvent || parsed.type;\r\n\r\n if (eventType === 'delta' || (!eventType && parsed.content != null)) {\r\n controller.enqueue({\r\n type: 'delta',\r\n content: parsed.content ?? parsed.text ?? parsed.delta?.content ?? '',\r\n });\r\n } else if (eventType === 'patch') {\r\n controller.enqueue({ type: 'patch', patch: parsed });\r\n } else if (eventType === 'done') {\r\n controller.enqueue({ type: 'done', usage: parsed.usage });\r\n controller.close();\r\n return;\r\n } else if (eventType === 'error') {\r\n controller.enqueue({ type: 'error', message: parsed.message || 'Unknown error' });\r\n }\r\n } catch {\r\n // skip non-JSON lines\r\n }\r\n\r\n currentEvent = '';\r\n }\r\n }\r\n },\r\n cancel() {\r\n reader.cancel();\r\n },\r\n });\r\n}\r\n\r\nexport function createSSEAdapter(\r\n baseUrl: string,\r\n headers?: Record<string, string>,\r\n): AIServiceAdapter {\r\n let controller: AbortController | null = null;\r\n\r\n return {\r\n async request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>> {\r\n controller = new AbortController();\r\n\r\n const url = baseUrl.replace(/\\/+$/, '') + '/ai/completion';\r\n const resp = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream', ...headers },\r\n body: JSON.stringify(req),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!resp.ok) {\r\n throw new Error(`AI service error: ${resp.status} ${resp.statusText}`);\r\n }\r\n\r\n if (!resp.body) {\r\n throw new Error('AI service returned no body');\r\n }\r\n\r\n return parseSSEStream(resp.body);\r\n },\r\n\r\n abort() {\r\n controller?.abort();\r\n controller = null;\r\n },\r\n };\r\n}\r\n\r\n// ── Chat Session API (REST + SSE) ──\r\n\r\nexport function createChatSessionAPI(\r\n baseUrl: string,\r\n headers?: Record<string, string>,\r\n): ChatSessionAPI {\r\n let controller: AbortController | null = null;\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n\r\n async function json<T>(url: string, init?: RequestInit): Promise<T> {\r\n const resp = await fetch(url, {\r\n ...init,\r\n headers: { 'Content-Type': 'application/json', ...headers, ...init?.headers },\r\n });\r\n if (!resp.ok) throw new Error(`Chat API error: ${resp.status} ${resp.statusText}`);\r\n const body = await resp.json();\r\n return body.data ?? body;\r\n }\r\n\r\n return {\r\n async createSession(patentId, title, language) {\r\n return json<ChatSession>(`${base}/api/v1/chat/sessions`, {\r\n method: 'POST',\r\n body: JSON.stringify({ patentId, title, language }),\r\n });\r\n },\r\n\r\n async listSessions(patentId, page = 1, pageSize = 20) {\r\n const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\r\n if (patentId) params.set('patentId', patentId);\r\n return json(`${base}/api/v1/chat/sessions?${params}`);\r\n },\r\n\r\n async getMessages(sessionId, page = 1, pageSize = 50) {\r\n const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\r\n return json(`${base}/api/v1/chat/sessions/${sessionId}/messages?${params}`);\r\n },\r\n\r\n async deleteSession(sessionId) {\r\n await fetch(`${base}/api/v1/chat/sessions/${sessionId}`, {\r\n method: 'DELETE',\r\n headers: { ...headers },\r\n });\r\n },\r\n\r\n async sendMessage(sessionId, req) {\r\n return json<ChatMessageResponse>(`${base}/api/v1/chat/sessions/${sessionId}/messages`, {\r\n method: 'POST',\r\n body: JSON.stringify(req),\r\n });\r\n },\r\n\r\n async subscribeStream(sessionId, messageId) {\r\n controller = new AbortController();\r\n const url = `${base}/api/v1/chat/sessions/${sessionId}/stream?messageId=${messageId}`;\r\n const resp = await fetch(url, {\r\n headers: { Accept: 'text/event-stream', ...headers },\r\n signal: controller.signal,\r\n });\r\n if (!resp.ok) throw new Error(`Chat stream error: ${resp.status} ${resp.statusText}`);\r\n if (!resp.body) throw new Error('Chat stream returned no body');\r\n return parseSSEStream(resp.body);\r\n },\r\n\r\n abort() {\r\n controller?.abort();\r\n controller = null;\r\n },\r\n };\r\n}\r\n","import React, { forwardRef, useImperativeHandle, useRef, useCallback } from 'react';\r\nimport { JSONContent, Editor } from '@tiptap/react';\r\nimport { EditorView } from './components/EditorView';\r\nimport { useEditorStore, EditorLanguage } from './store/editorStore';\r\nimport { createCommandExecutor } from './editor/core/EditorCore';\r\nimport { createSSEAdapter, createChatSessionAPI } from './editor/ai/aiService';\r\nimport { buildPatentDocument } from './editor/plugins/patent/patentDocTemplate';\r\nimport type { PatentType } from './editor/plugins/patent/patentDocTemplate';\r\nimport type { AIServiceAdapter, ChatSessionAPI } from './editor/ai/aiService';\r\nimport './styles/editor.css';\r\n\r\nexport interface PatentEditorProps {\r\n initialContent?: JSONContent;\r\n patentType?: PatentType;\r\n onChange?: (content: JSONContent) => void;\r\n className?: string;\r\n readOnly?: boolean;\r\n /** Disable content editing without hiding toolbar/UI (unlike readOnly). */\r\n editable?: boolean;\r\n language?: EditorLanguage;\r\n aiService?: AIServiceAdapter;\r\n chatSessionAPI?: ChatSessionAPI;\r\n aiBaseUrl?: string;\r\n aiHeaders?: Record<string, string>;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport interface PatentEditorRef {\r\n getContent: () => JSONContent | null;\r\n setContent: (content: JSONContent) => void;\r\n getEditor: () => any;\r\n execCommand: (name: string, payload?: unknown) => Promise<unknown>;\r\n focus: () => void;\r\n}\r\n\r\nexport const PatentEditor = forwardRef<PatentEditorRef, PatentEditorProps>(\r\n ({ initialContent, patentType, onChange, className, readOnly = false, editable = true, language, aiService, chatSessionAPI, aiBaseUrl, aiHeaders, onSelectionOptimize }, ref) => {\r\n const { setEditorLanguage, setAIService, setChatSessionAPI } = useEditorStore();\r\n const localEditorRef = useRef<Editor | null>(null);\r\n\r\n const handleEditorReady = useCallback((editor: Editor) => {\r\n localEditorRef.current = editor;\r\n }, []);\r\n\r\n const resolvedContent = React.useMemo(() => {\r\n if (initialContent) return initialContent;\r\n if (patentType) return buildPatentDocument(patentType);\r\n return undefined;\r\n }, [initialContent, patentType]);\r\n\r\n React.useEffect(() => {\r\n if (language) setEditorLanguage(language);\r\n }, [language, setEditorLanguage]);\r\n\r\n React.useEffect(() => {\r\n if (aiService) {\r\n setAIService(aiService);\r\n } else if (aiBaseUrl) {\r\n setAIService(createSSEAdapter(aiBaseUrl, aiHeaders));\r\n }\r\n }, [aiService, aiBaseUrl, aiHeaders, setAIService]);\r\n\r\n React.useEffect(() => {\r\n if (chatSessionAPI) {\r\n setChatSessionAPI(chatSessionAPI);\r\n } else if (aiBaseUrl) {\r\n setChatSessionAPI(createChatSessionAPI(aiBaseUrl, aiHeaders));\r\n }\r\n }, [chatSessionAPI, aiBaseUrl, aiHeaders, setChatSessionAPI]);\r\n\r\n useImperativeHandle(ref, () => ({\r\n getContent: () => localEditorRef.current?.getJSON() ?? null,\r\n setContent: (content: JSONContent) => {\r\n localEditorRef.current?.commands.setContent(content);\r\n },\r\n getEditor: () => localEditorRef.current,\r\n execCommand: async (name: string, payload?: unknown) => {\r\n if (!localEditorRef.current) return null;\r\n const executor = createCommandExecutor(localEditorRef.current);\r\n return executor.execCommand(name, payload);\r\n },\r\n focus: () => { localEditorRef.current?.commands.focus(); },\r\n }));\r\n\r\n return (\r\n <EditorView\r\n initialContent={resolvedContent}\r\n onChange={onChange}\r\n onEditorReady={handleEditorReady}\r\n className={className}\r\n readOnly={readOnly}\r\n editable={editable}\r\n onSelectionOptimize={onSelectionOptimize}\r\n />\r\n );\r\n }\r\n);\r\n\r\nPatentEditor.displayName = 'PatentEditor';\r\n","import { Editor } from '@tiptap/react';\r\n\r\nexport type StreamWriteMode = 'cursor' | 'section';\r\n\r\nexport interface StreamWriterOptions {\r\n mode: StreamWriteMode;\r\n targetSectionPos?: number;\r\n onStart?: () => void;\r\n onChunk?: (text: string) => void;\r\n onComplete?: () => void;\r\n onError?: (error: Error) => void;\r\n onAbort?: () => void;\r\n}\r\n\r\nexport interface StreamWriterHandle {\r\n abort: () => void;\r\n isRunning: () => boolean;\r\n}\r\n\r\nexport function createStreamWriter(\r\n editor: Editor,\r\n options: StreamWriterOptions\r\n): StreamWriterHandle {\r\n let aborted = false;\r\n let running = false;\r\n\r\n return {\r\n abort: () => {\r\n aborted = true;\r\n if (running) {\r\n running = false;\r\n options.onAbort?.();\r\n }\r\n },\r\n isRunning: () => running,\r\n };\r\n}\r\n\r\nexport async function writeStream(\r\n editor: Editor,\r\n reader: ReadableStreamDefaultReader<string>,\r\n options: StreamWriterOptions\r\n): Promise<void> {\r\n let aborted = false;\r\n const abortController = { abort: () => { aborted = true; } };\r\n\r\n options.onStart?.();\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n clearSectionContent(editor, options.targetSectionPos);\r\n }\r\n\r\n try {\r\n let insertPos = getInsertPosition(editor, options);\r\n\r\n while (true) {\r\n if (aborted) {\r\n options.onAbort?.();\r\n return;\r\n }\r\n\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n if (!value) continue;\r\n\r\n options.onChunk?.(value);\r\n\r\n const tr = editor.state.tr.insertText(value, insertPos);\r\n editor.view.dispatch(tr);\r\n // 用 bias=1 将旧插入点映射到新文档中插入内容之后的位置\r\n // 这样无论 \\n 是否触发段落分割,position 都正确\r\n insertPos = tr.mapping.map(insertPos, 1);\r\n }\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n\r\n options.onComplete?.();\r\n } catch (err) {\r\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\r\n }\r\n}\r\n\r\nexport async function writeStreamFromSSE(\r\n editor: Editor,\r\n url: string,\r\n body: object,\r\n options: StreamWriterOptions\r\n): Promise<{ abort: () => void }> {\r\n const abortController = new AbortController();\r\n\r\n options.onStart?.();\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n clearSectionContent(editor, options.targetSectionPos);\r\n }\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n signal: abortController.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) throw new Error('No response body');\r\n\r\n const decoder = new TextDecoder();\r\n let insertPos = getInsertPosition(editor, options);\r\n let buffer = '';\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (!line.startsWith('data: ')) continue;\r\n const data = line.slice(6).trim();\r\n if (data === '[DONE]') {\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n options.onComplete?.();\r\n return { abort: () => abortController.abort() };\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(data);\r\n const text = parsed.content || parsed.text || parsed.delta?.content || '';\r\n if (!text) continue;\r\n\r\n options.onChunk?.(text);\r\n const ssetr = editor.state.tr.insertText(text, insertPos);\r\n editor.view.dispatch(ssetr);\r\n insertPos = ssetr.mapping.map(insertPos, 1);\r\n } catch {\r\n // skip non-JSON lines\r\n }\r\n }\r\n }\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n options.onComplete?.();\r\n } catch (err) {\r\n if ((err as Error).name === 'AbortError') {\r\n options.onAbort?.();\r\n } else {\r\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\r\n }\r\n }\r\n\r\n return { abort: () => abortController.abort() };\r\n}\r\n\r\nfunction getInsertPosition(editor: Editor, options: StreamWriterOptions): number {\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n const node = editor.state.doc.nodeAt(options.targetSectionPos);\r\n if (node && node.type.name === 'patent_section') {\r\n return options.targetSectionPos + 2;\r\n }\r\n }\r\n return editor.state.selection.from;\r\n}\r\n\r\nfunction clearSectionContent(editor: Editor, sectionPos: number): void {\r\n const node = editor.state.doc.nodeAt(sectionPos);\r\n if (!node || node.type.name !== 'patent_section') return;\r\n\r\n const contentStart = sectionPos + 1;\r\n const contentEnd = sectionPos + node.nodeSize - 1;\r\n\r\n if (contentEnd > contentStart + 2) {\r\n const tr = editor.state.tr;\r\n const paragraph = editor.state.schema.nodes.paragraph.create();\r\n tr.replaceWith(contentStart, contentEnd, paragraph);\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n }\r\n}\r\n\r\n/**\r\n * Remove empty paragraph nodes from a patent_section after streaming.\r\n * ProseMirror's insertText splits on every \\n, so \\n\\n produces empty paragraphs\r\n * that need to be cleaned up. Always keeps at least one paragraph in the section.\r\n */\r\nfunction removeEmptyParagraphs(editor: Editor, sectionPos: number): void {\r\n const node = editor.state.doc.nodeAt(sectionPos);\r\n if (!node || node.type.name !== 'patent_section') return;\r\n\r\n const tr = editor.state.tr;\r\n const toDelete: { from: number; to: number }[] = [];\r\n\r\n let offset = sectionPos + 1;\r\n let totalChildren = 0;\r\n node.forEach((child) => { totalChildren++; });\r\n\r\n let nonEmptyCount = 0;\r\n node.forEach((child) => {\r\n if (child.type.name === 'paragraph' && child.textContent.trim().length > 0) {\r\n nonEmptyCount++;\r\n }\r\n });\r\n\r\n offset = sectionPos + 1;\r\n node.forEach((child) => {\r\n const childStart = offset;\r\n const childEnd = offset + child.nodeSize;\r\n if (\r\n child.type.name === 'paragraph' &&\r\n child.textContent.trim().length === 0 &&\r\n (nonEmptyCount > 0 || toDelete.length < totalChildren - 1)\r\n ) {\r\n toDelete.push({ from: childStart, to: childEnd });\r\n }\r\n offset = childEnd;\r\n });\r\n\r\n if (toDelete.length === 0) return;\r\n\r\n for (let i = toDelete.length - 1; i >= 0; i--) {\r\n tr.delete(toDelete[i].from, toDelete[i].to);\r\n }\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n}\r\n","/**\r\n * Mock AI Service — 用于演示 AI 流式写入 和 Chat 会话(含 target 化 patch)\r\n *\r\n * 模块 1: AIServiceAdapter — generate action(流式章节生成)\r\n * 模块 2: ChatSessionAPI — 会话制对话(含 session CRUD + 两步式 SSE)\r\n */\r\n\r\nimport type {\r\n AIServiceAdapter, AIRequest, AIResponseEvent,\r\n ChatSessionAPI, ChatSession, ChatMessage,\r\n ChatMessageRequest, ChatMessageResponse, ChatReference,\r\n} from './aiService';\r\n\r\n/* ═══════════════════ 各章节 Mock 文本 ═══════════════════ */\r\n\r\nconst SECTION_TEXTS: Record<string, { zh: string; en: string }> = {\r\n technical_field: {\r\n zh: '本发明涉及航天器自主导航与控制技术领域,具体涉及一种基于多传感器融合的航天器自主避障控制方法、系统、电子设备及计算机可读存储介质。该方法综合利用激光雷达、红外传感器和星敏感器的探测数据,通过实时环境感知与路径规划算法,实现航天器在复杂空间环境中的自主安全避障机动。',\r\n en: 'The present invention relates to the field of autonomous navigation and control technology for spacecraft, and specifically to a method, system, electronic device, and computer-readable storage medium for autonomous obstacle avoidance control of spacecraft based on multi-sensor fusion.',\r\n },\r\n background_art: {\r\n zh: '随着人类空间活动日益频繁,近地轨道空间碎片数量持续增长,对在轨航天器的安全运行构成了严重威胁。传统的空间碎片避碰方法主要依赖地面监测站的跟踪数据和人工决策,存在响应时间长、决策链路复杂、无法应对突发碰撞风险等缺点。\\n\\n现有技术中,部分航天器采用预设轨道机动策略进行避碰,但该方法对碎片轨道预报精度要求极高,且无法适应非合作目标的不确定运动。也有研究提出基于人工势场法的避障方案,但存在局部最优陷阱问题,在密集碎片环境中表现不佳。\\n\\n因此,亟需一种能够实现航天器自主感知、自主决策、自主机动的避障控制方法,以提高航天器的在轨生存能力。',\r\n en: 'With the increasing frequency of human space activities, the number of space debris in low Earth orbit continues to grow, posing a serious threat to the safe operation of on-orbit spacecraft. Traditional space debris collision avoidance methods mainly rely on tracking data from ground monitoring stations and manual decision-making.',\r\n },\r\n summary: {\r\n zh: '为解决上述技术问题,本发明提供了一种航天器自主避障控制方法,包括以下步骤:\\n\\n步骤一:通过多传感器融合模块实时获取航天器周围空间环境信息,构建三维障碍物地图;\\n\\n步骤二:基于改进的快速搜索随机树(RRT*)算法进行全局路径规划,生成无碰撞参考轨迹;\\n\\n步骤三:采用模型预测控制(MPC)策略进行局部路径跟踪与实时避障,在满足燃料约束和姿态约束的条件下,计算最优推力控制量;\\n\\n步骤四:通过安全验证模块对控制指令进行合规性检查,确保机动轨迹不会与已知空间目标产生二次碰撞风险。\\n\\n本发明的有益效果在于:显著缩短碰撞告警到规避机动的响应时间,从传统方法的数小时级缩短至分钟级;提高避障成功率至99.7%以上;降低单次避障机动的燃料消耗约35%。',\r\n en: 'To solve the above technical problems, the present invention provides a method for autonomous obstacle avoidance control of spacecraft, comprising the following steps...',\r\n },\r\n claims: {\r\n zh: '1. 一种航天器自主避障控制方法,其特征在于,包括以下步骤:\\n通过多传感器融合模块实时获取航天器周围空间环境信息,构建三维障碍物分布地图;\\n基于改进的快速搜索随机树算法进行全局路径规划,生成无碰撞参考轨迹;\\n采用模型预测控制策略进行局部路径跟踪与实时避障控制。\\n\\n2. 根据权利要求1所述的方法,其特征在于,所述多传感器融合模块包括激光雷达传感器、红外传感器和星敏感器,采用扩展卡尔曼滤波算法对多源传感器数据进行融合处理。\\n\\n3. 根据权利要求1所述的方法,其特征在于,所述改进的快速搜索随机树算法引入了自适应采样策略和路径平滑优化机制。',\r\n en: '1. A method for autonomous obstacle avoidance control of a spacecraft, characterized in that it comprises the following steps...',\r\n },\r\n abstract: {\r\n zh: '本发明公开了一种航天器自主避障控制方法、系统、电子设备及存储介质。该方法通过多传感器融合模块实时感知空间环境,基于改进RRT*算法规划全局无碰撞路径,采用MPC策略实现局部实时避障控制。本发明显著缩短了碰撞告警响应时间,提高了避障成功率,降低了燃料消耗。',\r\n en: 'The present invention discloses a method, system, electronic device and storage medium for autonomous obstacle avoidance control of a spacecraft.',\r\n },\r\n drawing_description: {\r\n zh: '图1为本发明实施例提供的航天器自主避障控制方法的流程示意图;\\n\\n图2为本发明实施例提供的多传感器融合模块的结构框图;\\n\\n图3为本发明实施例提供的改进RRT*算法的路径规划效果示意图;\\n\\n图4为本发明实施例提供的模型预测控制策略的控制框图;\\n\\n图5为本发明实施例提供的航天器自主避障控制系统的架构示意图。',\r\n en: 'FIG. 1 is a schematic flow chart of the autonomous obstacle avoidance control method for a spacecraft provided by an embodiment of the present invention.',\r\n },\r\n detailed_description: {\r\n zh: '下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述。\\n\\n实施例一:\\n\\n如图1所示,本发明提供的航天器自主避障控制方法包括以下步骤:\\n\\nS101:多传感器数据采集与融合。航天器搭载的激光雷达以10Hz频率扫描前方120°锥形区域,红外传感器以5Hz频率探测周围热辐射目标,星敏感器以1Hz频率提供高精度姿态信息。采用扩展卡尔曼滤波(EKF)算法对上述多源数据进行时间同步和空间配准,生成统一坐标系下的三维障碍物分布地图。\\n\\nS102:全局路径规划。基于步骤S101获得的障碍物地图,采用改进的RRT*算法进行路径规划。改进之处在于:引入目标导向采样策略,以概率p=0.3直接向目标点采样,加速收敛;引入路径平滑机制,对生成路径进行B样条曲线拟合,确保路径连续可微。\\n\\nS103:局部实时避障控制。采用模型预测控制(MPC)策略,以步骤S102的规划路径为参考,在预测时域N=20内求解带约束的最优控制问题。约束条件包括:推力幅值约束|F|≤Fmax、姿态角速度约束|ω|≤ωmax、最小安全距离约束d≥dmin。\\n\\nS104:安全验证。对计算得到的控制指令进行轨迹传播仿真,验证机动后轨迹在未来72小时内不会与TLE目录中的已知空间目标产生碰撞风险(miss distance > 1km)。',\r\n en: 'The technical solution of the embodiments of the present invention will be described clearly and completely below with reference to the drawings.',\r\n },\r\n};\r\n\r\n/* ═══════════════════ Chat Mock 回复 ═══════════════════ */\r\n\r\nconst CHAT_RESPONSES: Record<string, { zh: string; en: string }> = {\r\n 'help-draft': {\r\n zh: '当然可以帮你撰写技术方案!请先描述以下信息:\\n\\n1. **技术领域**:你的发明属于哪个技术领域?\\n2. **技术问题**:现有技术存在什么缺陷或不足?\\n3. **核心创新**:你的发明的关键创新点是什么?\\n4. **实施方式**:大致的技术实现路径是怎样的?\\n\\n提供这些信息后,我可以帮你生成完整的技术方案初稿。',\r\n en: 'Sure, I can help draft the technical solution! Please describe the following...',\r\n },\r\n review: {\r\n zh: '好的,我将对当前专利文档进行全面审查,主要检查以下方面:\\n\\n**格式规范性**\\n- 各章节是否完整\\n- 权利要求书格式是否符合要求\\n- 摘要字数是否在50-300字范围\\n\\n**内容质量**\\n- 技术方案是否清楚完整\\n- 权利要求保护范围是否合理\\n- 说明书是否充分公开\\n\\n**一致性检查**\\n- 术语使用是否统一\\n- 附图标记是否一致\\n- 权利要求与说明书是否对应\\n\\n请稍候,我正在分析文档内容...',\r\n en: 'I will review the current patent document comprehensively...',\r\n },\r\n claims: {\r\n zh: '针对当前权利要求书,我有以下优化建议:\\n\\n1. **独立权利要求1** 中的技术特征可以进一步上位化,扩大保护范围。建议将\"激光雷达\"上位为\"距离探测传感器\"\\n\\n2. **从属权利要求** 数量偏少,建议补充:\\n - 传感器融合算法的具体实现方式\\n - 路径规划的采样策略参数范围\\n - MPC控制器的预测时域和约束条件\\n\\n3. 建议增加 **方法+系统** 双重保护的权利要求布局\\n\\n需要我帮你自动生成优化后的权利要求书吗?',\r\n en: 'For the current claims, I have the following optimization suggestions...',\r\n },\r\n default: {\r\n zh: '这是一个很好的问题。作为AI专利撰写助手,我可以帮助你:\\n\\n- **生成章节草稿**:基于已有内容和你的描述,自动撰写各章节\\n- **优化表达**:使文本更符合专利撰写规范\\n- **审查文档**:检查格式规范性和内容完整性\\n- **权利要求优化**:调整保护范围和层次布局\\n\\n你可以选中文档中的文字使用浮动菜单的AI操作,或者在左侧面板点击章节的\"AI生成\"按钮来体验这些功能。',\r\n en: 'That is a great question. As an AI patent writing assistant, I can help you with...',\r\n },\r\n};\r\n\r\n/* ═══════════════════ Helper: 延迟 ═══════════════════ */\r\n\r\nconst delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\r\n\r\n/* ═══════════════════ 创建 Mock 流 ═══════════════════ */\r\n\r\nfunction createMockStream(events: AIResponseEvent[], chunkDelayMs = 30): ReadableStream<AIResponseEvent> {\r\n let cancelled = false;\r\n return new ReadableStream<AIResponseEvent>({\r\n async pull(controller) {\r\n for (const evt of events) {\r\n if (cancelled) {\r\n controller.close();\r\n return;\r\n }\r\n controller.enqueue(evt);\r\n if (evt.type === 'delta') {\r\n await delay(chunkDelayMs);\r\n }\r\n }\r\n controller.close();\r\n },\r\n cancel() {\r\n cancelled = true;\r\n },\r\n });\r\n}\r\n\r\n/* ═══════════════════ 场景 1: 流式写入 ═══════════════════ */\r\n\r\nfunction buildStreamingEvents(text: string): AIResponseEvent[] {\r\n const events: AIResponseEvent[] = [];\r\n // 按字符逐个发送(中文按字,英文按词+空格分组提高效率)\r\n const chunks = splitTextIntoChunks(text, 3);\r\n for (const chunk of chunks) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n events.push({ type: 'done', usage: { tokens: text.length * 2 } });\r\n return events;\r\n}\r\n\r\nfunction splitTextIntoChunks(text: string, chunkSize: number): string[] {\r\n const chunks: string[] = [];\r\n for (let i = 0; i < text.length; i += chunkSize) {\r\n chunks.push(text.slice(i, i + chunkSize));\r\n }\r\n return chunks;\r\n}\r\n\r\n/* ═══════════════════ Chat 回复构建(含 target 化 patch) ═══════════════════ */\r\n\r\nfunction buildChatStreamEvents(\r\n userContent: string,\r\n refs: ChatReference[],\r\n language: string,\r\n): AIResponseEvent[] {\r\n const zh = language === 'zh';\r\n const events: AIResponseEvent[] = [];\r\n\r\n // 匹配预设回复\r\n let responseText: string;\r\n if (userContent.includes('技术方案') || userContent.includes('draft')) {\r\n responseText = CHAT_RESPONSES['help-draft'][zh ? 'zh' : 'en'];\r\n } else if (userContent.includes('审查') || userContent.includes('review') || userContent.includes('Review')) {\r\n responseText = CHAT_RESPONSES['review'][zh ? 'zh' : 'en'];\r\n } else if (userContent.includes('权利要求') || userContent.includes('claims') || userContent.includes('Optimize')) {\r\n responseText = CHAT_RESPONSES['claims'][zh ? 'zh' : 'en'];\r\n } else {\r\n responseText = CHAT_RESPONSES['default'][zh ? 'zh' : 'en'];\r\n }\r\n\r\n // 如果有引用,返回 target 化 patch\r\n if (refs.length > 0) {\r\n // 先返回分析文字\r\n const analysis = zh\r\n ? `正在分析引用的 ${refs.length} 段文本并生成优化建议...\\n\\n`\r\n : `Analyzing ${refs.length} referenced text(s) and generating suggestions...\\n\\n`;\r\n for (const chunk of splitTextIntoChunks(analysis, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n for (const chunk of splitTextIntoChunks(responseText, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n\r\n // 为每个引用生成一个 target 化的 patch\r\n for (let i = 0; i < refs.length; i++) {\r\n const ref = refs[i];\r\n const original = ref.text;\r\n let optimized: string;\r\n if (zh) {\r\n optimized = original\r\n .replace(/一种/g, '一种基于本发明的')\r\n .replace(/方法/g, '技术方案')\r\n .replace(/包括/g, '具体包括');\r\n if (optimized === original) {\r\n optimized = `根据本发明优选实施例,${original}`;\r\n }\r\n } else {\r\n optimized = `According to a preferred embodiment, ${original.charAt(0).toLowerCase()}${original.slice(1)}`;\r\n }\r\n\r\n // 优先使用 ref target(精确 from/to),避免 search 匹配歧义\r\n // 仅当 ref 没有位置信息时才降级为 section+search(使用完整原文)\r\n if (ref.from != null && ref.to != null) {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'ref', refIndex: i },\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n } else if (ref.source) {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'section', sectionType: ref.source as any },\r\n search: original,\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n } else {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'search', searchText: original },\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n }\r\n }\r\n } else {\r\n // 纯文字对话回复\r\n for (const chunk of splitTextIntoChunks(responseText, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n }\r\n\r\n events.push({ type: 'done', usage: { tokens: responseText.length * 2 } });\r\n return events;\r\n}\r\n\r\n/* ═══════════════════ Mock AI Adapter (generate only) ═══════════════════ */\r\n\r\nexport function createMockAIService(): AIServiceAdapter {\r\n let abortController: AbortController | null = null;\r\n\r\n return {\r\n async request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>> {\r\n abortController = new AbortController();\r\n\r\n // 模拟网络延迟\r\n await delay(300);\r\n\r\n if (abortController.signal.aborted) {\r\n throw new DOMException('Aborted', 'AbortError');\r\n }\r\n\r\n const lang = req.language === 'zh' ? 'zh' : 'en';\r\n const sectionKey = req.sectionType || 'technical_field';\r\n const sectionText = SECTION_TEXTS[sectionKey]?.[lang]\r\n || SECTION_TEXTS['technical_field'][lang];\r\n\r\n let fullText = sectionText;\r\n if (req.instruction) {\r\n const prefix = lang === 'zh'\r\n ? `[基于指令\"${req.instruction}\"生成]\\n\\n`\r\n : `[Generated based on instruction \"${req.instruction}\"]\\n\\n`;\r\n fullText = prefix + sectionText;\r\n }\r\n\r\n const events = buildStreamingEvents(fullText);\r\n return createMockStream(events, 25);\r\n },\r\n\r\n abort() {\r\n abortController?.abort();\r\n abortController = null;\r\n },\r\n };\r\n}\r\n\r\n/* ═══════════════════ Mock Chat Session API ═══════════════════ */\r\n\r\ninterface MockSession {\r\n session: ChatSession;\r\n messages: ChatMessage[];\r\n}\r\n\r\nexport function createMockChatSessionAPI(): ChatSessionAPI {\r\n const sessions = new Map<string, MockSession>();\r\n let abortController: AbortController | null = null;\r\n // pending stream for the latest message\r\n let pendingStream: { messageId: string; events: AIResponseEvent[] } | null = null;\r\n\r\n return {\r\n async createSession(patentId, title, language) {\r\n await delay(100);\r\n const sessionId = `sess_${Date.now()}`;\r\n const session: ChatSession = {\r\n sessionId,\r\n patentId: patentId || undefined,\r\n title: title || (language === 'zh' ? '新对话' : 'New Chat'),\r\n messageCount: 0,\r\n createdAt: new Date().toISOString(),\r\n updatedAt: new Date().toISOString(),\r\n };\r\n sessions.set(sessionId, { session, messages: [] });\r\n return session;\r\n },\r\n\r\n async listSessions() {\r\n await delay(50);\r\n const items = Array.from(sessions.values()).map((s) => s.session);\r\n return { total: items.length, items };\r\n },\r\n\r\n async getMessages(sessionId) {\r\n await delay(50);\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n return { total: s.messages.length, items: s.messages };\r\n },\r\n\r\n async deleteSession(sessionId) {\r\n await delay(50);\r\n sessions.delete(sessionId);\r\n },\r\n\r\n async sendMessage(sessionId, req: ChatMessageRequest): Promise<ChatMessageResponse> {\r\n await delay(150);\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n\r\n const messageId = `msg_${Date.now()}`;\r\n\r\n // Store user message\r\n s.messages.push({\r\n messageId,\r\n role: 'user',\r\n content: req.content,\r\n references: req.references,\r\n status: 'done',\r\n createdAt: new Date().toISOString(),\r\n });\r\n s.session.messageCount = s.messages.length;\r\n s.session.lastMessage = req.content;\r\n s.session.updatedAt = new Date().toISOString();\r\n\r\n // Build events for the response stream\r\n const events = buildChatStreamEvents(\r\n req.content,\r\n req.references || [],\r\n req.language,\r\n );\r\n pendingStream = { messageId, events };\r\n\r\n return { messageId, sessionId, status: 'processing' };\r\n },\r\n\r\n async subscribeStream(sessionId, messageId) {\r\n abortController = new AbortController();\r\n await delay(100);\r\n\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n\r\n if (!pendingStream || pendingStream.messageId !== messageId) {\r\n // Already completed or not found — return done\r\n return createMockStream([{ type: 'done' }]);\r\n }\r\n\r\n const events = pendingStream.events;\r\n pendingStream = null;\r\n\r\n // After stream, store the assistant message\r\n const stream = createMockStream(events, 18);\r\n\r\n // Collect assistant content for storage (fire-and-forget)\r\n const asstId = `${messageId}_a`;\r\n let content = '';\r\n for (const evt of events) {\r\n if (evt.type === 'delta') content += evt.content;\r\n }\r\n s.messages.push({\r\n messageId: asstId,\r\n role: 'assistant',\r\n content,\r\n status: 'done',\r\n createdAt: new Date().toISOString(),\r\n });\r\n s.session.messageCount = s.messages.length;\r\n s.session.updatedAt = new Date().toISOString();\r\n\r\n return stream;\r\n },\r\n\r\n abort() {\r\n abortController?.abort();\r\n abortController = null;\r\n },\r\n };\r\n}\r\n","/**\r\n * Post-process streamed text content in a claims section,\r\n * converting plain text into proper `claim` nodes.\r\n *\r\n * The AI streams plain text like:\r\n * \"1. 一种方法,其特征在于...\\n\\n2. 根据权利要求1...\"\r\n *\r\n * This function parses that text, splits it into individual claims,\r\n * and replaces the section content with structured `claim` nodes.\r\n */\r\n\r\nimport { Editor } from '@tiptap/react';\r\n\r\ninterface ParsedClaim {\r\n number: number;\r\n text: string;\r\n dependsOn: number[];\r\n}\r\n\r\n/**\r\n * Parse plain text into individual claims.\r\n * Splits by the pattern \"N. \" or \"N、\" at the start of a line.\r\n */\r\nexport function parseClaimsText(text: string): ParsedClaim[] {\r\n const claims: ParsedClaim[] = [];\r\n\r\n // Normalize line breaks\r\n const normalized = text.replace(/\\r\\n/g, '\\n').trim();\r\n if (!normalized) return claims;\r\n\r\n // Split by claim number pattern: \"1. \", \"2. \", \"10. \" etc. at line start\r\n // Also handle \"1、\" Chinese-style numbering\r\n const claimPattern = /(?:^|\\n)\\s*(\\d+)\\s*[.、]\\s*/g;\r\n const matches: { index: number; number: number; matchLength: number }[] = [];\r\n\r\n let match: RegExpExecArray | null;\r\n while ((match = claimPattern.exec(normalized)) !== null) {\r\n matches.push({\r\n index: match.index,\r\n number: parseInt(match[1], 10),\r\n matchLength: match[0].length,\r\n });\r\n }\r\n\r\n if (matches.length === 0) {\r\n // No claim pattern found — treat as a single claim\r\n claims.push({ number: 1, text: normalized, dependsOn: [] });\r\n return claims;\r\n }\r\n\r\n for (let i = 0; i < matches.length; i++) {\r\n const start = matches[i].index + matches[i].matchLength;\r\n const end = i + 1 < matches.length ? matches[i + 1].index : normalized.length;\r\n const claimText = normalized.slice(start, end).trim();\r\n const claimNumber = matches[i].number;\r\n\r\n // Detect dependsOn from text like \"根据权利要求1所述\" or \"根据权利要求1-3\"\r\n const dependsOn = extractDependencies(claimText, claimNumber);\r\n\r\n claims.push({ number: claimNumber, text: claimText, dependsOn });\r\n }\r\n\r\n return claims;\r\n}\r\n\r\n/**\r\n * Extract claim dependencies from claim text.\r\n * Matches patterns like:\r\n * \"根据权利要求1所述\"\r\n * \"根据权利要求1-3所述\"\r\n * \"The method of claim 1\"\r\n * \"The method according to claims 1-3\"\r\n */\r\nfunction extractDependencies(text: string, selfNumber: number): number[] {\r\n const deps: number[] = [];\r\n\r\n // Chinese pattern: 根据权利要求N\r\n const zhPattern = /根据权利要求(\\d+)(?:\\s*[-~至到]\\s*(\\d+))?/g;\r\n let m: RegExpExecArray | null;\r\n while ((m = zhPattern.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n // English pattern: claim(s) N\r\n const enPattern = /claims?\\s+(\\d+)(?:\\s*[-~to]+\\s*(\\d+))?/gi;\r\n while ((m = enPattern.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n return [...new Set(deps)].sort((a, b) => a - b);\r\n}\r\n\r\n/**\r\n * Create a unique claim ID.\r\n */\r\nfunction createClaimId(): string {\r\n return `claim_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\r\n}\r\n\r\n/**\r\n * Post-process a claims section: replace streamed plain text with proper claim nodes.\r\n *\r\n * @param editor - The Tiptap editor instance\r\n * @param sectionPos - Position of the patent_section node (sectionType === 'claims')\r\n */\r\nexport function postProcessClaimsSection(editor: Editor, sectionPos: number): boolean {\r\n const sectionNode = editor.state.doc.nodeAt(sectionPos);\r\n if (!sectionNode || sectionNode.type.name !== 'patent_section') return false;\r\n if (sectionNode.attrs.sectionType !== 'claims') return false;\r\n\r\n // Collect text content with block separators preserved\r\n const contentStart = sectionPos + 1;\r\n const contentEnd = sectionPos + sectionNode.nodeSize - 1;\r\n const fullText = editor.state.doc.textBetween(contentStart, contentEnd, '\\n\\n', '\\0');\r\n if (!fullText.trim()) return false;\r\n\r\n // Parse into individual claims\r\n const parsedClaims = parseClaimsText(fullText);\r\n if (parsedClaims.length === 0) return false;\r\n\r\n // Build claim node JSON content\r\n const claimSchema = editor.state.schema.nodes.claim;\r\n if (!claimSchema) {\r\n console.warn('Claim node type not found in schema');\r\n return false;\r\n }\r\n\r\n // Build claim nodes\r\n const claimNodes = parsedClaims.map((parsed) => {\r\n const claimId = createClaimId();\r\n return claimSchema.create(\r\n {\r\n number: parsed.number,\r\n claimId,\r\n dependsOn: parsed.dependsOn,\r\n dependsOnClaimIds: [], // Will be resolved by syncClaimState\r\n },\r\n parsed.text ? editor.state.schema.text(parsed.text) : undefined\r\n );\r\n });\r\n\r\n // Replace section content with claim nodes (reuse contentStart/contentEnd from above)\r\n const { tr } = editor.state;\r\n tr.replaceWith(contentStart, contentEnd, claimNodes);\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Build structured JSONContent for claims from text,\r\n * suitable for use with editor.commands.insertContent() or diff comparison.\r\n */\r\nexport function buildClaimsJSONContent(text: string): Array<{\r\n type: string;\r\n attrs: Record<string, unknown>;\r\n content?: Array<{ type: string; text: string }>;\r\n}> {\r\n const parsedClaims = parseClaimsText(text);\r\n return parsedClaims.map((parsed) => ({\r\n type: 'claim',\r\n attrs: {\r\n number: parsed.number,\r\n claimId: createClaimId(),\r\n dependsOn: parsed.dependsOn,\r\n dependsOnClaimIds: [],\r\n },\r\n content: parsed.text ? [{ type: 'text', text: parsed.text }] : undefined,\r\n }));\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\nimport { diff_match_patch } from 'diff-match-patch';\r\nimport { buildTextMap, textOffsetToDocPos } from './patchDiff';\r\n\r\nconst DIFF_DELETE = -1;\r\nconst DIFF_INSERT = 1;\r\nconst DIFF_EQUAL = 0;\r\n\r\nconst DocDiffPluginKey = new PluginKey('docDiff');\r\n\r\nlet _dmp: InstanceType<typeof diff_match_patch> | null = null;\r\nfunction getDmp() {\r\n if (!_dmp) _dmp = new diff_match_patch();\r\n return _dmp;\r\n}\r\n\r\n/**\r\n * Split an inline range into per-textblock sub-ranges so that\r\n * Decoration.inline never crosses block boundaries.\r\n */\r\nfunction getInlineRanges(\r\n doc: import('@tiptap/pm/model').Node,\r\n from: number,\r\n to: number,\r\n): Array<{ from: number; to: number }> {\r\n const ranges: Array<{ from: number; to: number }> = [];\r\n doc.nodesBetween(from, to, (node, pos) => {\r\n if (node.isTextblock) {\r\n const blockStart = pos + 1;\r\n const blockEnd = pos + node.nodeSize - 1;\r\n const rangeFrom = Math.max(blockStart, from);\r\n const rangeTo = Math.min(blockEnd, to);\r\n if (rangeTo > rangeFrom) {\r\n ranges.push({ from: rangeFrom, to: rangeTo });\r\n }\r\n return false;\r\n }\r\n return true;\r\n });\r\n return ranges;\r\n}\r\n\r\n/**\r\n * Apply document-level diff decorations to a read-only editor.\r\n *\r\n * @param editor - The TipTap editor instance (should be loaded with the \"current\" document)\r\n * @param originalText - Plain text of the original document, extracted using the same\r\n * separator rules as ProseMirror's textBetween (\\0 separators).\r\n */\r\nexport function applyDocDiffDecorations(editor: Editor, originalText: string): void {\r\n const doc = editor.state.doc;\r\n const docSize = doc.content.size;\r\n const { text: currentText, segments } = buildTextMap(editor, 0, docSize);\r\n\r\n const dmp = getDmp();\r\n const diffs = dmp.diff_main(originalText, currentText);\r\n dmp.diff_cleanupEfficiency(diffs);\r\n\r\n const decorations: Decoration[] = [];\r\n let curOffset = 0;\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === DIFF_EQUAL) {\r\n curOffset += text.length;\r\n } else if (op === DIFF_INSERT) {\r\n let i = 0;\r\n while (i < text.length) {\r\n while (i < text.length && text[i] === '\\0') i++;\r\n if (i >= text.length) break;\r\n const runStart = i;\r\n while (i < text.length && text[i] !== '\\0') i++;\r\n\r\n const from = textOffsetToDocPos(segments, curOffset + runStart);\r\n const to = textOffsetToDocPos(segments, curOffset + i);\r\n if (from >= 0 && to >= 0 && to > from) {\r\n for (const range of getInlineRanges(doc, from, to)) {\r\n decorations.push(\r\n Decoration.inline(range.from, range.to, { class: 'patch-diff-insert-inline' }),\r\n );\r\n }\r\n }\r\n }\r\n curOffset += text.length;\r\n } else if (op === DIFF_DELETE) {\r\n const pos = textOffsetToDocPos(segments, curOffset);\r\n if (pos >= 0) {\r\n const display = text.replace(/\\0/g, ' ');\r\n decorations.push(\r\n Decoration.widget(\r\n pos,\r\n () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-delete';\r\n el.textContent = display;\r\n return el;\r\n },\r\n { side: -1 },\r\n ),\r\n );\r\n }\r\n }\r\n }\r\n\r\n const decoSet = DecorationSet.create(doc, decorations);\r\n const plugin = new Plugin({\r\n key: DocDiffPluginKey,\r\n props: {\r\n decorations() {\r\n return decoSet;\r\n },\r\n },\r\n });\r\n\r\n editor.registerPlugin(plugin);\r\n}\r\n\r\n/**\r\n * Remove the doc-diff decoration plugin from the editor.\r\n */\r\nexport function removeDocDiffDecorations(editor: Editor): void {\r\n editor.unregisterPlugin(DocDiffPluginKey);\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport type { EditorLanguage } from '../../../store/editorStore';\r\n\r\nexport type ValidationSeverity = 'error' | 'warning' | 'suggestion';\r\n\r\nexport interface ValidationIssue {\r\n id: string;\r\n severity: ValidationSeverity;\r\n message: string;\r\n sectionType?: string;\r\n pos?: number;\r\n}\r\n\r\nexport function validatePatentDocument(editor: Editor, language: EditorLanguage): ValidationIssue[] {\r\n const issues: ValidationIssue[] = [];\r\n const zh = language === 'zh';\r\n let issueIdx = 0;\r\n const nextId = () => `v_${++issueIdx}`;\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n const text = node.textContent.trim();\r\n if (text.length === 0) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? '专利名称为空' : 'Patent title is empty',\r\n sectionType: 'patent_title',\r\n pos,\r\n });\r\n } else {\r\n const charCount = text.replace(/\\s/g, '').length;\r\n if (charCount > 25 && zh) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'error',\r\n message: `专利名称超过25个汉字(当前${charCount}字)`,\r\n sectionType: 'patent_title',\r\n pos,\r\n });\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const text = node.textContent.trim();\r\n\r\n if (text.length === 0) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh\r\n ? `章节\"${sectionType}\"内容为空`\r\n : `Section \"${sectionType}\" is empty`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n\r\n if (sectionType === 'abstract') {\r\n const charCount = text.replace(/\\s/g, '').length;\r\n if (charCount > 0 && charCount < 50) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? `摘要字数过少(${charCount}字),建议50~300字` : `Abstract too short (${charCount} chars), recommend 50-300`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n if (charCount > 300) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? `摘要字数过多(${charCount}字),建议不超过300字` : `Abstract too long (${charCount} chars), recommend ≤300`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n if (node.type.name === 'claim') {\r\n const body = node.textContent.trim();\r\n if (body.length > 0 && !body.endsWith('。') && !body.endsWith('.')) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh\r\n ? `权利要求${node.attrs.number}末尾应以句号结束`\r\n : `Claim ${node.attrs.number} should end with a period`,\r\n pos,\r\n });\r\n }\r\n }\r\n\r\n return true;\r\n });\r\n\r\n return issues;\r\n}\r\n"],"names":["SlashCommandPluginKey","PluginKey","SlashCommand","Extension","editor","range","props","Suggestion","defaultRightPanel","useEditorStore","create","set","document","selection","editorLanguage","autoSaveStatus","lastSavedAt","status","sectionType","state","abortFn","adapter","api","id","sectionPos","regenerate","tab","ref","msg","SlashMenuList","forwardRef","items","command","selectedIndex","setSelectedIndex","useState","useEffect","selectItem","useCallback","index","item","useImperativeHandle","event","prev","jsx","jsxs","getSlashCommandItems","lang","zh","url","createCommandExecutor","createSlashSuggestion","query","all","lower","component","popup","ReactRenderer","tippy","_a","_b","SearchReplacePluginKey","findMatches","doc","searchTerm","caseSensitive","results","text","term","haystack","pos","idx","charCount","fromPos","toPos","node","nodePos","nodeText","i","SearchReplace","val","r","scrollToSelection","replaceTerm","matches","tr","offset","m","from","to","storage","Plugin","DecorationSet","decorations","className","Decoration","dom","el","DIFF_DELETE","DIFF_INSERT","DIFF_EQUAL","_dmp","getDmp","diff_match_patch","PatchDiffPluginKey","findSectionRange","result","buildTextMap","rangeFrom","rangeTo","segments","separated","nodeStart","sliceFrom","sliceTo","slice","textOffsetToDocPos","seg","searchTextInRange","searchText","skipPositions","searchStart","matchFrom","matchTo","resolvePatchTarget","patchData","refs","patchIndex","alreadyResolved","target","claimedPositions","p","finalRange","narrowed","origText","pendingPatches","patchChangeListeners","onPatchChange","listener","l","notifyPatchChange","getPatches","setPatches","patches","clearPatches","acceptPatch","patchId","patch","isBlockContainerContentRange","nodes","textToParagraphs","mapping","newFrom","newTo","refreshDecorations","rejectPatch","acceptAllPatches","sorted","b","rejectAllPatches","getInlineRanges","ranges","blockStart","blockEnd","computeFineDiff","$from","$to","inst","diffs","equalLen","op","sum","docPos","delEnd","createPatchDiffPlugin","pending","fineDiffs","widgetPos","isLong","schema","content","HardBreak","Node","nodeType","DragDropUX","dropCursor","gapCursor","PatchDiffExtension","baseNodes","Document","Paragraph","Text","Heading","BulletList","OrderedList","ListItem","Blockquote","CodeBlock","HorizontalRule","TaskList","TaskItem","Image","element","attributes","Table","TableRow","TableCell","TableHeader","Placeholder","History","TextAlign","baseMarks","Bold","Italic","Underline","Strike","Code","Superscript","Subscript","Link","TextStyle","Color","Highlight","schemaExtensions","CommandRegistry","__publicField","name","namespace","options","fullName","context","payload","startedAt","useTransaction","rollbackOnFail","snapshot","success","completed","_c","error","_d","commandRegistry","PluginManager","stage","pluginName","a","plugin","commandName","missingDependencies","dependency","extensions","pluginManager","dict","count","number","claimType","getEditorText","language","formatClaimGraphIssueMessage","code","claimNumber","targetNumber","mermaidIdCounter","cleanupOrphans","MermaidNode","HTMLAttributes","mergeAttributes","getPos","currentNode","editMode","viewContainer","preview","viewHint","editContainer","textarea","toolbar","errorMsg","cancelBtn","saveBtn","setNodeAttrs","dispatch","lastRenderedCode","doRender","trimmed","mermaid","renderId","svg","enterEditMode","renderUI","exitEditMode","saveAndRender","e","i18n","hasCode","hasSvg","currentLanguage","unsub","updatedNode","MermaidPlugin","DrawioNode","previewImg","drawioMessageHandler","drawioModal","drawioIframe","modalContent","modalHeader","modalTitle","closeBtn","iframeRef","ev","existingXml","xml","svgData","DrawioPlugin","MathComponent","updateAttributes","selected","mfRef","useRef","isEditing","setIsEditing","isBlock","isEditingRef","latestUpdateAttrs","latestLatex","enterEdit","exitEdit","latex","isCollapsed","mf","onFocusOut","active","onKeyDown","markup","katex","NodeViewWrapper","MathInline","ReactNodeViewRenderer","MathBlock","MathPlugin","findNodeByType","typeName","scope","matched","findNodesByPredicate","predicate","findAncestorNode","depth","findCurrentBlock","getNodeType","buildNodeContent","input","normalizedContent","insertNode","updateNodeAttrs","targetPos","attrs","removeNode","wrapSelection","wrapping","findWrapping","applyTransactionBatch","operations","operation","createClaimId","ClaimNode","empty","claimDepth","findClaimDepth","claimNode","claimEnd","afterClaim","claimCount","n","newClaim","cursorPos","TextSelection","claimStart","newPos","$newPos","label","contentDOM","render","end","$pos","d","_svgGenQueue","_svgGenBusy","_SVG_GEN_TIMEOUT_MS","_IDLE_DESTROY_MS","_sharedIframe","_sharedIframeReady","_currentMsgHandler","_idleTimer","_svgCache","_destroySharedIframe","queueDrawioSvgGen","callback","cached","_processNextSvgGen","timeoutId","done","sendLoad","cleanupMermaidOrphans","FigureNode","mermaidEditMode","drawioEditMode","visual","imgEl","uploadArea","uploadHint","fileInput","replaceBtn","mermaidViewContainer","mermaidPreview","mermaidViewHint","mermaidEditContainer","mermaidEditor","mermaidToolbar","mermaidSaveBtn","mermaidCancelBtn","mermaidErrorMsg","drawioViewContainer","drawioPreviewImg","drawioViewHint","caption","idLabel","captionContent","handleFiles","files","file","reader","enterMermaidEditMode","exitMermaidEditMode","saveMermaidAndRender","enterDrawioEditMode","exitDrawioEditMode","sel","drawioSvgGenQueued","drawioSvgDebounceTimer","drawioSvgRetryTimer","drawioSvgRetries","_MAX_SVG_RETRIES","_SVG_DEBOUNCE_MS","_SVG_RETRY_DELAY_MS","lastRenderedMermaidCode","doInitialMermaidRender","contentType","figureId","imageSrc","mermaidCode","isImage","isMermaid","isDrawio","drawioSvg","drawioXml","mutation","ReferenceNode","fallback","rerender","targetType","resolvedNumber","resolvedFigureId","targetFigureId","descendant","SECTION_TITLE_I18N_KEYS","BOOK_LEVEL_SECTIONS","DESCRIPTION_SUB_SECTIONS","hasMeaningfulContent","found","child","PatentTitleNode","bookHeading","placeholder","contentArea","getNodePos","activateTitle","onPlaceholderClick","bookLabel","titleLabel","hasContent","isActive","prevLang","prevActivePos","langChanged","posChanged","PatentSectionNode","stripSectionWrappers","fragment","Fragment","cleaned","Slice","oldOrder","newOrder","heading","body","activateSection","openDraftingForSection","isBook","isSub","titleKey","sectionTitle","PRE_DESCRIPTION_SECTIONS","DESCRIPTION_SECTIONS","POST_DESCRIPTION_SECTIONS","DESIGN_SECTIONS","buildSectionNode","buildTitleNode","buildInventionContent","buildDesignContent","buildPatentDocument","patentType","CLAIM_CONTENT_LIMIT","pluginState","getClaimNodes","getFigureNodes","normalizeFigureId","value","suggestNextFigureId","prefix","used","FIGURE_ID_PATTERN","syncFigureOrder","figures","updates","seqIndex","fig","currentId","expectedId","u","normalizeNumberArray","numbers","normalizeStringArray","sameArray","buildReferenceText","invalid","getGlobalReferenceLanguage","validateClaimGraph","claims","issues","numberMap","claim","dependencyId","adjacency","visited","inStack","cycleNodes","dfs","nodeId","depId","syncClaimState","claimNodes","usedClaimIds","baseClaims","match","rawClaimId","claimId","numberToId","idToNumber","normalizedClaims","currentDependsOnIds","fallbackIds","dependsOnClaimIds","source","dependsOn","updated","changed","nextAttrs","signature","issue","getClaimIndex","claimIndex","numberValue","getFigureIndex","figureIndex","syncReferenceState","invalidRefs","globalLanguage","targetClaimId","matchedClaim","matchedFigure","displayText","legacyTarget","key","syncReferenceHighlightState","activeClaim","activeClaimId","nextHighlight","warnClaimContentLength","overLimit","resolveClaimPos","position","currentClaim","firstClaim","updateClaimText","contentFrom","contentTo","PatentPlugin","data","placement","claimAttrs","claimBody","inserted","lastClaim","attrsPatch","targetNode","currentNumber","currentReference","figureNode","candidateId","duplicated","_","normalizedClaimId","sectionNode","plugins","defaultPlugins","createEditorConfig","createCommandContext","BOOK_SECTIONS","DESCRIPTION_SUBS","extractDocNodes","title","paragraphs","TextRun","AlignmentType","subSectionHeading","patentTitleParagraph","bodyParagraph","convertMillimetersToTwip","buildDocxParagraphs","descriptionBookInserted","exportToWord","patentTitle","fileName","sectionOptions","blob","Packer","saveAs","exportToPdf","defaultGroupOrder","formatGroupLabel","group","part","DropdownButton","btn","open","setOpen","triggerRef","menuRef","setPos","updatePosition","rect","handleClickOutside","handleScroll","clsx","v","ChevronDown","createPortal","Toolbar","groupOrder","collapsibleGroups","defaultCollapsedGroups","collapsedGroups","setCollapsedGroups","setEditorLanguage","commandExecutor","coreButtons","Undo2","Redo2","Strikethrough","Pilcrow","Heading1","Heading2","Heading3","AlignLeft","AlignCenter","AlignRight","AlignJustify","List","ListOrdered","Quote","FileCode2","TableIcon","Minus","CheckSquare","iconMap","GitGraph","Sigma","FunctionSquare","Workflow","Box","FileText","Link2","pluginButtons","commandMeta","tooltip","shortcut","displayTooltip","Square","exportButton","Download","exportDropdownItems","allButtons","extraGroups","button","groupedButtons","entry","toggleGroup","next","tableDropdownItems","figureDropdownItems","renderButton","collapsed","NodeToolbar","version","setVersion","selectedClaimId","setSelectedClaimId","selectedFigureId","setSelectedFigureId","claimOptions","figureOptions","activeClaimNumber","activeDependsOn","dependencyCandidates","activeDependsOnSet","hasActiveClaim","toggleDependency","activeFigure","hasActiveFigure","activeFigureId","activeFigureContentType","editingFigureId","setEditingFigureId","figureIdInputRef","prevActiveFigurePos","currentFigurePos","handleFigureTypeChange","newType","handleFigureIdCommit","currentWidth","w","Trash2","buildReferenceInlineText","serializeClaimBodyText","extractClaimsFromEditor","resolvedIds","validateClaimGraphIssues","independentClaims","c","multiDeps","hasIndependent","dep","hasDependent","buildClaimTreeRows","dependsMap","childrenMap","parentId","current","roots","allIds","orderedRoots","idToClaim","rows","appended","walk","childId","rootId","ClaimWorkspacePanel","showTree","setShowTree","useEditorState","ctx","useMemo","treeRows","claimPosMap","jumpTo","row","sectionContextDeps","getMissingSectionDeps","targetSection","completedSections","getAllSections","sections","findSectionAtCursor","buildDependencyContext","targetSectionType","deps","sectionMap","depType","section","buildAIContext","selectedText","targetSectionPos","dependencyContext","surroundingText","beforeFrom","afterTo","before","after","EditorBubbleMenu","onSelectionOptimize","addChatReference","openChatPanel","btnClass","handleAIOptimize","handleLink","TiptapBubbleMenu","Highlighter","Sparkles","FindReplace","visible","setVisible","showReplace","setShowReplace","setSearchTerm","setReplaceTerm","setCaseSensitive","searchInputRef","resultCount","currentIndex","handler","detail","doSearch","close","toggleCaseSensitive","CaseSensitive","ChevronUp","Replace","X","ReplaceAll","WordCount","stats","selectionCount","STATE_ICONS","STATE_COLORS","DESCRIPTION_SUB_TYPES","OutlinePanel","setCollapsed","descriptionGroupInserted","level","PanelLeft","PanelLeftClose","NodeRenderer","mode","EditorContent","AUTO_SAVE_KEY","AUTO_SAVE_DEBOUNCE_MS","loadDraftFromStorage","raw","EditorView","initialContent","onChange","readOnly","editable","onEditorReady","setEditor","setDocument","ai","setAutoSaveStatus","setLastSavedAt","debounceRef","resolvedInitialContent","saveToStorage","json","useEditor","initialContentAppliedRef","saveLabel","parseSSEStream","decoder","buffer","controller","lines","currentEvent","line","parsed","eventType","createSSEAdapter","baseUrl","headers","req","resp","createChatSessionAPI","base","init","patentId","page","pageSize","params","sessionId","messageId","PatentEditor","aiService","chatSessionAPI","aiBaseUrl","aiHeaders","setAIService","setChatSessionAPI","localEditorRef","handleEditorReady","resolvedContent","React","writeStream","aborted","clearSectionContent","insertPos","getInsertPosition","removeEmptyParagraphs","err","writeStreamFromSSE","abortController","response","_e","ssetr","_f","_g","_h","contentStart","contentEnd","paragraph","toDelete","totalChildren","nonEmptyCount","childStart","childEnd","SECTION_TEXTS","CHAT_RESPONSES","delay","ms","createMockStream","events","chunkDelayMs","cancelled","evt","buildStreamingEvents","chunks","splitTextIntoChunks","chunk","chunkSize","buildChatStreamEvents","userContent","responseText","analysis","original","optimized","createMockAIService","sectionKey","sectionText","fullText","createMockChatSessionAPI","sessions","pendingStream","session","s","stream","asstId","parseClaimsText","normalized","claimPattern","start","claimText","extractDependencies","selfNumber","zhPattern","enPattern","buildClaimsJSONContent","DocDiffPluginKey","applyDocDiffDecorations","originalText","docSize","currentText","dmp","curOffset","runStart","display","decoSet","removeDocDiffDecorations","validatePatentDocument","issueIdx","nextId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lib.js","sources":["../src/editor/extensions/slashCommand.ts","../src/store/editorStore.ts","../src/components/SlashMenu.tsx","../src/editor/extensions/searchReplace.ts","../src/editor/ai/patchDiff.ts","../src/editor/schema/baseNodes.ts","../src/editor/schema/baseMarks.ts","../src/editor/schema/schema.ts","../src/editor/core/CommandRegistry.ts","../src/editor/core/PluginManager.ts","../src/lib/editorI18n.ts","../src/editor/plugins/mermaid/mermaidNode.ts","../src/editor/plugins/mermaid/index.ts","../src/editor/plugins/drawio/drawioNode.ts","../src/editor/plugins/drawio/index.ts","../src/editor/plugins/math/MathComponent.tsx","../src/editor/plugins/math/mathNode.ts","../src/editor/plugins/math/index.ts","../src/editor/commands/nodeQueries.ts","../src/editor/commands/nodeCommands.ts","../src/editor/plugins/patent/figureNode.ts","../src/editor/plugins/patent/referenceNode.ts","../src/editor/plugins/patent/sectionNode.ts","../src/editor/plugins/patent/patentDocTemplate.ts","../src/editor/plugins/patent/index.ts","../src/editor/plugins/index.ts","../src/editor/core/EditorCore.ts","../src/components/Toolbar.tsx","../src/components/NodeToolbar.tsx","../src/editor/ai/sectionContextDeps.ts","../src/editor/ai/aiContext.ts","../src/components/BubbleMenu.tsx","../src/components/FindReplace.tsx","../src/components/WordCount.tsx","../src/components/OutlinePanel.tsx","../src/editor/renderer/NodeRenderer.tsx","../src/components/EditorView.tsx","../src/editor/ai/aiService.ts","../src/PatentEditor.tsx","../src/editor/ai/streamWriter.ts","../src/editor/ai/mockAIService.ts","../src/editor/ai/postProcessClaims.ts","../src/editor/ai/docDiff.ts","../src/editor/export/wordExport.ts","../src/editor/plugins/patent/validation.ts","../src/editor/plugins/patent/claimIndustrial.ts"],"sourcesContent":["import { Extension } from '@tiptap/react';\r\nimport { PluginKey } from '@tiptap/pm/state';\r\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion';\r\n\r\nexport interface SlashCommandItem {\r\n title: string;\r\n description: string;\r\n icon: string;\r\n command: (props: { editor: any; range: any }) => void;\r\n}\r\n\r\nexport const SlashCommandPluginKey = new PluginKey('slashCommand');\r\n\r\nexport const SlashCommand = Extension.create({\r\n name: 'slashCommand',\r\n\r\n addOptions() {\r\n return {\r\n suggestion: {\r\n char: '/',\r\n command: ({ editor, range, props }: { editor: any; range: any; props: SlashCommandItem }) => {\r\n props.command({ editor, range });\r\n },\r\n } as Partial<SuggestionOptions<SlashCommandItem>>,\r\n };\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n return [\r\n Suggestion<SlashCommandItem>({\r\n editor: this.editor,\r\n ...this.options.suggestion,\r\n pluginKey: SlashCommandPluginKey,\r\n }),\r\n ];\r\n },\r\n});\r\n","import { create } from 'zustand';\r\nimport { Editor, JSONContent } from '@tiptap/react';\r\nimport type { AIServiceAdapter, ChatSessionAPI } from '../editor/ai/aiService';\r\n\r\nexport type EditorLanguage = 'zh' | 'en';\r\nexport type AutoSaveStatus = 'idle' | 'saving' | 'saved' | 'error';\r\nexport type AIStatus = 'idle' | 'streaming' | 'loading' | 'error';\r\nexport type RightPanelTab = 'drafting' | 'chat';\r\n\r\ninterface AIStreamingState {\r\n status: AIStatus;\r\n activeSectionType: string | null;\r\n requestId: string | null;\r\n abortFn: (() => void) | null;\r\n}\r\n\r\nexport interface ChatReference {\r\n id: string;\r\n text: string;\r\n from?: number;\r\n to?: number;\r\n sectionType?: string;\r\n}\r\n\r\ninterface RightPanelState {\r\n visible: boolean;\r\n activeTab: RightPanelTab;\r\n activeSectionType: string | null;\r\n activeSectionPos: number | null;\r\n regenerate: boolean;\r\n chatReferences: ChatReference[];\r\n pendingChatMessage: string | null;\r\n}\r\n\r\ninterface EditorState {\r\n editor: Editor | null;\r\n document: JSONContent | null;\r\n selection: { from: number; to: number } | null;\r\n editorLanguage: EditorLanguage;\r\n autoSaveStatus: AutoSaveStatus;\r\n lastSavedAt: Date | null;\r\n ai: AIStreamingState;\r\n aiService: AIServiceAdapter | null;\r\n chatSessionAPI: ChatSessionAPI | null;\r\n chatSessionId: string | null;\r\n rightPanel: RightPanelState;\r\n setEditor: (editor: Editor) => void;\r\n setDocument: (document: JSONContent) => void;\r\n setSelection: (selection: { from: number; to: number }) => void;\r\n setEditorLanguage: (language: EditorLanguage) => void;\r\n setAutoSaveStatus: (status: AutoSaveStatus) => void;\r\n setLastSavedAt: (date: Date | null) => void;\r\n setAIStatus: (status: AIStatus, sectionType?: string | null) => void;\r\n setAIAbort: (abortFn: (() => void) | null) => void;\r\n resetAI: () => void;\r\n setAIService: (adapter: AIServiceAdapter | null) => void;\r\n setChatSessionAPI: (api: ChatSessionAPI | null) => void;\r\n setChatSessionId: (id: string | null) => void;\r\n setActiveSection: (sectionType: string, sectionPos: number) => void;\r\n openDraftingPanel: (sectionType: string, sectionPos: number, regenerate?: boolean) => void;\r\n openChatPanel: () => void;\r\n setRightPanelTab: (tab: RightPanelTab) => void;\r\n closeRightPanel: () => void;\r\n addChatReference: (ref: Omit<ChatReference, 'id'>) => void;\r\n removeChatReference: (id: string) => void;\r\n clearChatReferences: () => void;\r\n setPendingChatMessage: (msg: string | null) => void;\r\n}\r\n\r\nconst defaultRightPanel: RightPanelState = {\r\n visible: true,\r\n activeTab: 'chat',\r\n activeSectionType: null,\r\n activeSectionPos: null,\r\n regenerate: false,\r\n chatReferences: [],\r\n pendingChatMessage: null,\r\n};\r\n\r\nexport const useEditorStore = create<EditorState>((set) => ({\r\n editor: null,\r\n document: null,\r\n selection: null,\r\n editorLanguage: 'zh',\r\n autoSaveStatus: 'idle',\r\n lastSavedAt: null,\r\n ai: { status: 'idle', activeSectionType: null, requestId: null, abortFn: null },\r\n aiService: null,\r\n chatSessionAPI: null,\r\n chatSessionId: null,\r\n rightPanel: { ...defaultRightPanel },\r\n setEditor: (editor) => set({ editor }),\r\n setDocument: (document) => set({ document }),\r\n setSelection: (selection) => set({ selection }),\r\n setEditorLanguage: (editorLanguage) => set({ editorLanguage }),\r\n setAutoSaveStatus: (autoSaveStatus) => set({ autoSaveStatus }),\r\n setLastSavedAt: (lastSavedAt) => set({ lastSavedAt }),\r\n setAIStatus: (status, sectionType) =>\r\n set((state) => ({\r\n ai: {\r\n ...state.ai,\r\n status,\r\n activeSectionType: sectionType ?? state.ai.activeSectionType,\r\n requestId: status === 'streaming' ? `req_${Date.now()}` : state.ai.requestId,\r\n },\r\n })),\r\n setAIAbort: (abortFn) =>\r\n set((state) => ({ ai: { ...state.ai, abortFn } })),\r\n resetAI: () =>\r\n set({ ai: { status: 'idle', activeSectionType: null, requestId: null, abortFn: null } }),\r\n setAIService: (adapter) => set({ aiService: adapter }),\r\n setChatSessionAPI: (api) => set({ chatSessionAPI: api }),\r\n setChatSessionId: (id) => set({ chatSessionId: id }),\r\n setActiveSection: (sectionType, sectionPos) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n activeSectionType: sectionType,\r\n activeSectionPos: sectionPos,\r\n regenerate: false,\r\n },\r\n })),\r\n openDraftingPanel: (sectionType, sectionPos, regenerate = false) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n visible: true,\r\n activeTab: 'drafting',\r\n activeSectionType: sectionType,\r\n activeSectionPos: sectionPos,\r\n regenerate,\r\n },\r\n })),\r\n openChatPanel: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, visible: true, activeTab: 'chat' },\r\n })),\r\n setRightPanelTab: (tab) =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, activeTab: tab },\r\n })),\r\n closeRightPanel: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, visible: false },\r\n })),\r\n addChatReference: (ref) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n chatReferences: [\r\n ...state.rightPanel.chatReferences,\r\n { ...ref, id: `ref_${Date.now()}_${Math.random().toString(36).slice(2, 6)}` },\r\n ],\r\n },\r\n })),\r\n removeChatReference: (id) =>\r\n set((state) => ({\r\n rightPanel: {\r\n ...state.rightPanel,\r\n chatReferences: state.rightPanel.chatReferences.filter((r) => r.id !== id),\r\n },\r\n })),\r\n clearChatReferences: () =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, chatReferences: [] },\r\n })),\r\n setPendingChatMessage: (msg) =>\r\n set((state) => ({\r\n rightPanel: { ...state.rightPanel, pendingChatMessage: msg },\r\n })),\r\n}));\r\n","import React, {\r\n forwardRef,\r\n useEffect,\r\n useImperativeHandle,\r\n useState,\r\n useCallback,\r\n useRef,\r\n useLayoutEffect,\r\n} from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { ReactRenderer } from '@tiptap/react';\r\nimport tippy, { Instance as TippyInstance } from 'tippy.js';\r\nimport type { SuggestionOptions, SuggestionProps, SuggestionKeyDownProps } from '@tiptap/suggestion';\r\nimport type { SlashCommandItem } from '../editor/extensions/slashCommand';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\n\r\n\r\ninterface SlashMenuListProps {\r\n items: SlashCommandItem[];\r\n command: (item: SlashCommandItem) => void;\r\n}\r\n\r\ninterface SlashMenuListRef {\r\n onKeyDown: (props: SuggestionKeyDownProps) => boolean;\r\n}\r\n\r\nconst SlashMenuList = forwardRef<SlashMenuListRef, SlashMenuListProps>(\r\n ({ items, command }, ref) => {\r\n const [selectedIndex, setSelectedIndex] = useState(0);\r\n\r\n useEffect(() => {\r\n setSelectedIndex(0);\r\n }, [items]);\r\n\r\n const selectItem = useCallback(\r\n (index: number) => {\r\n const item = items[index];\r\n if (item) command(item);\r\n },\r\n [items, command]\r\n );\r\n\r\n useImperativeHandle(ref, () => ({\r\n onKeyDown: ({ event }: SuggestionKeyDownProps) => {\r\n if (event.key === 'ArrowUp') {\r\n setSelectedIndex((prev) => (prev + items.length - 1) % items.length);\r\n return true;\r\n }\r\n if (event.key === 'ArrowDown') {\r\n setSelectedIndex((prev) => (prev + 1) % items.length);\r\n return true;\r\n }\r\n if (event.key === 'Enter') {\r\n selectItem(selectedIndex);\r\n return true;\r\n }\r\n return false;\r\n },\r\n }));\r\n\r\n if (!items.length) {\r\n return (\r\n <div className=\"slash-menu\">\r\n <div className=\"slash-menu-empty\">No results</div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"slash-menu\">\r\n {items.map((item, index) => (\r\n <button\r\n key={item.title}\r\n className={`slash-menu-item ${index === selectedIndex ? 'slash-menu-item--active' : ''}`}\r\n onClick={() => selectItem(index)}\r\n onMouseEnter={() => setSelectedIndex(index)}\r\n >\r\n <span className=\"slash-menu-icon\">{item.icon}</span>\r\n <div className=\"slash-menu-text\">\r\n <span className=\"slash-menu-title\">{item.title}</span>\r\n <span className=\"slash-menu-desc\">{item.description}</span>\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n );\r\n }\r\n);\r\n\r\nSlashMenuList.displayName = 'SlashMenuList';\r\n\r\nexport function getSlashCommandItems(lang: 'zh' | 'en'): SlashCommandItem[] {\r\n const zh = lang === 'zh';\r\n return [\r\n {\r\n title: zh ? '段落' : 'Paragraph',\r\n description: zh ? '普通文本段落' : 'Plain text paragraph',\r\n icon: '¶',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setParagraph().run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 1' : 'Heading 1',\r\n description: zh ? '大标题' : 'Large heading',\r\n icon: 'H1',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 1 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 2' : 'Heading 2',\r\n description: zh ? '中标题' : 'Medium heading',\r\n icon: 'H2',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 2 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '标题 3' : 'Heading 3',\r\n description: zh ? '小标题' : 'Small heading',\r\n icon: 'H3',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHeading({ level: 3 }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '无序列表' : 'Bullet List',\r\n description: zh ? '创建无序列表' : 'Create a bullet list',\r\n icon: '•',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleBulletList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '有序列表' : 'Ordered List',\r\n description: zh ? '创建有序列表' : 'Create a numbered list',\r\n icon: '1.',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleOrderedList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '任务列表' : 'Task List',\r\n description: zh ? '创建待办列表' : 'Create a task list',\r\n icon: '☑',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleTaskList().run();\r\n },\r\n },\r\n {\r\n title: zh ? '引用' : 'Blockquote',\r\n description: zh ? '创建引用块' : 'Create a blockquote',\r\n icon: '❝',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleBlockquote().run();\r\n },\r\n },\r\n {\r\n title: zh ? '代码块' : 'Code Block',\r\n description: zh ? '插入代码块' : 'Insert a code block',\r\n icon: '<>',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).toggleCodeBlock().run();\r\n },\r\n },\r\n {\r\n title: zh ? '表格' : 'Table',\r\n description: zh ? '插入 3×3 表格' : 'Insert a 3×3 table',\r\n icon: '⊞',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\r\n },\r\n },\r\n {\r\n title: zh ? '分割线' : 'Horizontal Rule',\r\n description: zh ? '插入水平分割线' : 'Insert a horizontal rule',\r\n icon: '─',\r\n command: ({ editor, range }) => {\r\n editor.chain().focus().deleteRange(range).setHorizontalRule().run();\r\n },\r\n },\r\n {\r\n title: zh ? '图片' : 'Image',\r\n description: zh ? '插入图片(URL)' : 'Insert an image (URL)',\r\n icon: '🖼',\r\n command: ({ editor, range }) => {\r\n const url = window.prompt(zh ? '请输入图片 URL' : 'Enter image URL');\r\n if (url) {\r\n editor.chain().focus().deleteRange(range).setImage({ src: url }).run();\r\n }\r\n },\r\n },\r\n ];\r\n}\r\n\r\nexport function createSlashSuggestion(): Partial<SuggestionOptions<SlashCommandItem>> {\r\n return {\r\n char: '/',\r\n items: ({ query }) => {\r\n const lang = useEditorStore.getState().editorLanguage;\r\n const all = getSlashCommandItems(lang);\r\n if (!query) return all;\r\n const lower = query.toLowerCase();\r\n return all.filter(\r\n (item) =>\r\n item.title.toLowerCase().includes(lower) ||\r\n item.description.toLowerCase().includes(lower)\r\n );\r\n },\r\n render: () => {\r\n let component: ReactRenderer<SlashMenuListRef> | null = null;\r\n let popup: TippyInstance[] | null = null;\r\n\r\n return {\r\n onStart: (props: SuggestionProps<SlashCommandItem>) => {\r\n component = new ReactRenderer(SlashMenuList, {\r\n props,\r\n editor: props.editor,\r\n });\r\n\r\n if (!props.clientRect) return;\r\n\r\n popup = tippy('body', {\r\n getReferenceClientRect: props.clientRect as () => DOMRect,\r\n appendTo: () => document.body,\r\n content: component.element,\r\n showOnCreate: true,\r\n interactive: true,\r\n trigger: 'manual',\r\n placement: 'bottom-start',\r\n });\r\n },\r\n onUpdate: (props: SuggestionProps<SlashCommandItem>) => {\r\n component?.updateProps(props);\r\n if (popup && props.clientRect) {\r\n popup[0].setProps({\r\n getReferenceClientRect: props.clientRect as () => DOMRect,\r\n });\r\n }\r\n },\r\n onKeyDown: (props: SuggestionKeyDownProps) => {\r\n if (props.event.key === 'Escape') {\r\n popup?.[0]?.hide();\r\n return true;\r\n }\r\n return component?.ref?.onKeyDown(props) ?? false;\r\n },\r\n onExit: () => {\r\n popup?.[0]?.destroy();\r\n component?.destroy();\r\n },\r\n };\r\n },\r\n };\r\n}\r\n","import { Extension } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\n\r\nexport interface SearchReplaceStorage {\r\n searchTerm: string;\r\n replaceTerm: string;\r\n caseSensitive: boolean;\r\n results: { from: number; to: number }[];\r\n currentIndex: number;\r\n}\r\n\r\nexport const SearchReplacePluginKey = new PluginKey('searchReplace');\r\n\r\nfunction findMatches(doc: any, searchTerm: string, caseSensitive: boolean): { from: number; to: number }[] {\r\n if (!searchTerm) return [];\r\n const results: { from: number; to: number }[] = [];\r\n const text = doc.textBetween(0, doc.content.size, '\\n', '\\0');\r\n const term = caseSensitive ? searchTerm : searchTerm.toLowerCase();\r\n const haystack = caseSensitive ? text : text.toLowerCase();\r\n\r\n let pos = 0;\r\n while (pos < haystack.length) {\r\n const idx = haystack.indexOf(term, pos);\r\n if (idx === -1) break;\r\n\r\n let docFrom = 0;\r\n let charCount = 0;\r\n let fromPos = -1;\r\n let toPos = -1;\r\n\r\n doc.descendants((node: any, nodePos: number) => {\r\n if (fromPos !== -1 && toPos !== -1) return false;\r\n if (node.isText) {\r\n const nodeText = node.text || '';\r\n for (let i = 0; i < nodeText.length; i++) {\r\n if (charCount === idx) fromPos = nodePos + i;\r\n if (charCount === idx + term.length) {\r\n toPos = nodePos + i;\r\n return false;\r\n }\r\n charCount++;\r\n }\r\n if (charCount === idx + term.length && toPos === -1) {\r\n toPos = nodePos + nodeText.length;\r\n }\r\n } else if (node.isBlock && charCount > 0) {\r\n if (charCount === idx) fromPos = nodePos;\r\n charCount++;\r\n }\r\n return true;\r\n });\r\n\r\n if (fromPos !== -1 && toPos !== -1) {\r\n results.push({ from: fromPos, to: toPos });\r\n }\r\n pos = idx + 1;\r\n }\r\n\r\n return results;\r\n}\r\n\r\nexport const SearchReplace = Extension.create<{}, SearchReplaceStorage>({\r\n name: 'searchReplace',\r\n\r\n addStorage() {\r\n return {\r\n searchTerm: '',\r\n replaceTerm: '',\r\n caseSensitive: false,\r\n results: [],\r\n currentIndex: 0,\r\n };\r\n },\r\n\r\n addCommands() {\r\n return {\r\n setSearchTerm: (term: string) => ({ editor }) => {\r\n this.storage.searchTerm = term;\r\n this.storage.results = findMatches(editor.state.doc, term, this.storage.caseSensitive);\r\n this.storage.currentIndex = this.storage.results.length > 0 ? 0 : -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n setReplaceTerm: (term: string) => () => {\r\n this.storage.replaceTerm = term;\r\n return true;\r\n },\r\n setCaseSensitive: (val: boolean) => ({ editor }) => {\r\n this.storage.caseSensitive = val;\r\n this.storage.results = findMatches(editor.state.doc, this.storage.searchTerm, val);\r\n this.storage.currentIndex = this.storage.results.length > 0 ? 0 : -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n nextSearchResult: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n this.storage.currentIndex = (this.storage.currentIndex + 1) % this.storage.results.length;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (r) {\r\n editor.commands.setTextSelection(r);\r\n scrollToSelection(editor);\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n previousSearchResult: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n this.storage.currentIndex =\r\n (this.storage.currentIndex - 1 + this.storage.results.length) % this.storage.results.length;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (r) {\r\n editor.commands.setTextSelection(r);\r\n scrollToSelection(editor);\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n replaceCurrent: () => ({ editor }) => {\r\n if (this.storage.results.length === 0 || this.storage.currentIndex < 0) return false;\r\n const r = this.storage.results[this.storage.currentIndex];\r\n if (!r) return false;\r\n editor.chain().focus().insertContentAt(r, this.storage.replaceTerm).run();\r\n this.storage.results = findMatches(editor.state.doc, this.storage.searchTerm, this.storage.caseSensitive);\r\n if (this.storage.currentIndex >= this.storage.results.length) {\r\n this.storage.currentIndex = 0;\r\n }\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n replaceAll: () => ({ editor }) => {\r\n if (this.storage.results.length === 0) return false;\r\n const { searchTerm, replaceTerm, caseSensitive } = this.storage;\r\n let matches = findMatches(editor.state.doc, searchTerm, caseSensitive);\r\n const tr = editor.state.tr;\r\n let offset = 0;\r\n for (const m of matches) {\r\n const from = m.from + offset;\r\n const to = m.to + offset;\r\n tr.insertText(replaceTerm, from, to);\r\n offset += replaceTerm.length - (m.to - m.from);\r\n }\r\n editor.view.dispatch(tr);\r\n this.storage.results = [];\r\n this.storage.currentIndex = -1;\r\n return true;\r\n },\r\n clearSearch: () => ({ editor }) => {\r\n this.storage.searchTerm = '';\r\n this.storage.replaceTerm = '';\r\n this.storage.results = [];\r\n this.storage.currentIndex = -1;\r\n editor.view.dispatch(editor.state.tr);\r\n return true;\r\n },\r\n } as any;\r\n },\r\n\r\n addKeyboardShortcuts() {\r\n return {\r\n 'Mod-f': () => {\r\n const event = new CustomEvent('editor:toggleSearch');\r\n window.dispatchEvent(event);\r\n return true;\r\n },\r\n 'Mod-h': () => {\r\n const event = new CustomEvent('editor:toggleSearch', { detail: { replace: true } });\r\n window.dispatchEvent(event);\r\n return true;\r\n },\r\n };\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n const storage = this.storage;\r\n return [\r\n new Plugin({\r\n key: SearchReplacePluginKey,\r\n props: {\r\n decorations: (state) => {\r\n if (!storage.searchTerm || storage.results.length === 0) {\r\n return DecorationSet.empty;\r\n }\r\n const decorations = storage.results.map((r, i) => {\r\n const className = i === storage.currentIndex ? 'search-highlight search-highlight--current' : 'search-highlight';\r\n return Decoration.inline(r.from, r.to, { class: className });\r\n });\r\n return DecorationSet.create(state.doc, decorations);\r\n },\r\n },\r\n }),\r\n ];\r\n },\r\n});\r\n\r\nfunction scrollToSelection(editor: any) {\r\n requestAnimationFrame(() => {\r\n const dom = editor.view.domAtPos(editor.state.selection.from);\r\n if (dom?.node) {\r\n const el = dom.node instanceof HTMLElement ? dom.node : dom.node.parentElement;\r\n el?.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n }\r\n });\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Node as PMNode } from '@tiptap/pm/model';\r\nimport type { AIPatchData, ChatReference } from './aiService';\r\nimport { diff_match_patch } from 'diff-match-patch';\r\n\r\n// diff-match-patch constants\r\nconst DIFF_DELETE = -1;\r\nconst DIFF_INSERT = 1;\r\nconst DIFF_EQUAL = 0;\r\n\r\n// Lazy singleton\r\nlet _dmp: InstanceType<typeof diff_match_patch> | null = null;\r\nfunction getDmp(): InstanceType<typeof diff_match_patch> {\r\n if (!_dmp) _dmp = new diff_match_patch();\r\n return _dmp;\r\n}\r\n\r\nexport interface AIPatch {\r\n id: string;\r\n type: 'insert' | 'replace' | 'delete';\r\n from: number;\r\n to: number;\r\n content: string;\r\n originalText?: string;\r\n reason?: string;\r\n status: 'pending' | 'accepted' | 'rejected';\r\n}\r\n\r\nexport const PatchDiffPluginKey = new PluginKey('patchDiff');\r\n\r\n// ── Resolve semantic patch target to absolute positions ──\r\n\r\ninterface ResolvedRange {\r\n from: number;\r\n to: number;\r\n}\r\n\r\n/**\r\n * Find a patent_section node by sectionType, return its content range.\r\n */\r\nfunction findSectionRange(editor: Editor, sectionType: string): ResolvedRange | null {\r\n let result: ResolvedRange | null = null;\r\n editor.state.doc.descendants((node, pos) => {\r\n if (result) return false;\r\n if (node.type.name === 'patent_section' && node.attrs.sectionType === sectionType) {\r\n result = { from: pos + 1, to: pos + node.nodeSize - 1 };\r\n return false;\r\n }\r\n return true;\r\n });\r\n return result;\r\n}\r\n\r\n/**\r\n * A text segment mapping: textIdx in the concatenated string → docPos in ProseMirror.\r\n */\r\nexport interface TextSegment {\r\n textIdx: number;\r\n docPos: number;\r\n len: number;\r\n}\r\n\r\n/**\r\n * Build a concatenated text string that exactly mirrors `doc.textBetween(from, to, '\\0', '\\0')`\r\n * and simultaneously record position-mapping segments for every text node slice.\r\n *\r\n * ProseMirror's `textBetween` inserts `blockSeparator` before a block node\r\n * only when `!separated` (i.e. text/leaf content appeared before it).\r\n * The old implementation incorrectly counted `charCount++` for every non-leaf\r\n * non-text node, which over-counted for wrapper nodes like `patent_section`.\r\n */\r\nexport function buildTextMap(\r\n editor: Editor,\r\n rangeFrom: number,\r\n rangeTo: number,\r\n): { text: string; segments: TextSegment[] } {\r\n const segments: TextSegment[] = [];\r\n let text = '';\r\n let separated = true; // mirrors ProseMirror textBetween initial state\r\n\r\n editor.state.doc.nodesBetween(rangeFrom, rangeTo, (node, pos) => {\r\n if (node.isText) {\r\n const nodeStart = pos;\r\n const sliceFrom = Math.max(rangeFrom, nodeStart) - nodeStart;\r\n const sliceTo = Math.min(rangeTo, nodeStart + node.nodeSize) - nodeStart;\r\n const slice = node.text!.slice(sliceFrom, sliceTo);\r\n segments.push({ textIdx: text.length, docPos: nodeStart + sliceFrom, len: slice.length });\r\n text += slice;\r\n separated = false;\r\n } else if (node.isLeaf) {\r\n // leafText — mirrors textBetween's leafText parameter ('\\0')\r\n text += '\\0';\r\n separated = false;\r\n } else if (!separated && node.isBlock) {\r\n // blockSeparator — only inserted between consecutive text-bearing blocks\r\n text += '\\0';\r\n separated = true;\r\n }\r\n });\r\n\r\n return { text, segments };\r\n}\r\n\r\n/**\r\n * Convert a text offset (in the concatenated string from buildTextMap)\r\n * to an absolute ProseMirror document position.\r\n */\r\nexport function textOffsetToDocPos(segments: TextSegment[], offset: number): number {\r\n for (const seg of segments) {\r\n if (offset >= seg.textIdx && offset <= seg.textIdx + seg.len) {\r\n return seg.docPos + (offset - seg.textIdx);\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\n/**\r\n * Search for a text string within a document range [rangeFrom, rangeTo].\r\n * `skipPositions` is an optional set of doc positions to skip (avoid matching\r\n * ranges that are already claimed by earlier patches in the same section).\r\n * Returns the first non-skipped match position, or null.\r\n */\r\nfunction searchTextInRange(\r\n editor: Editor,\r\n searchText: string,\r\n rangeFrom: number,\r\n rangeTo: number,\r\n skipPositions?: Set<number>,\r\n): ResolvedRange | null {\r\n const { text, segments } = buildTextMap(editor, rangeFrom, rangeTo);\r\n\r\n let searchStart = 0;\r\n while (searchStart <= text.length - searchText.length) {\r\n const idx = text.indexOf(searchText, searchStart);\r\n if (idx === -1) return null;\r\n\r\n const matchFrom = textOffsetToDocPos(segments, idx);\r\n const matchTo = textOffsetToDocPos(segments, idx + searchText.length);\r\n\r\n if (matchFrom >= 0 && matchTo >= 0 && !(skipPositions && skipPositions.has(matchFrom))) {\r\n return { from: matchFrom, to: matchTo };\r\n }\r\n searchStart = idx + 1;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Resolve an AIPatchData (with semantic target) into absolute from/to positions.\r\n * Returns an AIPatch ready for decoration, or null if resolution fails.\r\n */\r\nexport function resolvePatchTarget(\r\n editor: Editor,\r\n patchData: AIPatchData,\r\n refs: ChatReference[],\r\n patchIndex: number,\r\n alreadyResolved?: AIPatch[],\r\n): AIPatch | null {\r\n const target = patchData.target;\r\n let range: ResolvedRange | null = null;\r\n\r\n // Build a set of already-claimed positions to skip during search\r\n const claimedPositions = new Set<number>();\r\n if (alreadyResolved) {\r\n for (const p of alreadyResolved) {\r\n claimedPositions.add(p.from);\r\n }\r\n }\r\n\r\n // Step 1: Resolve target to a search scope\r\n if (!target) {\r\n // Legacy: use from/to directly\r\n if (patchData.from != null && patchData.to != null) {\r\n range = { from: patchData.from, to: patchData.to };\r\n }\r\n } else if (target.type === 'section' && target.sectionType) {\r\n range = findSectionRange(editor, target.sectionType);\r\n } else if (target.type === 'ref' && target.refIndex != null) {\r\n const ref = refs[target.refIndex];\r\n if (ref?.from != null && ref?.to != null) {\r\n range = { from: ref.from, to: ref.to };\r\n }\r\n } else if (target.type === 'search' && target.searchText) {\r\n range = searchTextInRange(editor, target.searchText, 0, editor.state.doc.content.size, claimedPositions);\r\n }\r\n\r\n if (!range) return null;\r\n\r\n // Step 2: If there's a search field, narrow down within the resolved range\r\n let finalRange = range;\r\n if (patchData.search) {\r\n const narrowed = searchTextInRange(editor, patchData.search, range.from, range.to, claimedPositions);\r\n if (narrowed) {\r\n finalRange = narrowed;\r\n }\r\n // If search fails, fallback to the full range\r\n }\r\n\r\n // Step 3: Build AIPatch\r\n const origText = (finalRange.from < finalRange.to)\r\n ? editor.state.doc.textBetween(finalRange.from, finalRange.to, ' ', '\\0')\r\n : '';\r\n\r\n return {\r\n id: `patch_${Date.now()}_${patchIndex}`,\r\n type: patchData.op === 'delete' ? 'delete' : patchData.op === 'insert' ? 'insert' : 'replace',\r\n from: finalRange.from,\r\n to: patchData.op === 'insert' ? finalRange.from : finalRange.to,\r\n content: patchData.content || '',\r\n originalText: origText,\r\n reason: patchData.reason,\r\n status: 'pending',\r\n };\r\n}\r\n\r\nlet pendingPatches: AIPatch[] = [];\r\nlet patchChangeListeners: Array<() => void> = [];\r\n\r\nexport function onPatchChange(listener: () => void): () => void {\r\n patchChangeListeners.push(listener);\r\n return () => {\r\n patchChangeListeners = patchChangeListeners.filter(l => l !== listener);\r\n };\r\n}\r\n\r\nfunction notifyPatchChange(): void {\r\n patchChangeListeners.forEach(l => l());\r\n}\r\n\r\nexport function getPatches(): AIPatch[] {\r\n return [...pendingPatches];\r\n}\r\n\r\nexport function setPatches(patches: AIPatch[]): void {\r\n pendingPatches = patches;\r\n notifyPatchChange();\r\n}\r\n\r\nexport function clearPatches(): void {\r\n pendingPatches = [];\r\n notifyPatchChange();\r\n}\r\n\r\nexport function acceptPatch(editor: Editor, patchId: string): boolean {\r\n const patch = pendingPatches.find(p => p.id === patchId);\r\n if (!patch || patch.status !== 'pending') return false;\r\n\r\n patch.status = 'accepted';\r\n const { tr } = editor.state;\r\n\r\n if (patch.type === 'delete') {\r\n tr.delete(patch.from, patch.to);\r\n } else if (patch.type === 'insert') {\r\n tr.insertText(patch.content, patch.from);\r\n } else {\r\n // Check if replacement spans a block container's full content (e.g. patent_section)\r\n const needsBlockContent = isBlockContainerContentRange(editor, patch.from, patch.to);\r\n if (needsBlockContent) {\r\n const nodes = textToParagraphs(editor, patch.content);\r\n tr.replaceWith(patch.from, patch.to, nodes);\r\n } else {\r\n tr.insertText(patch.content, patch.from, patch.to);\r\n }\r\n }\r\n\r\n editor.view.dispatch(tr);\r\n\r\n // Use ProseMirror mapping to remap remaining patches' positions.\r\n // This correctly handles any kind of replacement (block, inline, etc.)\r\n const mapping = tr.mapping;\r\n for (const p of pendingPatches) {\r\n if (p.id === patchId || p.status !== 'pending') continue;\r\n const newFrom = mapping.map(p.from, 1);\r\n const newTo = mapping.map(p.to, -1);\r\n if (newFrom >= newTo && p.type !== 'insert') {\r\n // Range collapsed — the accepted patch consumed this one's range\r\n p.status = 'rejected';\r\n } else {\r\n p.from = newFrom;\r\n p.to = p.type === 'insert' ? newFrom : newTo;\r\n }\r\n }\r\n\r\n pendingPatches = pendingPatches.filter(p => p.id !== patchId && p.status === 'pending');\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n return true;\r\n}\r\n\r\nexport function rejectPatch(editor: Editor, patchId: string): boolean {\r\n const patch = pendingPatches.find(p => p.id === patchId);\r\n if (!patch || patch.status !== 'pending') return false;\r\n\r\n patch.status = 'rejected';\r\n pendingPatches = pendingPatches.filter(p => p.id !== patchId);\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n return true;\r\n}\r\n\r\nexport function acceptAllPatches(editor: Editor): void {\r\n const pending = pendingPatches.filter(p => p.status === 'pending');\r\n const sorted = [...pending].sort((a, b) => b.from - a.from);\r\n const { tr } = editor.state;\r\n for (const patch of sorted) {\r\n if (patch.type === 'delete') {\r\n tr.delete(patch.from, patch.to);\r\n } else if (patch.type === 'insert') {\r\n tr.insertText(patch.content, patch.from);\r\n } else {\r\n const needsBlockContent = isBlockContainerContentRange(editor, patch.from, patch.to);\r\n if (needsBlockContent) {\r\n const nodes = textToParagraphs(editor, patch.content);\r\n tr.replaceWith(patch.from, patch.to, nodes);\r\n } else {\r\n tr.insertText(patch.content, patch.from, patch.to);\r\n }\r\n }\r\n }\r\n editor.view.dispatch(tr);\r\n pendingPatches = [];\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n}\r\n\r\nexport function rejectAllPatches(editor: Editor): void {\r\n pendingPatches = [];\r\n refreshDecorations(editor);\r\n notifyPatchChange();\r\n}\r\n\r\nfunction refreshDecorations(editor: Editor): void {\r\n editor.view.dispatch(editor.state.tr.setMeta(PatchDiffPluginKey, true));\r\n}\r\n\r\n/**\r\n * Collect all inline text ranges within a block range [from, to].\r\n * Inline decorations cannot span across block boundaries, so we\r\n * need to find each text block's range and decorate individually.\r\n */\r\nfunction getInlineRanges(\r\n doc: PMNode,\r\n from: number,\r\n to: number\r\n): Array<{ from: number; to: number }> {\r\n const ranges: Array<{ from: number; to: number }> = [];\r\n doc.nodesBetween(from, to, (node, pos) => {\r\n if (node.isTextblock) {\r\n const blockStart = pos + 1; // inside the textblock\r\n const blockEnd = pos + node.nodeSize - 1;\r\n const rangeFrom = Math.max(blockStart, from);\r\n const rangeTo = Math.min(blockEnd, to);\r\n if (rangeTo > rangeFrom) {\r\n ranges.push({ from: rangeFrom, to: rangeTo });\r\n }\r\n return false; // don't descend into text nodes\r\n }\r\n return true;\r\n });\r\n return ranges;\r\n}\r\n\r\n/**\r\n * For a single-textblock replace patch, compute fine-grained word-level\r\n * diff decorations using diff-match-patch. Returns null if:\r\n * - patch spans multiple textblocks (fall back to whole-block)\r\n * - EQUAL ratio < 30% (mostly rewritten → whole-block is clearer)\r\n */\r\nfunction computeFineDiff(\r\n doc: PMNode,\r\n patch: AIPatch,\r\n): Decoration[] | null {\r\n if (!patch.originalText || !patch.content) return null;\r\n\r\n // Only use fine diff for single-textblock patches\r\n try {\r\n const $from = doc.resolve(patch.from);\r\n const $to = doc.resolve(patch.to);\r\n if ($from.parent !== $to.parent || !$from.parent.isTextblock) return null;\r\n } catch {\r\n return null;\r\n }\r\n\r\n const inst = getDmp();\r\n const diffs = inst.diff_main(patch.originalText, patch.content);\r\n inst.diff_cleanupSemantic(diffs);\r\n\r\n // Check EQUAL ratio — if too low, whole-block coloring is clearer\r\n const equalLen = diffs\r\n .filter(([op]) => op === DIFF_EQUAL)\r\n .reduce((sum, [, text]) => sum + text.length, 0);\r\n if (patch.originalText.length > 0 && equalLen / patch.originalText.length < 0.3) return null;\r\n\r\n const decorations: Decoration[] = [];\r\n let docPos = patch.from; // cursor in the document (advances for EQUAL and DELETE)\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === DIFF_EQUAL) {\r\n // Unchanged text — no decoration, advance cursor\r\n docPos += text.length;\r\n } else if (op === DIFF_DELETE) {\r\n // Red strikethrough on the exact deleted characters\r\n const delEnd = docPos + text.length;\r\n decorations.push(\r\n Decoration.inline(docPos, delEnd, {\r\n class: 'patch-diff-delete',\r\n 'data-patch-id': patch.id,\r\n })\r\n );\r\n docPos = delEnd;\r\n } else if (op === DIFF_INSERT) {\r\n // Green widget right at the deletion/cursor point\r\n decorations.push(\r\n Decoration.widget(docPos, () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-insert-inline';\r\n el.textContent = text;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n }, { side: 1 })\r\n );\r\n // docPos does NOT advance — inserts don't exist in the original doc\r\n }\r\n }\r\n\r\n return decorations;\r\n}\r\n\r\nexport function createPatchDiffPlugin(): Plugin {\r\n return new Plugin({\r\n key: PatchDiffPluginKey,\r\n props: {\r\n decorations(state) {\r\n const pending = pendingPatches.filter(p => p.status === 'pending');\r\n if (pending.length === 0) return DecorationSet.empty;\r\n\r\n const decorations: Decoration[] = [];\r\n for (const patch of pending) {\r\n // For replace: try fine-grained inline diff first\r\n if (patch.type === 'replace') {\r\n const fineDiffs = computeFineDiff(state.doc, patch);\r\n if (fineDiffs) {\r\n decorations.push(...fineDiffs);\r\n continue; // skip whole-block fallback\r\n }\r\n }\r\n\r\n if (patch.type === 'delete' || patch.type === 'replace') {\r\n // Whole-block fallback: 删除/替换 — 原文全部标红 + 删除线\r\n const ranges = getInlineRanges(state.doc, patch.from, patch.to);\r\n for (const range of ranges) {\r\n decorations.push(\r\n Decoration.inline(range.from, range.to, {\r\n class: 'patch-diff-delete',\r\n 'data-patch-id': patch.id,\r\n })\r\n );\r\n }\r\n\r\n if (patch.type === 'replace') {\r\n // 在原文之后插入绿色新内容 widget\r\n const widgetPos = ranges.length > 0 ? ranges[ranges.length - 1].to : patch.to;\r\n const isLong = patch.content.length > 120 || patch.content.includes('\\n');\r\n decorations.push(\r\n Decoration.widget(widgetPos, () => {\r\n const el = document.createElement(isLong ? 'div' : 'span');\r\n el.className = isLong\r\n ? 'patch-diff-insert-inline patch-diff-insert-block'\r\n : 'patch-diff-insert-inline';\r\n el.textContent = patch.content;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n }, { side: 1 })\r\n );\r\n }\r\n } else {\r\n // 插入:绿色 widget 显示新内容\r\n decorations.push(\r\n Decoration.widget(patch.from, () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-insert-inline';\r\n el.textContent = patch.content;\r\n el.setAttribute('data-patch-id', patch.id);\r\n return el;\r\n })\r\n );\r\n }\r\n }\r\n return DecorationSet.create(state.doc, decorations);\r\n },\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Check if a position range spans the full content of a block container node\r\n * (e.g. patent_section with content: 'block+'). In that case, we need to\r\n * replace with block-level nodes instead of using insertText.\r\n */\r\nfunction isBlockContainerContentRange(editor: Editor, from: number, to: number): boolean {\r\n const $from = editor.state.doc.resolve(from);\r\n const parent = $from.parent;\r\n // If parent requires block content and range covers its full content\r\n if (parent.type.spec.content?.includes('block') && from === $from.start() && to === $from.end()) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Convert plain text into an array of paragraph nodes,\r\n * splitting by double newlines for paragraph breaks.\r\n */\r\nfunction textToParagraphs(editor: Editor, text: string): PMNode[] {\r\n const schema = editor.state.schema;\r\n const paragraphs = text.split(/\\n\\n+/);\r\n return paragraphs\r\n .filter(p => p.trim().length > 0)\r\n .map(p => {\r\n const content = p.replace(/\\n/g, ' ').trim();\r\n return schema.nodes.paragraph.create(\r\n null,\r\n content ? schema.text(content) : undefined\r\n );\r\n });\r\n}\r\n","import Document from '@tiptap/extension-document';\r\nimport Paragraph from '@tiptap/extension-paragraph';\r\nimport Text from '@tiptap/extension-text';\r\nimport Heading from '@tiptap/extension-heading';\r\nimport BulletList from '@tiptap/extension-bullet-list';\r\nimport OrderedList from '@tiptap/extension-ordered-list';\r\nimport ListItem from '@tiptap/extension-list-item';\r\nimport Blockquote from '@tiptap/extension-blockquote';\r\nimport CodeBlock from '@tiptap/extension-code-block';\r\nimport HorizontalRule from '@tiptap/extension-horizontal-rule';\r\nimport TaskList from '@tiptap/extension-task-list';\r\nimport TaskItem from '@tiptap/extension-task-item';\r\nimport Image from '@tiptap/extension-image';\r\nimport { Table } from '@tiptap/extension-table';\r\nimport TableRow from '@tiptap/extension-table-row';\r\nimport TableCell from '@tiptap/extension-table-cell';\r\nimport TableHeader from '@tiptap/extension-table-header';\r\nimport Placeholder from '@tiptap/extension-placeholder';\r\nimport History from '@tiptap/extension-history';\r\nimport { Extension, Node } from '@tiptap/react';\r\nimport { dropCursor } from 'prosemirror-dropcursor';\r\nimport { gapCursor } from 'prosemirror-gapcursor';\r\nimport TextAlign from '@tiptap/extension-text-align';\r\nimport { SlashCommand } from '../extensions/slashCommand';\r\nimport { createSlashSuggestion } from '../../components/SlashMenu';\r\nimport { SearchReplace } from '../extensions/searchReplace';\r\nimport { createPatchDiffPlugin } from '../ai/patchDiff';\r\n\r\nconst HardBreak = Node.create({\r\n name: 'hardBreak',\r\n inline: true,\r\n group: 'inline',\r\n selectable: false,\r\n parseHTML() {\r\n return [{ tag: 'br' }];\r\n },\r\n renderHTML() {\r\n return ['br'];\r\n },\r\n addKeyboardShortcuts() {\r\n return {\r\n 'Shift-Enter': () => {\r\n const nodeType = this.editor.schema.nodes.hardBreak;\r\n if (!nodeType) return false;\r\n const tr = this.editor.state.tr.replaceSelectionWith(nodeType.create()).scrollIntoView();\r\n this.editor.view.dispatch(tr);\r\n return true;\r\n },\r\n };\r\n },\r\n});\r\n\r\nconst DragDropUX = Extension.create({\r\n name: 'dragDropUX',\r\n addProseMirrorPlugins() {\r\n return [\r\n dropCursor({\r\n width: 3,\r\n color: '#2563eb',\r\n }),\r\n gapCursor(),\r\n ];\r\n },\r\n});\r\n\r\nconst PatchDiffExtension = Extension.create({\r\n name: 'patchDiff',\r\n addProseMirrorPlugins() {\r\n return [createPatchDiffPlugin()];\r\n },\r\n});\r\n\r\nexport const baseNodes = [\r\n Document,\r\n Paragraph,\r\n Text,\r\n DragDropUX,\r\n Heading.configure({\r\n levels: [1, 2, 3, 4, 5, 6],\r\n }),\r\n BulletList,\r\n OrderedList,\r\n ListItem,\r\n Blockquote,\r\n CodeBlock,\r\n HardBreak,\r\n HorizontalRule,\r\n TaskList,\r\n TaskItem.configure({ nested: true }),\r\n Image.extend({\r\n addAttributes() {\r\n return {\r\n ...this.parent?.(),\r\n width: {\r\n default: null,\r\n parseHTML: (element) => element.getAttribute('width') || element.style.width || null,\r\n renderHTML: (attributes) => {\r\n if (!attributes.width) return {};\r\n return { width: attributes.width, style: `width: ${attributes.width}` };\r\n },\r\n },\r\n };\r\n },\r\n }).configure({\r\n inline: true,\r\n allowBase64: true,\r\n }),\r\n Table.configure({\r\n resizable: true,\r\n }),\r\n TableRow,\r\n TableCell,\r\n TableHeader,\r\n Placeholder.configure({\r\n placeholder: ({ node }) => {\r\n if (node.type.name === 'heading') return 'Heading';\r\n return 'Type / for commands...';\r\n },\r\n }),\r\n History,\r\n SlashCommand.configure({\r\n suggestion: createSlashSuggestion(),\r\n }),\r\n SearchReplace,\r\n TextAlign.configure({\r\n types: ['heading', 'paragraph'],\r\n defaultAlignment: 'left',\r\n }),\r\n PatchDiffExtension,\r\n];\r\n","import Bold from '@tiptap/extension-bold';\r\nimport Italic from '@tiptap/extension-italic';\r\nimport Underline from '@tiptap/extension-underline';\r\nimport Strike from '@tiptap/extension-strike';\r\nimport Code from '@tiptap/extension-code';\r\nimport Superscript from '@tiptap/extension-superscript';\r\nimport Subscript from '@tiptap/extension-subscript';\r\nimport Link from '@tiptap/extension-link';\r\nimport { TextStyle } from '@tiptap/extension-text-style';\r\nimport Color from '@tiptap/extension-color';\r\nimport Highlight from '@tiptap/extension-highlight';\r\n\r\nexport const baseMarks = [\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strike,\r\n Code,\r\n Superscript,\r\n Subscript,\r\n Link.configure({\r\n openOnClick: false,\r\n }),\r\n TextStyle,\r\n Color,\r\n Highlight.configure({ multicolor: true }),\r\n];\r\n","import { baseNodes } from './baseNodes';\r\nimport { baseMarks } from './baseMarks';\r\n\r\nexport const schemaExtensions = [\r\n ...baseNodes,\r\n ...baseMarks,\r\n];\r\n","import { CommandCompletionResult, CommandExecutionContext, CommandExecutionOptions, EditorCommand, EditorCommandDefinition } from '../../types/plugin';\r\n\r\ninterface RegisterCommandOptions {\r\n namespace?: string;\r\n override?: boolean;\r\n}\r\n\r\nexport class CommandRegistry {\r\n private commands: Map<string, EditorCommandDefinition> = new Map();\r\n\r\n private normalizeCommand(command: EditorCommand | EditorCommandDefinition): EditorCommandDefinition {\r\n if (typeof command === 'function') {\r\n return {\r\n execute: command,\r\n };\r\n }\r\n return command;\r\n }\r\n\r\n private getFullName(name: string, namespace?: string) {\r\n return namespace ? `${namespace}.${name}` : name;\r\n }\r\n\r\n register(name: string, command: EditorCommand | EditorCommandDefinition, options: RegisterCommandOptions = {}) {\r\n const fullName = this.getFullName(name, options.namespace);\r\n if (this.commands.has(fullName) && !options.override) {\r\n console.warn(`Command \"${fullName}\" is already registered.`);\r\n return fullName;\r\n }\r\n this.commands.set(fullName, this.normalizeCommand(command));\r\n return fullName;\r\n }\r\n\r\n canExecute(name: string, context: CommandExecutionContext, payload?: unknown) {\r\n const command = this.commands.get(name);\r\n if (command) {\r\n if (command.canExecute) {\r\n return command.canExecute(context, payload);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n isActive(name: string, context: CommandExecutionContext) {\r\n const command = this.commands.get(name);\r\n if (!command || !command.isActive) {\r\n return false;\r\n }\r\n return command.isActive(context);\r\n }\r\n\r\n async execute(\r\n name: string,\r\n context: CommandExecutionContext,\r\n payload?: unknown,\r\n options: CommandExecutionOptions = {}\r\n ): Promise<boolean> {\r\n const startedAt = Date.now();\r\n const useTransaction = options.transaction ?? true;\r\n const rollbackOnFail = options.rollbackOnFail ?? true;\r\n const snapshot = useTransaction ? context.editor.getJSON() : null;\r\n const command = this.commands.get(name);\r\n if (!command) {\r\n console.warn(`Command \"${name}\" not found.`);\r\n options.onComplete?.({\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n });\r\n return false;\r\n }\r\n if (!this.canExecute(name, context, payload)) {\r\n options.onComplete?.({\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n });\r\n return false;\r\n }\r\n try {\r\n const result = await command.execute(context, payload);\r\n const success = Boolean(result);\r\n if (!success && snapshot && rollbackOnFail) {\r\n context.editor.commands.setContent(snapshot);\r\n }\r\n const completed: CommandCompletionResult = {\r\n name,\r\n success,\r\n durationMs: Date.now() - startedAt,\r\n };\r\n options.onComplete?.(completed);\r\n return success;\r\n } catch (error) {\r\n if (snapshot && rollbackOnFail) {\r\n context.editor.commands.setContent(snapshot);\r\n }\r\n const completed: CommandCompletionResult = {\r\n name,\r\n success: false,\r\n durationMs: Date.now() - startedAt,\r\n error,\r\n };\r\n options.onComplete?.(completed);\r\n return false;\r\n }\r\n }\r\n\r\n getCommand(name: string) {\r\n return this.commands.get(name) || null;\r\n }\r\n\r\n getCommands() {\r\n return Array.from(this.commands.keys()).sort();\r\n }\r\n}\r\n\r\nexport const commandRegistry = new CommandRegistry();\r\n","import { Editor, Extension, Node, Mark } from '@tiptap/react';\r\nimport { CommandExecutionContext, CommandExecutionOptions, EditorPlugin, ToolbarItem } from '../../types/plugin';\r\nimport { commandRegistry } from './CommandRegistry';\r\n\r\ntype PluginLifecycleStage = 'register' | 'init' | 'stateSync' | 'destroy';\r\n\r\nexport class PluginManager {\r\n private plugins: Map<string, EditorPlugin> = new Map();\r\n private lifecycleOrder: PluginLifecycleStage[] = ['register', 'init', 'stateSync', 'destroy'];\r\n\r\n private logLifecycle(stage: PluginLifecycleStage, pluginName: string) {\r\n if (stage === 'stateSync') {\r\n return;\r\n }\r\n console.info(`[PluginManager:${stage}] ${pluginName}`);\r\n }\r\n\r\n private getOrderedPlugins() {\r\n return Array.from(this.plugins.values()).sort((a, b) => (a.priority || 0) - (b.priority || 0));\r\n }\r\n\r\n private registerPluginCommands(plugin: EditorPlugin) {\r\n if (!plugin.commands) {\r\n return;\r\n }\r\n Object.entries(plugin.commands).forEach(([commandName, command]) => {\r\n commandRegistry.register(commandName, command, { namespace: plugin.name });\r\n });\r\n }\r\n\r\n register(plugin: EditorPlugin) {\r\n if (this.plugins.has(plugin.name)) {\r\n console.warn(`Plugin \"${plugin.name}\" is already registered.`);\r\n return;\r\n }\r\n if (plugin.dependsOn && plugin.dependsOn.length > 0) {\r\n const missingDependencies = plugin.dependsOn.filter((dependency) => !this.plugins.has(dependency));\r\n if (missingDependencies.length > 0) {\r\n console.warn(`Plugin \"${plugin.name}\" has missing dependencies: ${missingDependencies.join(', ')}`);\r\n }\r\n }\r\n this.plugins.set(plugin.name, plugin);\r\n this.registerPluginCommands(plugin);\r\n this.logLifecycle('register', plugin.name);\r\n }\r\n\r\n getExtensions(): (Extension | Node | Mark)[] {\r\n const extensions: (Extension | Node | Mark)[] = [];\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.extensions) {\r\n extensions.push(...plugin.extensions);\r\n }\r\n });\r\n return extensions;\r\n }\r\n\r\n initializePlugins(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n this.logLifecycle('init', plugin.name);\r\n if (plugin.init) {\r\n plugin.init(editor);\r\n }\r\n });\r\n }\r\n\r\n notifySelectionChange(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.onSelectionChange) {\r\n plugin.onSelectionChange(editor);\r\n }\r\n });\r\n }\r\n\r\n notifyStateChange(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (plugin.onStateChange) {\r\n plugin.onStateChange(editor);\r\n }\r\n });\r\n }\r\n\r\n executeCommand(name: string, context: CommandExecutionContext, payload?: unknown, options?: CommandExecutionOptions) {\r\n return commandRegistry.execute(name, context, payload, options);\r\n }\r\n\r\n canExecuteCommand(name: string, context: CommandExecutionContext, payload?: unknown) {\r\n return commandRegistry.canExecute(name, context, payload);\r\n }\r\n\r\n isCommandActive(name: string, context: CommandExecutionContext) {\r\n return commandRegistry.isActive(name, context);\r\n }\r\n\r\n getCommandNames() {\r\n return commandRegistry.getCommands();\r\n }\r\n\r\n getLifecycleOrder() {\r\n return [...this.lifecycleOrder];\r\n }\r\n\r\n getCommandMeta(name: string) {\r\n return commandRegistry.getCommand(name);\r\n }\r\n\r\n getToolbarItems() {\r\n const items: ToolbarItem[] = [];\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n if (!plugin.toolbarItems) {\r\n return;\r\n }\r\n plugin.toolbarItems.forEach((item) => {\r\n const command = item.command.includes('.') ? item.command : `${plugin.name}.${item.command}`;\r\n items.push({\r\n ...item,\r\n command,\r\n group: item.group || 'technical',\r\n });\r\n });\r\n });\r\n return items;\r\n }\r\n\r\n destroyPlugins(editor: Editor) {\r\n this.getOrderedPlugins().forEach((plugin) => {\r\n this.logLifecycle('destroy', plugin.name);\r\n if (plugin.destroy) {\r\n plugin.destroy(editor);\r\n }\r\n });\r\n }\r\n}\r\n\r\nexport const pluginManager = new PluginManager();\r\n","import type { EditorLanguage } from '../store/editorStore';\r\n\r\ntype ClaimGraphIssueCode =\r\n | 'forward_reference'\r\n | 'self_reference'\r\n | 'cycle_dependency'\r\n | 'too_many_independent'\r\n | 'multi_dependency_conflict';\r\n\r\nconst dict = {\r\n zh: {\r\n language: '语言',\r\n bold: '加粗',\r\n italic: '斜体',\r\n underline: '下划线',\r\n referenceTarget: '引用目标',\r\n referenceTargetPlaceholder: '请选择权利要求',\r\n insertReference: '插入权利要求引用',\r\n figureReferenceTarget: '附图目标',\r\n figureReferenceTargetPlaceholder: '请选择附图',\r\n insertFigureReference: '插入附图引用',\r\n validateClaimGraph: '校验权利要求依赖图',\r\n graphPassed: '依赖图校验通过',\r\n graphIssuesFound: (count: number) => `发现 ${count} 个依赖问题`,\r\n currentClaim: (number: number) => `当前 Claim ${number}`,\r\n dependsOn: '依赖',\r\n noDependencyCandidates: '无可选前置 Claim',\r\n placeCursorToEditDependencies: '将光标放入 Claim 段落后可编辑依赖关系',\r\n deleteSelection: '删除选区',\r\n claimWorkspacePanel: 'Claim 工业化面板',\r\n claimsSectionTitle: '权利要求书',\r\n totalCount: (count: number) => `总数 ${count}`,\r\n claimsSectionEnabled: '已启用 Claims 区',\r\n claimsSectionDisabled: '未启用 Claims 区',\r\n graphIssuesCount: (count: number) => (count === 0 ? '依赖图通过' : `依赖图问题 ${count}`),\r\n createClaimsSection: '创建 Claims 区',\r\n organizeClaimsSection: '整理到 Claims 区',\r\n exportCnipaXml: '导出 CNIPA XML',\r\n exportWordMapping: '导出 Word 映射',\r\n claimDependencyTree: 'Claim 依赖树',\r\n invalidClaimReference: '无效权利要求引用',\r\n invalidFigureReference: '无效附图引用',\r\n claimLabel: (number: number) => `权利要求${number}`,\r\n claimTypeLabel: (claimType: 'independent' | 'dependent' | string) => (claimType === 'dependent' ? '从属项' : '独立项'),\r\n claimInsertHintCreated: '已自动创建 Claim 区并插入新 Claim',\r\n claimInsertHintMoved: '当前光标在区外,已放入 Claim 区',\r\n referenceNavigateTitle: '点击跳转到目标权利要求',\r\n figureReferenceNavigateTitle: '点击跳转到目标附图',\r\n referenceNavigateDisabledTitle: '引用无效,无法跳转',\r\n currentFigure: '当前附图',\r\n figureId: '图号',\r\n figureCaption: '图注',\r\n figureIdConflict: '图号重复,请使用唯一图号',\r\n figureUploadHint: '点击上传或拖拽图片',\r\n figureReplaceImage: '更换图片',\r\n figureDrawioPlaceholder: 'Draw.io 编辑器',\r\n figureContentTypeImage: '图片',\r\n figureContentTypeMermaid: 'Mermaid 图表',\r\n figureContentTypeDrawio: 'Draw.io 图表',\r\n mermaidDoubleClickToEdit: '双击编辑',\r\n mermaidDoubleClickToCreate: '双击编辑 Mermaid 图表',\r\n mermaidSaveAndRender: '保存并渲染',\r\n mermaidCancel: '取消',\r\n mermaidSyntaxError: 'Mermaid 语法错误,请修正后重试',\r\n drawioDoubleClickToEdit: '双击编辑 Draw.io 图表',\r\n // Patent book titles\r\n bookTitle_description: '说明书',\r\n // Patent title placeholder\r\n patentTitlePlaceholder: '专利名称',\r\n // Patent section titles — Invention & Utility Model\r\n sectionTitle_technical_field: '技术领域',\r\n sectionTitle_background_art: '背景技术',\r\n sectionTitle_summary: '发明内容',\r\n sectionTitle_drawing_description: '附图说明',\r\n sectionTitle_detailed_description: '具体实施方式',\r\n sectionTitle_claims: '权利要求书',\r\n sectionTitle_abstract: '摘要',\r\n sectionTitle_abstract_drawing: '摘要附图',\r\n sectionTitle_drawing_figures: '说明书附图',\r\n // Patent section titles — Design\r\n sectionTitle_design_product_name: '产品名称',\r\n sectionTitle_design_usage: '用途说明',\r\n sectionTitle_design_description: '设计说明',\r\n sectionTitle_design_views: '图片或照片',\r\n sectionTitle_design_brief: '简要说明',\r\n // Auto-save\r\n // Figure insert dropdown\r\n insertImageFigure: '图片附图',\r\n insertMermaidFigure: 'Mermaid 附图',\r\n insertDrawioFigure: 'Draw.io 附图',\r\n switchFigureType: '切换附图类型',\r\n // Patent template (removed from toolbar)\r\n // Auto-save\r\n autoSaveSaving: '保存中...',\r\n autoSaveSaved: '已保存',\r\n autoSaveError: '保存失败',\r\n // Toolbar group labels\r\n groupHistory: '历史',\r\n groupText: '文本',\r\n groupStructure: '结构',\r\n groupFormat: '格式',\r\n groupTechnical: '技术',\r\n groupPatent: '专利',\r\n // Toolbar button tooltips\r\n undo: '撤销',\r\n redo: '重做',\r\n strike: '删除线',\r\n code: '代码',\r\n superscript: '上标',\r\n subscript: '下标',\r\n paragraph: '段落',\r\n heading1: '标题 1',\r\n heading2: '标题 2',\r\n heading3: '标题 3',\r\n alignLeft: '左对齐',\r\n alignCenter: '居中对齐',\r\n alignRight: '右对齐',\r\n alignJustify: '两端对齐',\r\n bulletList: '无序列表',\r\n orderedList: '有序列表',\r\n blockquote: '引用',\r\n codeBlock: '代码块',\r\n insertTable: '插入表格',\r\n horizontalRule: '分割线',\r\n taskList: '任务列表',\r\n exportDocument: '导出文档',\r\n expand: '展开',\r\n collapse: '收起',\r\n // Plugin tooltips\r\n insertClaimBlock: '插入权利要求',\r\n insertFigureBlock: '插入附图',\r\n insertMermaidDiagram: '插入 Mermaid 图表',\r\n insertInlineMath: '插入行内公式',\r\n insertMathBlock: '插入公式块',\r\n insertDrawioDiagram: '插入 Draw.io 图表',\r\n },\r\n en: {\r\n language: 'Language',\r\n bold: 'Bold',\r\n italic: 'Italic',\r\n underline: 'Underline',\r\n referenceTarget: 'Reference target',\r\n referenceTargetPlaceholder: 'Select claim',\r\n insertReference: 'Insert claim reference',\r\n figureReferenceTarget: 'Figure target',\r\n figureReferenceTargetPlaceholder: 'Select figure',\r\n insertFigureReference: 'Insert figure reference',\r\n validateClaimGraph: 'Validate claim graph',\r\n graphPassed: 'Claim graph validated',\r\n graphIssuesFound: (count: number) => `${count} dependency issue(s) found`,\r\n currentClaim: (number: number) => `Current Claim ${number}`,\r\n dependsOn: 'Depends on',\r\n noDependencyCandidates: 'No preceding claims available',\r\n placeCursorToEditDependencies: 'Place cursor inside a Claim to edit dependencies',\r\n deleteSelection: 'Delete selection',\r\n claimWorkspacePanel: 'Claim Industrial Panel',\r\n claimsSectionTitle: 'Claims',\r\n totalCount: (count: number) => `Total ${count}`,\r\n claimsSectionEnabled: 'Claims section enabled',\r\n claimsSectionDisabled: 'Claims section disabled',\r\n graphIssuesCount: (count: number) => (count === 0 ? 'Graph valid' : `Graph issues ${count}`),\r\n createClaimsSection: 'Create Claims Section',\r\n organizeClaimsSection: 'Organize to Claims Section',\r\n exportCnipaXml: 'Export CNIPA XML',\r\n exportWordMapping: 'Export Word Mapping',\r\n claimDependencyTree: 'Claim Dependency Tree',\r\n invalidClaimReference: 'Invalid claim reference',\r\n invalidFigureReference: 'Invalid figure reference',\r\n claimLabel: (number: number) => `Claim ${number}`,\r\n claimTypeLabel: (claimType: 'independent' | 'dependent' | string) =>\r\n claimType === 'dependent' ? 'Dependent' : 'Independent',\r\n claimInsertHintCreated: 'Claims section was created and a new Claim was inserted',\r\n claimInsertHintMoved: 'Cursor is outside claims section, inserted into Claims section',\r\n referenceNavigateTitle: 'Click to navigate to target claim',\r\n figureReferenceNavigateTitle: 'Click to navigate to target figure',\r\n referenceNavigateDisabledTitle: 'Invalid reference, navigation unavailable',\r\n currentFigure: 'Current Figure',\r\n figureId: 'Figure ID',\r\n figureCaption: 'Figure Caption',\r\n figureIdConflict: 'Figure ID already exists, please use a unique value',\r\n figureUploadHint: 'Click to upload or drop an image',\r\n figureReplaceImage: 'Replace image',\r\n figureDrawioPlaceholder: 'Draw.io editor coming soon',\r\n figureContentTypeImage: 'Image',\r\n figureContentTypeMermaid: 'Mermaid Diagram',\r\n figureContentTypeDrawio: 'Draw.io Diagram',\r\n mermaidDoubleClickToEdit: 'Double-click to edit',\r\n mermaidDoubleClickToCreate: 'Double-click to edit Mermaid diagram',\r\n mermaidSaveAndRender: 'Save & Render',\r\n mermaidCancel: 'Cancel',\r\n mermaidSyntaxError: 'Mermaid syntax error, please fix and retry',\r\n drawioDoubleClickToEdit: 'Double-click to edit Draw.io diagram (coming soon)',\r\n bookTitle_description: 'Description',\r\n patentTitlePlaceholder: 'Patent Title',\r\n sectionTitle_technical_field: 'Technical Field',\r\n sectionTitle_background_art: 'Background Art',\r\n sectionTitle_summary: 'Summary of Invention',\r\n sectionTitle_drawing_description: 'Brief Description of Drawings',\r\n sectionTitle_detailed_description: 'Detailed Description',\r\n sectionTitle_claims: 'Claims',\r\n sectionTitle_abstract: 'Abstract',\r\n sectionTitle_abstract_drawing: 'Abstract Drawing',\r\n sectionTitle_drawing_figures: 'Description Drawings',\r\n sectionTitle_design_product_name: 'Product Name',\r\n sectionTitle_design_usage: 'Usage Description',\r\n sectionTitle_design_description: 'Design Description',\r\n sectionTitle_design_views: 'Views (Photos/Images)',\r\n sectionTitle_design_brief: 'Brief Description',\r\n insertImageFigure: 'Image Figure',\r\n insertMermaidFigure: 'Mermaid Figure',\r\n insertDrawioFigure: 'Draw.io Figure',\r\n switchFigureType: 'Switch figure type',\r\n // Patent template keys removed from toolbar\r\n patentTemplateTooltip: 'Insert patent document template',\r\n autoSaveSaving: 'Saving...',\r\n autoSaveSaved: 'Saved',\r\n autoSaveError: 'Save failed',\r\n // Toolbar group labels\r\n groupHistory: 'History',\r\n groupText: 'Text',\r\n groupStructure: 'Structure',\r\n groupFormat: 'Format',\r\n groupTechnical: 'Technical',\r\n groupPatent: 'Patent',\r\n // Toolbar button tooltips\r\n undo: 'Undo',\r\n redo: 'Redo',\r\n strike: 'Strike',\r\n code: 'Code',\r\n superscript: 'Superscript',\r\n subscript: 'Subscript',\r\n paragraph: 'Paragraph',\r\n heading1: 'Heading 1',\r\n heading2: 'Heading 2',\r\n heading3: 'Heading 3',\r\n alignLeft: 'Align Left',\r\n alignCenter: 'Align Center',\r\n alignRight: 'Align Right',\r\n alignJustify: 'Justify',\r\n bulletList: 'Bullet List',\r\n orderedList: 'Ordered List',\r\n blockquote: 'Blockquote',\r\n codeBlock: 'Code Block',\r\n insertTable: 'Insert Table',\r\n horizontalRule: 'Horizontal Rule',\r\n taskList: 'Task List',\r\n exportDocument: 'Export Document',\r\n expand: 'Expand',\r\n collapse: 'Collapse',\r\n // Plugin tooltips\r\n insertClaimBlock: 'Insert claim block',\r\n insertFigureBlock: 'Insert figure block',\r\n insertMermaidDiagram: 'Insert Mermaid diagram',\r\n insertInlineMath: 'Insert inline math',\r\n insertMathBlock: 'Insert math block',\r\n insertDrawioDiagram: 'Insert Draw.io diagram',\r\n },\r\n} as const;\r\n\r\nexport const getEditorText = (language: EditorLanguage) => {\r\n return language === 'en' ? dict.en : dict.zh;\r\n};\r\n\r\nexport const formatClaimGraphIssueMessage = (\r\n language: EditorLanguage,\r\n code: ClaimGraphIssueCode,\r\n claimNumber: number,\r\n targetNumber?: number\r\n) => {\r\n if (language === 'en') {\r\n if (code === 'forward_reference') {\r\n return `Claim ${claimNumber} references later claim ${targetNumber}.`;\r\n }\r\n if (code === 'self_reference') {\r\n return `Claim ${claimNumber} references itself.`;\r\n }\r\n return `Claim ${claimNumber} has circular dependency.`;\r\n }\r\n if (code === 'forward_reference') {\r\n return `权利要求${claimNumber}引用了后置项权利要求${targetNumber}。`;\r\n }\r\n if (code === 'self_reference') {\r\n return `权利要求${claimNumber}引用了自身。`;\r\n }\r\n return `权利要求${claimNumber}存在循环依赖。`;\r\n};\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nlet mermaidIdCounter = 0;\r\n\r\nconst cleanupOrphans = () => {\r\n document.querySelectorAll('body > svg[id^=\"standalone-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > svg[id^=\"d\"]').forEach((el) => {\r\n if (el.id.startsWith('dmermaid') || el.id.startsWith('dstandalone')) el.remove();\r\n });\r\n document.querySelectorAll('body > div[id^=\"dstandalone-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > div[id^=\"dmermaid\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > div[id^=\"standalone-mermaid-\"]').forEach((el) => el.remove());\r\n};\r\n\r\nexport const MermaidNode = Node.create({\r\n name: 'mermaid',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n code: { default: 'graph TD; A-->B;' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"mermaid\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'mermaid' })];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let editMode = false;\r\n\r\n const dom = document.createElement('div');\r\n dom.classList.add('mermaid-node');\r\n\r\n // View mode: SVG preview + hint\r\n const viewContainer = document.createElement('div');\r\n viewContainer.className = 'mermaid-view';\r\n viewContainer.contentEditable = 'false';\r\n\r\n const preview = document.createElement('div');\r\n preview.className = 'mermaid-preview';\r\n preview.contentEditable = 'false';\r\n\r\n const viewHint = document.createElement('div');\r\n viewHint.className = 'mermaid-view-hint';\r\n\r\n viewContainer.append(preview, viewHint);\r\n\r\n // Edit mode: textarea + toolbar\r\n const editContainer = document.createElement('div');\r\n editContainer.className = 'mermaid-edit';\r\n\r\n const textarea = document.createElement('textarea');\r\n textarea.className = 'mermaid-editor-textarea';\r\n textarea.spellcheck = false;\r\n\r\n const toolbar = document.createElement('div');\r\n toolbar.className = 'mermaid-edit-toolbar';\r\n\r\n const errorMsg = document.createElement('span');\r\n errorMsg.className = 'mermaid-error-msg';\r\n\r\n const cancelBtn = document.createElement('button');\r\n cancelBtn.className = 'mermaid-cancel-btn';\r\n cancelBtn.type = 'button';\r\n\r\n const saveBtn = document.createElement('button');\r\n saveBtn.className = 'mermaid-save-btn';\r\n saveBtn.type = 'button';\r\n\r\n toolbar.append(errorMsg, cancelBtn, saveBtn);\r\n editContainer.append(textarea, toolbar);\r\n\r\n dom.append(viewContainer, editContainer);\r\n\r\n // Helpers\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n let lastRenderedCode = '';\r\n\r\n const doRender = async (code: string) => {\r\n const trimmed = code.trim();\r\n if (trimmed === lastRenderedCode) return;\r\n if (!trimmed) {\r\n preview.innerHTML = '';\r\n lastRenderedCode = '';\r\n return;\r\n }\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `standalone-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n preview.innerHTML = svg;\r\n lastRenderedCode = trimmed;\r\n } catch {\r\n preview.innerHTML = '';\r\n lastRenderedCode = '';\r\n } finally {\r\n cleanupOrphans();\r\n }\r\n };\r\n\r\n const enterEditMode = () => {\r\n if (editMode) return;\r\n editMode = true;\r\n textarea.value = typeof currentNode.attrs.code === 'string' ? currentNode.attrs.code : '';\r\n errorMsg.textContent = '';\r\n errorMsg.style.display = 'none';\r\n renderUI();\r\n requestAnimationFrame(() => textarea.focus());\r\n };\r\n\r\n const exitEditMode = () => {\r\n editMode = false;\r\n renderUI();\r\n };\r\n\r\n const saveAndRender = async () => {\r\n const code = textarea.value;\r\n errorMsg.textContent = '';\r\n errorMsg.style.display = 'none';\r\n\r\n const trimmed = code.trim();\r\n if (trimmed) {\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `standalone-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n preview.innerHTML = svg;\r\n lastRenderedCode = trimmed;\r\n cleanupOrphans();\r\n } catch {\r\n cleanupOrphans();\r\n const language = useEditorStore.getState().editorLanguage;\r\n errorMsg.textContent = language === 'en'\r\n ? 'Mermaid syntax error, please fix and retry'\r\n : 'Mermaid 语法错误,请修正后重试';\r\n errorMsg.style.display = 'inline';\r\n return;\r\n }\r\n }\r\n\r\n setNodeAttrs({ code });\r\n editMode = false;\r\n renderUI();\r\n };\r\n\r\n viewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterEditMode();\r\n });\r\n\r\n saveBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n void saveAndRender();\r\n });\r\n\r\n cancelBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n exitEditMode();\r\n });\r\n\r\n textarea.addEventListener('mousedown', (e) => e.stopPropagation());\r\n textarea.addEventListener('keydown', (e) => e.stopPropagation());\r\n textarea.addEventListener('keypress', (e) => e.stopPropagation());\r\n\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const code = typeof currentNode.attrs.code === 'string' ? currentNode.attrs.code : '';\r\n\r\n viewContainer.style.display = !editMode ? 'block' : 'none';\r\n editContainer.style.display = editMode ? 'block' : 'none';\r\n\r\n saveBtn.textContent = (i18n.mermaidSaveAndRender as string) || '保存并渲染';\r\n cancelBtn.textContent = (i18n.mermaidCancel as string) || '取消';\r\n\r\n const hasCode = code.trim().length > 0;\r\n const hasSvg = preview.querySelector('svg') !== null;\r\n if (!editMode) {\r\n if (hasCode && hasSvg) {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n viewHint.className = 'mermaid-view-hint mermaid-view-hint--subtle';\r\n } else {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToCreate as string) || '双击编辑 Mermaid 图表';\r\n viewHint.className = 'mermaid-view-hint mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n if (!editMode && code.trim() !== lastRenderedCode) {\r\n void doRender(code);\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n stopEvent: (event: Event) => {\r\n const target = event.target;\r\n if (target === textarea) return true;\r\n if (editContainer.contains(target as globalThis.Node)) return true;\r\n return false;\r\n },\r\n ignoreMutation: () => true,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'mermaid') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n cleanupOrphans();\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { MermaidNode } from './mermaidNode';\r\n\r\nexport const MermaidPlugin: EditorPlugin = {\r\n name: 'mermaid',\r\n version: '1.0.0',\r\n extensions: [MermaidNode],\r\n toolbarItems: [\r\n {\r\n id: 'mermaid-insert',\r\n label: 'Mermaid',\r\n command: 'insert',\r\n group: 'technical',\r\n tooltip: 'Insert Mermaid diagram',\r\n tooltipZh: '插入 Mermaid 图表',\r\n icon: 'GitGraph',\r\n shortcut: 'Ctrl+Shift+M',\r\n },\r\n ],\r\n commands: {\r\n insert: {\r\n description: 'Insert Mermaid diagram block',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+M',\r\n isActive: ({ editor }) => editor.isActive('mermaid'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { code?: string }) : {};\r\n const code = data.code || 'graph TD; A-->B;';\r\n return editor.chain().focus().insertContent({ type: 'mermaid', attrs: { code } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport const DrawioNode = Node.create({\r\n name: 'drawio',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n xml: { default: '' },\r\n svg: { default: '' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"drawio\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'drawio' })];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let editMode = false;\r\n\r\n const dom = document.createElement('div');\r\n dom.classList.add('drawio-node');\r\n\r\n // View mode: image preview + hint\r\n const viewContainer = document.createElement('div');\r\n viewContainer.className = 'drawio-view';\r\n viewContainer.contentEditable = 'false';\r\n\r\n const previewImg = document.createElement('img');\r\n previewImg.className = 'drawio-preview-img';\r\n previewImg.style.display = 'none';\r\n\r\n const viewHint = document.createElement('div');\r\n viewHint.className = 'drawio-view-hint';\r\n\r\n viewContainer.append(previewImg, viewHint);\r\n dom.append(viewContainer);\r\n\r\n // Helpers\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n // Modal editing\r\n let drawioMessageHandler: ((ev: MessageEvent) => void) | null = null;\r\n let drawioModal: HTMLDivElement | null = null;\r\n let drawioIframe: HTMLIFrameElement | null = null;\r\n\r\n const enterEditMode = () => {\r\n if (editMode) return;\r\n editMode = true;\r\n\r\n drawioModal = document.createElement('div');\r\n drawioModal.className = 'drawio-modal-overlay';\r\n\r\n const modalContent = document.createElement('div');\r\n modalContent.className = 'drawio-modal-content';\r\n\r\n const modalHeader = document.createElement('div');\r\n modalHeader.className = 'drawio-modal-header';\r\n\r\n const language = useEditorStore.getState().editorLanguage;\r\n const modalTitle = document.createElement('span');\r\n modalTitle.textContent = language === 'en' ? 'Edit Draw.io Diagram' : '编辑 Draw.io 图表';\r\n modalTitle.className = 'drawio-modal-title';\r\n\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'drawio-modal-close-btn';\r\n closeBtn.textContent = '✕';\r\n closeBtn.type = 'button';\r\n closeBtn.addEventListener('click', () => exitEditMode());\r\n\r\n modalHeader.append(modalTitle, closeBtn);\r\n\r\n drawioIframe = document.createElement('iframe');\r\n drawioIframe.className = 'drawio-modal-iframe';\r\n drawioIframe.setAttribute('frameborder', '0');\r\n\r\n modalContent.append(modalHeader, drawioIframe);\r\n drawioModal.appendChild(modalContent);\r\n document.body.appendChild(drawioModal);\r\n\r\n const lang = language === 'en' ? 'en' : 'zh';\r\n drawioIframe.src = `https://embed.diagrams.net/?embed=1&proto=json&spin=1&lang=${lang}`;\r\n\r\n const iframeRef = drawioIframe;\r\n drawioMessageHandler = (ev: MessageEvent) => {\r\n if (!iframeRef || ev.source !== iframeRef.contentWindow) return;\r\n let msg: { event?: string; xml?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n const existingXml = typeof currentNode.attrs.xml === 'string' ? currentNode.attrs.xml : '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: existingXml || '' }), '*'\r\n );\r\n } else if (msg.event === 'save') {\r\n const xml = msg.xml || '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n setNodeAttrs({ xml });\r\n } else if (msg.event === 'export') {\r\n const svgData = msg.data || '';\r\n setNodeAttrs({ svg: svgData });\r\n exitEditMode();\r\n } else if (msg.event === 'exit') {\r\n exitEditMode();\r\n }\r\n };\r\n window.addEventListener('message', drawioMessageHandler);\r\n };\r\n\r\n const exitEditMode = () => {\r\n editMode = false;\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n renderUI();\r\n };\r\n\r\n viewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterEditMode();\r\n });\r\n\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const svgData = typeof currentNode.attrs.svg === 'string' ? currentNode.attrs.svg : '';\r\n\r\n if (svgData) {\r\n previewImg.src = svgData;\r\n previewImg.style.display = 'block';\r\n } else {\r\n previewImg.src = '';\r\n previewImg.style.display = 'none';\r\n }\r\n\r\n if (svgData) {\r\n viewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n viewHint.className = 'drawio-view-hint drawio-view-hint--subtle';\r\n } else {\r\n viewHint.textContent = (i18n.drawioDoubleClickToEdit as string) || '双击编辑 Draw.io 图表';\r\n viewHint.className = 'drawio-view-hint drawio-view-hint--empty';\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n ignoreMutation: () => true,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'drawio') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { DrawioNode } from './drawioNode';\r\n\r\nexport const DrawioPlugin: EditorPlugin = {\r\n name: 'drawio',\r\n version: '1.0.0',\r\n extensions: [DrawioNode],\r\n toolbarItems: [\r\n {\r\n id: 'drawio-insert',\r\n label: 'Draw.io',\r\n command: 'insert',\r\n group: 'technical',\r\n tooltip: 'Insert Draw.io diagram',\r\n tooltipZh: '插入 Draw.io 图表',\r\n icon: 'Workflow',\r\n shortcut: 'Ctrl+Shift+D',\r\n },\r\n ],\r\n commands: {\r\n insert: {\r\n description: 'Insert Draw.io diagram block',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+D',\r\n isActive: ({ editor }) => editor.isActive('drawio'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { xml?: string }) : {};\r\n const xml = data.xml || '';\r\n return editor.chain().focus().insertContent({ type: 'drawio', attrs: { xml } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { NodeViewProps, NodeViewWrapper } from '@tiptap/react';\r\nimport katex from 'katex';\r\nimport 'katex/dist/katex.min.css';\r\nimport 'mathlive';\r\nimport { MathfieldElement } from 'mathlive';\r\nimport { useCallback, useEffect, useRef, useState } from 'react';\r\n\r\ndeclare global {\r\n namespace JSX {\r\n interface IntrinsicElements {\r\n 'math-field': React.DetailedHTMLProps<\r\n React.HTMLAttributes<HTMLElement>,\r\n HTMLElement\r\n > & {\r\n ref?: React.Ref<MathfieldElement>;\r\n value?: string;\r\n };\r\n }\r\n }\r\n}\r\n\r\nexport const MathComponent = ({\r\n node,\r\n updateAttributes,\r\n selected,\r\n editor,\r\n}: NodeViewProps) => {\r\n const mfRef = useRef<MathfieldElement | null>(null);\r\n const [isEditing, setIsEditing] = useState(false);\r\n const isBlock = node.type.name === 'math_block';\r\n\r\n // Refs to latest values — prevent stale closures in callbacks\r\n const isEditingRef = useRef(false);\r\n const latestUpdateAttrs = useRef(updateAttributes);\r\n const latestLatex = useRef<string>(node.attrs.latex ?? '');\r\n useEffect(() => { latestUpdateAttrs.current = updateAttributes; }, [updateAttributes]);\r\n useEffect(() => { latestLatex.current = node.attrs.latex ?? ''; }, [node.attrs.latex]);\r\n\r\n // ── Enter edit mode ────────────────────────────────────────────\r\n const enterEdit = useCallback(() => {\r\n if (isEditingRef.current) return;\r\n isEditingRef.current = true;\r\n setIsEditing(true);\r\n }, []);\r\n\r\n // ── Exit edit mode: save current math-field value ──────────────\r\n const exitEdit = useCallback(() => {\r\n if (!isEditingRef.current) return;\r\n isEditingRef.current = false;\r\n const latex = mfRef.current?.value ?? latestLatex.current;\r\n latestUpdateAttrs.current({ latex });\r\n setIsEditing(false);\r\n (globalThis as unknown as {\r\n mathVirtualKeyboard?: { hide: (opts?: { animate?: boolean }) => void };\r\n }).mathVirtualKeyboard?.hide({ animate: true });\r\n }, []);\r\n\r\n // ── Use ProseMirror `selected` only to ENTER edit mode ─────────\r\n // Never use it to exit — that caused inline math to close after one keystroke\r\n // (updateAttributes dispatches a transaction that resets inline NodeSelection)\r\n useEffect(() => {\r\n const isCollapsed = Boolean(editor?.view?.state?.selection?.empty);\r\n if (selected && isCollapsed) {\r\n enterEdit();\r\n }\r\n }, [selected, enterEdit]);\r\n\r\n // ── Auto-focus + keyboard policy when edit starts ──────────────\r\n // Bug fix: requestAnimationFrame lets the math-field web component\r\n // finish its internal initialization before we call focus()\r\n useEffect(() => {\r\n if (!isEditing) return;\r\n requestAnimationFrame(() => {\r\n const mf = mfRef.current as unknown as {\r\n virtualKeyboardMode?: string;\r\n focus?: () => void;\r\n } | null;\r\n if (!mf) return;\r\n mf.virtualKeyboardMode = 'onfocus';\r\n mf.focus?.();\r\n });\r\n }, [isEditing]);\r\n\r\n // ── Exit via focusout (blur away from math-field AND keyboard) ──\r\n useEffect(() => {\r\n if (!isEditing) return;\r\n const mf = mfRef.current;\r\n if (!mf) return;\r\n\r\n const onFocusOut = () => {\r\n setTimeout(() => {\r\n if (!isEditingRef.current) return;\r\n const active = document.activeElement;\r\n // Stay in edit mode if focus moved to math-field or MathLive keyboard\r\n if (\r\n active?.tagName === 'MATH-FIELD' ||\r\n active?.closest?.('math-field') ||\r\n active?.closest?.('.ML__keyboard') ||\r\n document.querySelector('.ML__keyboard')?.contains(active as globalThis.Node)\r\n ) return;\r\n exitEdit();\r\n }, 300);\r\n };\r\n\r\n const onKeyDown = (e: Event) => {\r\n if ((e as KeyboardEvent).key === 'Escape') exitEdit();\r\n };\r\n\r\n mf.addEventListener('focusout', onFocusOut);\r\n mf.addEventListener('keydown', onKeyDown);\r\n return () => {\r\n mf.removeEventListener('focusout', onFocusOut);\r\n mf.removeEventListener('keydown', onKeyDown);\r\n };\r\n }, [isEditing, exitEdit]);\r\n\r\n // ── Sync external latex changes into math-field (when not editing) ──\r\n useEffect(() => {\r\n if (!isEditing && mfRef.current && mfRef.current.value !== node.attrs.latex) {\r\n mfRef.current.value = node.attrs.latex ?? '';\r\n }\r\n }, [node.attrs.latex, isEditing]);\r\n\r\n // ── KaTeX preview ───────────────────────────────────────────────\r\n let markup = '';\r\n try {\r\n markup = katex.renderToString(node.attrs.latex || '', {\r\n throwOnError: false,\r\n displayMode: isBlock,\r\n });\r\n } catch {\r\n markup = node.attrs.latex || '';\r\n }\r\n\r\n return (\r\n <NodeViewWrapper\r\n as={isBlock ? 'div' : 'span'}\r\n className={isBlock ? 'math-block' : 'math-inline'}\r\n >\r\n {isEditing ? (\r\n <math-field\r\n ref={mfRef as React.Ref<MathfieldElement>}\r\n className={isBlock ? 'math-live-field math-live-field--block' : 'math-live-field'}\r\n >\r\n {node.attrs.latex}\r\n </math-field>\r\n ) : (\r\n <span className=\"math-preview\" onClick={enterEdit}>\r\n <span dangerouslySetInnerHTML={{ __html: markup }} />\r\n <span className=\"math-tooltip\">点击编辑</span>\r\n </span>\r\n )}\r\n </NodeViewWrapper>\r\n );\r\n};\r\n","import { Node, mergeAttributes, ReactNodeViewRenderer } from '@tiptap/react';\r\nimport { MathComponent } from './MathComponent';\r\n\r\nexport const MathInline = Node.create({\r\n name: 'math_inline',\r\n group: 'inline',\r\n inline: true,\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n latex: { default: 'E = mc^2' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [\r\n { tag: 'span[data-type=\"math_inline\"]' },\r\n {\r\n tag: 'span',\r\n getAttrs: (node) => {\r\n const el = node as HTMLElement;\r\n if (!el.hasAttribute('data-math')) return false;\r\n return { latex: (el.getAttribute('latex') || '').trim() };\r\n },\r\n },\r\n ];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'math_inline' })];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(MathComponent, {\r\n stopEvent: ({ event }) => {\r\n const target = event.target as HTMLElement;\r\n return (\r\n target.tagName.toLowerCase() === 'math-field' ||\r\n target.closest('math-field') !== null\r\n );\r\n },\r\n });\r\n },\r\n});\r\n\r\nexport const MathBlock = Node.create({\r\n name: 'math_block',\r\n group: 'block',\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n latex: { default: '\\\\sum_{i=1}^n i = \\\\frac{n(n+1)}{2}' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'div[data-type=\"math_block\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'math_block' })];\r\n },\r\n\r\n addNodeView() {\r\n return ReactNodeViewRenderer(MathComponent, {\r\n stopEvent: ({ event }) => {\r\n const target = event.target as HTMLElement;\r\n return (\r\n target.tagName.toLowerCase() === 'math-field' ||\r\n target.closest('math-field') !== null\r\n );\r\n },\r\n });\r\n },\r\n});\r\n","import { EditorPlugin } from '../../../types/plugin';\r\nimport { MathInline, MathBlock } from './mathNode';\r\nimport 'katex/dist/katex.min.css';\r\nexport const MathPlugin: EditorPlugin = {\r\n name: 'math',\r\n version: '1.0.0',\r\n extensions: [MathInline, MathBlock],\r\n toolbarItems: [\r\n {\r\n id: 'math-inline-insert',\r\n label: 'Math Inline',\r\n command: 'insertInline',\r\n group: 'technical',\r\n tooltip: 'Insert inline math',\r\n tooltipZh: '插入行内公式',\r\n icon: 'Sigma',\r\n shortcut: 'Ctrl+M',\r\n },\r\n {\r\n id: 'math-block-insert',\r\n label: 'Math Block',\r\n command: 'insertBlock',\r\n group: 'technical',\r\n tooltip: 'Insert math block',\r\n tooltipZh: '插入公式块',\r\n icon: 'FunctionSquare',\r\n shortcut: 'Ctrl+Shift+M',\r\n },\r\n ],\r\n commands: {\r\n insertInline: {\r\n description: 'Insert inline math formula',\r\n category: 'technical',\r\n shortcut: 'Ctrl+M',\r\n isActive: ({ editor }) => editor.isActive('math_inline'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { latex?: string }) : {};\r\n const latex = data.latex || 'E = mc^2';\r\n return editor.chain().focus().insertContent({ type: 'math_inline', attrs: { latex } }).run();\r\n },\r\n },\r\n insertBlock: {\r\n description: 'Insert block math formula',\r\n category: 'technical',\r\n shortcut: 'Ctrl+Shift+M',\r\n isActive: ({ editor }) => editor.isActive('math_block'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as { latex?: string }) : {};\r\n const latex = data.latex || '\\\\sum_{i=1}^n i = \\\\frac{n(n+1)}{2}';\r\n return editor.chain().focus().insertContent({ type: 'math_block', attrs: { latex } }).run();\r\n },\r\n },\r\n },\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\r\n\r\nexport interface NodeMatch {\r\n node: ProseMirrorNode;\r\n pos: number;\r\n}\r\n\r\nexport interface NodeQueryScope {\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport const findNodeByType = (editor: Editor, typeName: string, scope: NodeQueryScope = {}): NodeMatch | null => {\r\n const from = scope.from ?? 0;\r\n const to = scope.to ?? editor.state.doc.content.size;\r\n let matched: NodeMatch | null = null;\r\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\r\n if (matched) {\r\n return false;\r\n }\r\n if (node.type.name === typeName) {\r\n matched = { node, pos };\r\n return false;\r\n }\r\n return true;\r\n });\r\n return matched;\r\n};\r\n\r\nexport const findNodesByPredicate = (\r\n editor: Editor,\r\n predicate: (node: ProseMirrorNode, pos: number) => boolean,\r\n scope: NodeQueryScope = {}\r\n): NodeMatch[] => {\r\n const from = scope.from ?? 0;\r\n const to = scope.to ?? editor.state.doc.content.size;\r\n const matches: NodeMatch[] = [];\r\n editor.state.doc.nodesBetween(from, to, (node, pos) => {\r\n if (predicate(node, pos)) {\r\n matches.push({ node, pos });\r\n }\r\n return true;\r\n });\r\n return matches;\r\n};\r\n\r\nexport const findAncestorNode = (\r\n editor: Editor,\r\n predicate: string | ((node: ProseMirrorNode) => boolean)\r\n): NodeMatch | null => {\r\n const { $from } = editor.state.selection;\r\n for (let depth = $from.depth; depth >= 0; depth -= 1) {\r\n const node = $from.node(depth);\r\n const matched = typeof predicate === 'string' ? node.type.name === predicate : predicate(node);\r\n if (matched) {\r\n return {\r\n node,\r\n pos: depth === 0 ? 0 : $from.before(depth),\r\n };\r\n }\r\n }\r\n return null;\r\n};\r\n\r\nexport const findCurrentBlock = (editor: Editor): NodeMatch | null => {\r\n const { $from } = editor.state.selection;\r\n for (let depth = $from.depth; depth >= 0; depth -= 1) {\r\n const node = $from.node(depth);\r\n if (node.isBlock) {\r\n return {\r\n node,\r\n pos: depth === 0 ? 0 : $from.before(depth),\r\n };\r\n }\r\n }\r\n return null;\r\n};\r\n","import { Editor, JSONContent } from '@tiptap/react';\r\nimport { NodeType } from '@tiptap/pm/model';\r\nimport { findWrapping } from '@tiptap/pm/transform';\r\nimport { findNodeByType } from './nodeQueries';\r\n\r\ntype JSONBlockContent = JSONContent | JSONContent[];\r\n\r\ninterface InsertNodeInput {\r\n type: string;\r\n attrs?: Record<string, unknown>;\r\n content?: JSONBlockContent;\r\n position?: number;\r\n}\r\n\r\ninterface UpdateNodeAttrsInput {\r\n type?: string;\r\n position?: number;\r\n attrs: Record<string, unknown>;\r\n}\r\n\r\ninterface RemoveNodeInput {\r\n type?: string;\r\n position?: number;\r\n}\r\n\r\ninterface WrapSelectionInput {\r\n type: string;\r\n attrs?: Record<string, unknown>;\r\n}\r\n\r\ntype BatchOperation =\r\n | { type: 'insertNode'; payload: InsertNodeInput }\r\n | { type: 'updateNodeAttrs'; payload: UpdateNodeAttrsInput }\r\n | { type: 'removeNode'; payload: RemoveNodeInput }\r\n | { type: 'wrapSelection'; payload: WrapSelectionInput };\r\n\r\nconst getNodeType = (editor: Editor, name: string): NodeType | null => {\r\n return editor.state.schema.nodes[name] || null;\r\n};\r\n\r\nconst buildNodeContent = (input: InsertNodeInput): JSONContent => {\r\n const normalizedContent = Array.isArray(input.content)\r\n ? input.content\r\n : input.content\r\n ? [input.content]\r\n : undefined;\r\n return {\r\n type: input.type,\r\n attrs: input.attrs,\r\n content: normalizedContent,\r\n };\r\n};\r\n\r\nexport const insertNode = (editor: Editor, input: InsertNodeInput): boolean => {\r\n const content = buildNodeContent(input);\r\n if (typeof input.position === 'number') {\r\n return editor.chain().focus().insertContentAt(input.position, content).run();\r\n }\r\n return editor.chain().focus().insertContent(content).run();\r\n};\r\n\r\nexport const updateNodeAttrs = (editor: Editor, input: UpdateNodeAttrsInput): boolean => {\r\n if (typeof input.position !== 'number' && !input.type) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const targetPos =\r\n typeof input.position === 'number' ? input.position : findNodeByType(editor, input.type || '')?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const node = state.doc.nodeAt(targetPos);\r\n if (!node) {\r\n return false;\r\n }\r\n if (input.type && node.type.name !== input.type) {\r\n return false;\r\n }\r\n const attrs = { ...node.attrs, ...input.attrs };\r\n tr.setNodeMarkup(targetPos, undefined, attrs);\r\n if (dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport const removeNode = (editor: Editor, input: RemoveNodeInput): boolean => {\r\n if (typeof input.position !== 'number' && !input.type) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const targetPos =\r\n typeof input.position === 'number' ? input.position : findNodeByType(editor, input.type || '')?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const node = state.doc.nodeAt(targetPos);\r\n if (!node) {\r\n return false;\r\n }\r\n if (input.type && node.type.name !== input.type) {\r\n return false;\r\n }\r\n tr.delete(targetPos, targetPos + node.nodeSize);\r\n if (dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport const wrapSelection = (editor: Editor, input: WrapSelectionInput): boolean => {\r\n const nodeType = getNodeType(editor, input.type);\r\n if (!nodeType) {\r\n return false;\r\n }\r\n return editor.commands.command(({ tr, state, dispatch }) => {\r\n const { from, to } = state.selection;\r\n const range = state.selection.$from.blockRange(state.selection.$to);\r\n if (!range) {\r\n return false;\r\n }\r\n const wrapping = findWrapping(range, nodeType, input.attrs);\r\n if (!wrapping) {\r\n return false;\r\n }\r\n tr.wrap(range, wrapping);\r\n if (dispatch) {\r\n dispatch(tr.scrollIntoView());\r\n }\r\n return from <= to;\r\n });\r\n};\r\n\r\nexport const applyTransactionBatch = (editor: Editor, operations: BatchOperation[]): boolean => {\r\n if (operations.length === 0) {\r\n return false;\r\n }\r\n const snapshot = editor.getJSON();\r\n for (const operation of operations) {\r\n const success =\r\n operation.type === 'insertNode'\r\n ? insertNode(editor, operation.payload)\r\n : operation.type === 'updateNodeAttrs'\r\n ? updateNodeAttrs(editor, operation.payload)\r\n : operation.type === 'removeNode'\r\n ? removeNode(editor, operation.payload)\r\n : wrapSelection(editor, operation.payload);\r\n if (!success) {\r\n editor.commands.setContent(snapshot);\r\n return false;\r\n }\r\n }\r\n return true;\r\n};\r\n\r\nexport type { BatchOperation, InsertNodeInput, RemoveNodeInput, UpdateNodeAttrsInput, WrapSelectionInput };\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { TextSelection } from '@tiptap/pm/state';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport type FigureContentType = 'image' | 'mermaid' | 'drawio';\r\n\r\nlet mermaidIdCounter = 0;\r\n\r\n// ====== Drawio auto-SVG generation queue ======\r\n// Reuses a single hidden diagrams.net iframe to avoid repeated resource loads\r\n// (e.g. dia_zh.txt). Also caches XML→SVG results to skip duplicate exports.\r\ntype SvgGenTask = { xml: string; callback: (svg: string) => void };\r\nconst _svgGenQueue: SvgGenTask[] = [];\r\nlet _svgGenBusy = false;\r\nconst _SVG_GEN_TIMEOUT_MS = 20000;\r\nconst _IDLE_DESTROY_MS = 60000;\r\n\r\nlet _sharedIframe: HTMLIFrameElement | null = null;\r\nlet _sharedIframeReady = false;\r\nlet _currentMsgHandler: ((ev: MessageEvent) => void) | null = null;\r\nlet _idleTimer: ReturnType<typeof setTimeout> | null = null;\r\nconst _svgCache = new Map<string, string>();\r\n\r\nfunction _destroySharedIframe() {\r\n if (_currentMsgHandler) {\r\n window.removeEventListener('message', _currentMsgHandler);\r\n _currentMsgHandler = null;\r\n }\r\n if (_sharedIframe) {\r\n _sharedIframe.src = 'about:blank';\r\n _sharedIframe.remove();\r\n _sharedIframe = null;\r\n }\r\n _sharedIframeReady = false;\r\n}\r\n\r\nfunction queueDrawioSvgGen(xml: string, callback: (svg: string) => void) {\r\n const cached = _svgCache.get(xml);\r\n if (cached) { callback(cached); return; }\r\n _svgGenQueue.push({ xml, callback });\r\n _processNextSvgGen();\r\n}\r\n\r\nfunction _processNextSvgGen() {\r\n if (_svgGenBusy || _svgGenQueue.length === 0) return;\r\n _svgGenBusy = true;\r\n if (_idleTimer) { clearTimeout(_idleTimer); _idleTimer = null; }\r\n\r\n const { xml, callback } = _svgGenQueue.shift()!;\r\n const cached = _svgCache.get(xml);\r\n if (cached) {\r\n callback(cached);\r\n _svgGenBusy = false;\r\n _idleTimer = setTimeout(_destroySharedIframe, _IDLE_DESTROY_MS);\r\n _processNextSvgGen();\r\n return;\r\n }\r\n\r\n if (_currentMsgHandler) {\r\n window.removeEventListener('message', _currentMsgHandler);\r\n _currentMsgHandler = null;\r\n }\r\n\r\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n\r\n const done = (svg: string) => {\r\n if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; }\r\n if (svg) _svgCache.set(xml, svg);\r\n callback(svg);\r\n _svgGenBusy = false;\r\n _idleTimer = setTimeout(_destroySharedIframe, _IDLE_DESTROY_MS);\r\n _processNextSvgGen();\r\n };\r\n\r\n const sendLoad = () => {\r\n _sharedIframe!.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: xml || '' }), '*'\r\n );\r\n };\r\n\r\n _currentMsgHandler = (ev: MessageEvent) => {\r\n if (!_sharedIframe || ev.source !== _sharedIframe.contentWindow) return;\r\n let msg: { event?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n _sharedIframeReady = true;\r\n sendLoad();\r\n } else if (msg.event === 'load') {\r\n setTimeout(() => {\r\n _sharedIframe?.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n }, 1500);\r\n } else if (msg.event === 'export') {\r\n done(msg.data || '');\r\n }\r\n };\r\n\r\n window.addEventListener('message', _currentMsgHandler);\r\n timeoutId = setTimeout(() => done(''), _SVG_GEN_TIMEOUT_MS);\r\n\r\n if (!_sharedIframe) {\r\n _sharedIframe = document.createElement('iframe');\r\n _sharedIframe.style.cssText = 'position:fixed;left:-9999px;top:-9999px;width:1920px;height:1080px;opacity:0;pointer-events:none;';\r\n document.body.appendChild(_sharedIframe);\r\n _sharedIframeReady = false;\r\n _sharedIframe.src = 'https://embed.diagrams.net/?embed=1&proto=json&spin=0&chrome=0';\r\n } else if (_sharedIframeReady) {\r\n sendLoad();\r\n }\r\n}\r\n\r\nconst cleanupMermaidOrphans = () => {\r\n document.querySelectorAll('body > svg[id^=\"fig-mermaid-\"]').forEach((el) => el.remove());\r\n document.querySelectorAll('body > svg[id^=\"d\"]').forEach((el) => {\r\n if (el.id.startsWith('dmermaid') || el.id.startsWith('dfi')) el.remove();\r\n });\r\n document.querySelectorAll('body > #dmermaid-svg').forEach((el) => el.remove());\r\n document.querySelectorAll('body > style[data-mermaid-style]').forEach((el) => el.remove());\r\n};\r\n\r\nexport const FigureNode = Node.create({\r\n name: 'figure',\r\n group: 'block',\r\n content: 'inline*',\r\n draggable: true,\r\n isolating: true,\r\n\r\n addAttributes() {\r\n return {\r\n id: { default: null },\r\n contentType: { default: 'image' as FigureContentType },\r\n imageSrc: { default: '' },\r\n mermaidCode: { default: '' },\r\n drawioXml: { default: '' },\r\n drawioSvg: { default: '' },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'figure[data-type=\"figure\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'figure',\r\n mergeAttributes(HTMLAttributes, { 'data-type': 'figure', class: 'figure-block' }),\r\n ['figcaption', { class: 'figure-caption' }, 0],\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n let mermaidEditMode = false;\r\n let drawioEditMode = false;\r\n\r\n const dom = document.createElement('figure');\r\n dom.setAttribute('data-type', 'figure');\r\n dom.className = 'figure-block';\r\n\r\n // --- Visual area (non-editable, managed by NodeView) ---\r\n const visual = document.createElement('div');\r\n visual.className = 'figure-visual';\r\n visual.contentEditable = 'false';\r\n visual.setAttribute('spellcheck', 'false');\r\n\r\n // ====== Image elements ======\r\n const imgEl = document.createElement('img');\r\n imgEl.className = 'figure-img-preview';\r\n\r\n const uploadArea = document.createElement('div');\r\n uploadArea.className = 'figure-upload-area';\r\n\r\n const uploadHint = document.createElement('span');\r\n uploadHint.className = 'figure-upload-hint';\r\n\r\n const fileInput = document.createElement('input');\r\n fileInput.type = 'file';\r\n fileInput.accept = 'image/*';\r\n fileInput.style.display = 'none';\r\n\r\n const replaceBtn = document.createElement('button');\r\n replaceBtn.className = 'figure-replace-btn';\r\n\r\n uploadArea.append(uploadHint, fileInput);\r\n\r\n // ====== Mermaid elements ======\r\n // View mode: preview area (rendered SVG or placeholder)\r\n const mermaidViewContainer = document.createElement('div');\r\n mermaidViewContainer.className = 'figure-mermaid-view';\r\n mermaidViewContainer.contentEditable = 'false';\r\n mermaidViewContainer.setAttribute('spellcheck', 'false');\r\n\r\n const mermaidPreview = document.createElement('div');\r\n mermaidPreview.className = 'figure-mermaid-preview';\r\n mermaidPreview.contentEditable = 'false';\r\n\r\n const mermaidViewHint = document.createElement('div');\r\n mermaidViewHint.className = 'figure-mermaid-view-hint';\r\n\r\n mermaidViewContainer.append(mermaidPreview, mermaidViewHint);\r\n\r\n // Edit mode: textarea + toolbar\r\n const mermaidEditContainer = document.createElement('div');\r\n mermaidEditContainer.className = 'figure-mermaid-edit';\r\n\r\n const mermaidEditor = document.createElement('textarea');\r\n mermaidEditor.className = 'figure-mermaid-editor';\r\n mermaidEditor.spellcheck = false;\r\n\r\n const mermaidToolbar = document.createElement('div');\r\n mermaidToolbar.className = 'figure-mermaid-toolbar';\r\n\r\n const mermaidSaveBtn = document.createElement('button');\r\n mermaidSaveBtn.className = 'figure-mermaid-save-btn';\r\n mermaidSaveBtn.type = 'button';\r\n\r\n const mermaidCancelBtn = document.createElement('button');\r\n mermaidCancelBtn.className = 'figure-mermaid-cancel-btn';\r\n mermaidCancelBtn.type = 'button';\r\n\r\n const mermaidErrorMsg = document.createElement('span');\r\n mermaidErrorMsg.className = 'figure-mermaid-error-inline';\r\n\r\n mermaidToolbar.append(mermaidErrorMsg, mermaidCancelBtn, mermaidSaveBtn);\r\n mermaidEditContainer.append(mermaidEditor, mermaidToolbar);\r\n\r\n // ====== DrawIO elements ======\r\n // View mode: image preview + hint\r\n const drawioViewContainer = document.createElement('div');\r\n drawioViewContainer.className = 'figure-drawio-view';\r\n drawioViewContainer.contentEditable = 'false';\r\n\r\n const drawioPreviewImg = document.createElement('img');\r\n drawioPreviewImg.className = 'figure-drawio-preview-img';\r\n drawioPreviewImg.style.display = 'none';\r\n\r\n const drawioViewHint = document.createElement('div');\r\n drawioViewHint.className = 'figure-drawio-view-hint';\r\n\r\n drawioViewContainer.append(drawioPreviewImg, drawioViewHint);\r\n\r\n // Assemble visual\r\n visual.append(imgEl, uploadArea, replaceBtn);\r\n visual.append(mermaidViewContainer, mermaidEditContainer);\r\n visual.append(drawioViewContainer);\r\n\r\n // ====== Caption ======\r\n const caption = document.createElement('figcaption');\r\n caption.className = 'figure-caption';\r\n\r\n const idLabel = document.createElement('span');\r\n idLabel.className = 'figure-id-label';\r\n idLabel.contentEditable = 'false';\r\n\r\n const captionContent = document.createElement('span');\r\n captionContent.className = 'figure-caption-content';\r\n\r\n caption.append(idLabel, captionContent);\r\n dom.append(visual, caption);\r\n\r\n // ====== Helpers ======\r\n const setNodeAttrs = (patch: Record<string, unknown>) => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n editor.commands.command(({ tr, dispatch }) => {\r\n tr.setNodeMarkup(pos, undefined, { ...currentNode.attrs, ...patch });\r\n if (dispatch) dispatch(tr);\r\n return true;\r\n });\r\n };\r\n\r\n const handleFiles = (files: FileList | null) => {\r\n if (!files || files.length === 0) return;\r\n const file = files[0];\r\n if (!file.type.startsWith('image/')) return;\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n if (typeof reader.result === 'string') {\r\n setNodeAttrs({ imageSrc: reader.result });\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n };\r\n\r\n // ====== Image events ======\r\n fileInput.addEventListener('change', () => handleFiles(fileInput.files));\r\n uploadArea.addEventListener('click', () => fileInput.click());\r\n replaceBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n fileInput.click();\r\n });\r\n\r\n visual.addEventListener('dragover', (e) => {\r\n if (currentNode.attrs.contentType !== 'image') return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n uploadArea.classList.add('figure-upload-area--dragover');\r\n });\r\n visual.addEventListener('dragleave', () => {\r\n uploadArea.classList.remove('figure-upload-area--dragover');\r\n });\r\n visual.addEventListener('drop', (e) => {\r\n uploadArea.classList.remove('figure-upload-area--dragover');\r\n if (currentNode.attrs.contentType !== 'image') return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n handleFiles(e.dataTransfer?.files ?? null);\r\n });\r\n\r\n // ====== Mermaid: double-click to edit, save to render ======\r\n const enterMermaidEditMode = () => {\r\n if (mermaidEditMode) return;\r\n mermaidEditMode = true;\r\n mermaidEditor.value = typeof currentNode.attrs.mermaidCode === 'string'\r\n ? currentNode.attrs.mermaidCode : '';\r\n mermaidErrorMsg.textContent = '';\r\n mermaidErrorMsg.style.display = 'none';\r\n renderUI();\r\n requestAnimationFrame(() => mermaidEditor.focus());\r\n };\r\n\r\n const exitMermaidEditMode = () => {\r\n mermaidEditMode = false;\r\n renderUI();\r\n };\r\n\r\n const saveMermaidAndRender = async () => {\r\n const code = mermaidEditor.value;\r\n mermaidErrorMsg.textContent = '';\r\n mermaidErrorMsg.style.display = 'none';\r\n\r\n // Validate by trying to render first (don't save bad code to attrs)\r\n const trimmed = code.trim();\r\n if (trimmed) {\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `fig-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n mermaidPreview.innerHTML = svg;\r\n cleanupMermaidOrphans();\r\n } catch {\r\n cleanupMermaidOrphans();\r\n const language = useEditorStore.getState().editorLanguage;\r\n mermaidErrorMsg.textContent = language === 'en'\r\n ? 'Mermaid syntax error, please fix and retry'\r\n : 'Mermaid 语法错误,请修正后重试';\r\n mermaidErrorMsg.style.display = 'inline';\r\n return;\r\n }\r\n }\r\n\r\n setNodeAttrs({ mermaidCode: code });\r\n mermaidEditMode = false;\r\n renderUI();\r\n };\r\n\r\n mermaidViewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterMermaidEditMode();\r\n });\r\n\r\n mermaidSaveBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n void saveMermaidAndRender();\r\n });\r\n\r\n mermaidCancelBtn.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n exitMermaidEditMode();\r\n });\r\n\r\n // Prevent ProseMirror from stealing textarea events\r\n mermaidEditor.addEventListener('mousedown', (e) => e.stopPropagation());\r\n mermaidEditor.addEventListener('keydown', (e) => e.stopPropagation());\r\n mermaidEditor.addEventListener('keypress', (e) => e.stopPropagation());\r\n\r\n // ====== DrawIO: double-click to edit via full-screen modal ======\r\n let drawioMessageHandler: ((ev: MessageEvent) => void) | null = null;\r\n let drawioModal: HTMLDivElement | null = null;\r\n let drawioIframe: HTMLIFrameElement | null = null;\r\n\r\n const enterDrawioEditMode = () => {\r\n if (drawioEditMode) return;\r\n drawioEditMode = true;\r\n renderUI();\r\n\r\n // Create full-screen modal overlay\r\n drawioModal = document.createElement('div');\r\n drawioModal.className = 'drawio-modal-overlay';\r\n\r\n const modalContent = document.createElement('div');\r\n modalContent.className = 'drawio-modal-content';\r\n\r\n const modalHeader = document.createElement('div');\r\n modalHeader.className = 'drawio-modal-header';\r\n\r\n const modalTitle = document.createElement('span');\r\n const language = useEditorStore.getState().editorLanguage;\r\n modalTitle.textContent = language === 'en' ? 'Edit Draw.io Diagram' : '编辑 Draw.io 图表';\r\n modalTitle.className = 'drawio-modal-title';\r\n\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'drawio-modal-close-btn';\r\n closeBtn.textContent = '✕';\r\n closeBtn.type = 'button';\r\n closeBtn.addEventListener('click', () => exitDrawioEditMode());\r\n\r\n modalHeader.append(modalTitle, closeBtn);\r\n\r\n drawioIframe = document.createElement('iframe');\r\n drawioIframe.className = 'drawio-modal-iframe';\r\n drawioIframe.setAttribute('frameborder', '0');\r\n\r\n modalContent.append(modalHeader, drawioIframe);\r\n drawioModal.appendChild(modalContent);\r\n document.body.appendChild(drawioModal);\r\n\r\n const lang = language === 'en' ? 'en' : 'zh';\r\n drawioIframe.src = `https://embed.diagrams.net/?embed=1&proto=json&spin=1&lang=${lang}`;\r\n\r\n const iframeRef = drawioIframe;\r\n drawioMessageHandler = (ev: MessageEvent) => {\r\n if (!iframeRef || ev.source !== iframeRef.contentWindow) return;\r\n let msg: { event?: string; xml?: string; data?: string };\r\n try { msg = typeof ev.data === 'string' ? JSON.parse(ev.data) : ev.data; } catch { return; }\r\n\r\n if (msg.event === 'init') {\r\n const existingXml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'load', autosave: 0, xml: existingXml || '' }), '*'\r\n );\r\n } else if (msg.event === 'save') {\r\n const xml = msg.xml || '';\r\n iframeRef.contentWindow?.postMessage(\r\n JSON.stringify({ action: 'export', format: 'svg' }), '*'\r\n );\r\n setNodeAttrs({ drawioXml: xml });\r\n } else if (msg.event === 'export') {\r\n const svgData = msg.data || '';\r\n setNodeAttrs({ drawioSvg: svgData });\r\n exitDrawioEditMode();\r\n } else if (msg.event === 'exit') {\r\n exitDrawioEditMode();\r\n }\r\n };\r\n window.addEventListener('message', drawioMessageHandler);\r\n };\r\n\r\n const exitDrawioEditMode = () => {\r\n drawioEditMode = false;\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n renderUI();\r\n };\r\n\r\n drawioViewContainer.addEventListener('dblclick', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n enterDrawioEditMode();\r\n });\r\n\r\n // ====== Click non-editable -> focus caption ======\r\n dom.addEventListener('mousedown', (event) => {\r\n const target = event.target;\r\n if (!(target instanceof HTMLElement)) return;\r\n if (target === captionContent || captionContent.contains(target)) return;\r\n if (target === mermaidEditor) return;\r\n if (mermaidEditContainer.contains(target)) return;\r\n if (target === uploadArea || uploadArea.contains(target)) return;\r\n if (target === replaceBtn) return;\r\n if (target === fileInput) return;\r\n // Don't steal focus if double-clicking mermaid/drawio view\r\n if (mermaidViewContainer.contains(target)) return;\r\n if (drawioViewContainer.contains(target)) return;\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n if (typeof pos !== 'number') return;\r\n const end = pos + currentNode.nodeSize - 1;\r\n const sel = TextSelection.create(editor.state.doc, end);\r\n editor.view.dispatch(editor.state.tr.setSelection(sel));\r\n });\r\n\r\n // ====== DrawIO: auto-generate SVG if missing ======\r\n let drawioSvgGenQueued = false;\r\n let drawioSvgDebounceTimer: ReturnType<typeof setTimeout> | null = null;\r\n let drawioSvgRetryTimer: ReturnType<typeof setTimeout> | null = null;\r\n let drawioSvgRetries = 0;\r\n const _MAX_SVG_RETRIES = 2;\r\n const _SVG_DEBOUNCE_MS = 1500;\r\n const _SVG_RETRY_DELAY_MS = 3000;\r\n\r\n // ====== Mermaid initial render (from saved attrs, view mode only) ======\r\n let lastRenderedMermaidCode = '';\r\n\r\n const doInitialMermaidRender = async (code: string) => {\r\n const trimmed = code.trim();\r\n if (trimmed === lastRenderedMermaidCode) return;\r\n\r\n if (!trimmed) {\r\n mermaidPreview.innerHTML = '';\r\n lastRenderedMermaidCode = '';\r\n return;\r\n }\r\n\r\n try {\r\n const mermaid = await import('mermaid');\r\n mermaid.default.initialize({ startOnLoad: false, theme: 'default' });\r\n mermaidIdCounter += 1;\r\n const renderId = `fig-mermaid-${mermaidIdCounter}`;\r\n const { svg } = await mermaid.default.render(renderId, trimmed);\r\n mermaidPreview.innerHTML = svg;\r\n lastRenderedMermaidCode = trimmed;\r\n } catch {\r\n mermaidPreview.innerHTML = '';\r\n lastRenderedMermaidCode = '';\r\n } finally {\r\n cleanupMermaidOrphans();\r\n }\r\n };\r\n\r\n // ====== renderUI ======\r\n const renderUI = () => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const contentType: FigureContentType = (['image', 'mermaid', 'drawio'].includes(currentNode.attrs.contentType))\r\n ? currentNode.attrs.contentType as FigureContentType\r\n : 'image';\r\n const figureId = typeof currentNode.attrs.id === 'string' ? currentNode.attrs.id.trim() : '';\r\n const imageSrc = typeof currentNode.attrs.imageSrc === 'string' ? currentNode.attrs.imageSrc : '';\r\n const mermaidCode = typeof currentNode.attrs.mermaidCode === 'string' ? currentNode.attrs.mermaidCode : '';\r\n\r\n // ID label\r\n if (figureId) {\r\n idLabel.textContent = `[${figureId}] `;\r\n idLabel.style.display = 'inline';\r\n } else {\r\n idLabel.textContent = '';\r\n idLabel.style.display = 'none';\r\n }\r\n\r\n const isImage = contentType === 'image';\r\n const isMermaid = contentType === 'mermaid';\r\n const isDrawio = contentType === 'drawio';\r\n\r\n // Image visibility\r\n imgEl.style.display = isImage && imageSrc ? 'block' : 'none';\r\n uploadArea.style.display = isImage && !imageSrc ? 'flex' : 'none';\r\n replaceBtn.style.display = isImage && imageSrc ? 'block' : 'none';\r\n\r\n // Mermaid: view / edit mode\r\n mermaidViewContainer.style.display = isMermaid && !mermaidEditMode ? 'block' : 'none';\r\n mermaidEditContainer.style.display = isMermaid && mermaidEditMode ? 'block' : 'none';\r\n\r\n // DrawIO: view mode only (edit is in modal)\r\n drawioViewContainer.style.display = isDrawio ? 'flex' : 'none';\r\n\r\n // Image src\r\n if (isImage && imageSrc) {\r\n imgEl.src = imageSrc;\r\n }\r\n\r\n // DrawIO image preview (drawioSvg is a data URI like \"data:image/svg+xml;base64,...\")\r\n const drawioSvg = typeof currentNode.attrs.drawioSvg === 'string' ? currentNode.attrs.drawioSvg : '';\r\n if (isDrawio) {\r\n if (drawioSvg) {\r\n drawioPreviewImg.src = drawioSvg;\r\n drawioPreviewImg.style.display = 'block';\r\n } else {\r\n drawioPreviewImg.src = '';\r\n drawioPreviewImg.style.display = 'none';\r\n }\r\n }\r\n\r\n // i18n texts\r\n uploadHint.textContent = (i18n.figureUploadHint as string) || '点击上传或拖拽图片';\r\n replaceBtn.textContent = (i18n.figureReplaceImage as string) || '更换图片';\r\n mermaidSaveBtn.textContent = (i18n.mermaidSaveAndRender as string) || '保存并渲染';\r\n mermaidCancelBtn.textContent = (i18n.mermaidCancel as string) || '取消';\r\n\r\n // Mermaid view mode hint\r\n const hasCode = mermaidCode.trim().length > 0;\r\n const hasSvg = mermaidPreview.querySelector('svg') !== null;\r\n if (isMermaid && !mermaidEditMode) {\r\n if (hasCode && hasSvg) {\r\n mermaidViewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n mermaidViewHint.className = 'figure-mermaid-view-hint figure-mermaid-view-hint--subtle';\r\n } else {\r\n mermaidViewHint.textContent = (i18n.mermaidDoubleClickToCreate as string) || '双击编辑 Mermaid 图表';\r\n mermaidViewHint.className = 'figure-mermaid-view-hint figure-mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n // DrawIO view hint\r\n if (isDrawio && !drawioEditMode) {\r\n if (drawioSvg) {\r\n drawioViewHint.textContent = (i18n.mermaidDoubleClickToEdit as string) || '双击编辑';\r\n drawioViewHint.className = 'figure-drawio-view-hint figure-mermaid-view-hint--subtle';\r\n } else {\r\n drawioViewHint.textContent = (i18n.drawioDoubleClickToEdit as string) || '双击编辑 Draw.io 图表';\r\n drawioViewHint.className = 'figure-drawio-view-hint figure-mermaid-view-hint--empty';\r\n }\r\n }\r\n\r\n // Trigger initial mermaid render in view mode if code exists\r\n if (isMermaid && !mermaidEditMode && mermaidCode.trim() !== lastRenderedMermaidCode) {\r\n void doInitialMermaidRender(mermaidCode);\r\n }\r\n\r\n // Auto-generate SVG for drawio figures that have XML but no SVG.\r\n // Debounced to avoid wasted attempts during rapid SSE streaming updates,\r\n // with retry on failure (e.g. iframe timeout).\r\n const drawioXml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n if (isDrawio && drawioXml && !drawioSvg && !drawioSvgGenQueued && !drawioEditMode) {\r\n if (drawioSvgDebounceTimer) clearTimeout(drawioSvgDebounceTimer);\r\n drawioSvgDebounceTimer = setTimeout(() => {\r\n drawioSvgDebounceTimer = null;\r\n const xml = typeof currentNode.attrs.drawioXml === 'string' ? currentNode.attrs.drawioXml : '';\r\n const svg = typeof currentNode.attrs.drawioSvg === 'string' ? currentNode.attrs.drawioSvg : '';\r\n if (!xml || svg || drawioSvgGenQueued) return;\r\n drawioSvgGenQueued = true;\r\n queueDrawioSvgGen(xml, (result) => {\r\n drawioSvgGenQueued = false;\r\n if (result) {\r\n drawioSvgRetries = 0;\r\n setNodeAttrs({ drawioSvg: result });\r\n } else if (drawioSvgRetries < _MAX_SVG_RETRIES) {\r\n drawioSvgRetries++;\r\n drawioSvgRetryTimer = setTimeout(() => {\r\n drawioSvgRetryTimer = null;\r\n renderUI();\r\n }, _SVG_RETRY_DELAY_MS * drawioSvgRetries);\r\n }\r\n });\r\n }, _SVG_DEBOUNCE_MS);\r\n }\r\n };\r\n\r\n let currentLanguage = useEditorStore.getState().editorLanguage;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n if (state.editorLanguage !== currentLanguage) {\r\n currentLanguage = state.editorLanguage;\r\n renderUI();\r\n }\r\n });\r\n\r\n renderUI();\r\n\r\n return {\r\n dom,\r\n contentDOM: captionContent,\r\n stopEvent: (event: Event) => {\r\n const target = event.target;\r\n if (target === mermaidEditor) return true;\r\n if (mermaidEditContainer.contains(target as globalThis.Node)) return true;\r\n if (target === fileInput) return true;\r\n return false;\r\n },\r\n ignoreMutation: (mutation: MutationRecord | { type: 'selection'; target: Element }) => {\r\n const target = mutation.target as unknown as globalThis.Node;\r\n if (visual.contains(target)) return true;\r\n if (idLabel.contains(target)) return true;\r\n return false;\r\n },\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'figure') return false;\r\n currentNode = updatedNode;\r\n renderUI();\r\n return true;\r\n },\r\n destroy: () => {\r\n if (drawioSvgDebounceTimer) { clearTimeout(drawioSvgDebounceTimer); drawioSvgDebounceTimer = null; }\r\n if (drawioSvgRetryTimer) { clearTimeout(drawioSvgRetryTimer); drawioSvgRetryTimer = null; }\r\n unsub();\r\n cleanupMermaidOrphans();\r\n if (drawioMessageHandler) {\r\n window.removeEventListener('message', drawioMessageHandler);\r\n drawioMessageHandler = null;\r\n }\r\n if (drawioIframe) {\r\n drawioIframe.src = 'about:blank';\r\n drawioIframe = null;\r\n }\r\n if (drawioModal) {\r\n drawioModal.remove();\r\n drawioModal = null;\r\n }\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport const ReferenceNode = Node.create({\r\n name: 'reference',\r\n group: 'inline',\r\n inline: true,\r\n atom: true,\r\n\r\n addAttributes() {\r\n return {\r\n targetType: {\r\n default: 'claim',\r\n },\r\n target: {\r\n default: null,\r\n },\r\n targetClaimId: {\r\n default: null,\r\n },\r\n targetFigureId: {\r\n default: null,\r\n },\r\n displayText: {\r\n default: null,\r\n },\r\n resolvedNumber: {\r\n default: null,\r\n },\r\n resolvedFigureId: {\r\n default: null,\r\n },\r\n lang: {\r\n default: 'zh',\r\n },\r\n invalid: {\r\n default: false,\r\n },\r\n highlight: {\r\n default: false,\r\n },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [\r\n {\r\n tag: 'span[data-type=\"reference\"]',\r\n },\r\n ];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n const language = HTMLAttributes.lang === 'en' ? 'en' : 'zh';\r\n const targetType = HTMLAttributes.targetType === 'figure' ? 'figure' : 'claim';\r\n const fallback = targetType === 'figure'\r\n ? (HTMLAttributes.resolvedFigureId || (language === 'en' ? 'Figure ?' : '附图?'))\r\n : (language === 'en'\r\n ? `Claim ${HTMLAttributes.resolvedNumber ? String(HTMLAttributes.resolvedNumber) : '?'}`\r\n : `权利要求${HTMLAttributes.resolvedNumber ? String(HTMLAttributes.resolvedNumber) : '?'}`);\r\n const text = HTMLAttributes.displayText || fallback;\r\n return [\r\n 'span',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'reference',\r\n class: `reference-link${HTMLAttributes.invalid ? ' reference-link-invalid' : ''}`,\r\n }),\r\n text,\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ node, editor }) => {\r\n let currentNode = node;\r\n const dom = document.createElement('span');\r\n const rerender = () => {\r\n const language = currentNode.attrs.lang === 'en' ? 'en' : 'zh';\r\n const i18n = getEditorText(language);\r\n const targetType = currentNode.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n const resolvedNumber = Number(currentNode.attrs.resolvedNumber);\r\n const resolvedFigureId =\r\n typeof currentNode.attrs.resolvedFigureId === 'string' && currentNode.attrs.resolvedFigureId\r\n ? currentNode.attrs.resolvedFigureId\r\n : null;\r\n const fallback = targetType === 'figure'\r\n ? (resolvedFigureId || (language === 'en' ? 'Figure ?' : '附图?'))\r\n : (Number.isFinite(resolvedNumber)\r\n ? i18n.claimLabel(resolvedNumber)\r\n : (language === 'en' ? 'Claim ?' : '权利要求?'));\r\n const text = currentNode.attrs.displayText || fallback;\r\n dom.textContent = text;\r\n dom.className = `reference-link${currentNode.attrs.invalid ? ' reference-link-invalid' : ''}`;\r\n dom.setAttribute('data-type', 'reference');\r\n dom.setAttribute('data-highlight', currentNode.attrs.highlight ? 'true' : 'false');\r\n dom.title = currentNode.attrs.invalid\r\n ? i18n.referenceNavigateDisabledTitle\r\n : targetType === 'figure'\r\n ? i18n.figureReferenceNavigateTitle\r\n : i18n.referenceNavigateTitle;\r\n };\r\n rerender();\r\n dom.addEventListener('click', () => {\r\n const targetType = currentNode.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n if (currentNode.attrs.invalid) {\r\n return;\r\n }\r\n // Defer navigation so it runs after ProseMirror's own atom-node\r\n // selection handling; otherwise the NodeSelection may overwrite ours.\r\n setTimeout(() => {\r\n let targetPos: number | null = null;\r\n if (targetType === 'figure') {\r\n const targetFigureId =\r\n typeof currentNode.attrs.targetFigureId === 'string' ? currentNode.attrs.targetFigureId : '';\r\n if (!targetFigureId) {\r\n return;\r\n }\r\n editor.state.doc.descendants((descendant, pos) => {\r\n if (targetPos !== null) return false;\r\n if (descendant.type.name === 'figure' && descendant.attrs.id === targetFigureId) {\r\n targetPos = pos;\r\n return false;\r\n }\r\n return true;\r\n });\r\n } else {\r\n if (!currentNode.attrs.targetClaimId) {\r\n return;\r\n }\r\n editor.state.doc.descendants((descendant, pos) => {\r\n if (targetPos !== null) return false;\r\n if (descendant.type.name === 'claim' && descendant.attrs.claimId === currentNode.attrs.targetClaimId) {\r\n targetPos = pos;\r\n return false;\r\n }\r\n return true;\r\n });\r\n }\r\n if (typeof targetPos === 'number') {\r\n editor.chain().focus().setTextSelection(targetPos + 1).scrollIntoView().run();\r\n }\r\n }, 0);\r\n });\r\n return {\r\n dom,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== this.name) {\r\n return false;\r\n }\r\n currentNode = updatedNode;\r\n rerender();\r\n return true;\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Slice, Fragment, Node as PMNode } from '@tiptap/pm/model';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\nexport type PatentSectionType =\r\n // Invention & Utility Model\r\n | 'technical_field'\r\n | 'background_art'\r\n | 'summary'\r\n | 'drawing_description'\r\n | 'detailed_description'\r\n | 'claims'\r\n | 'abstract'\r\n | 'abstract_drawing'\r\n | 'drawing_figures'\r\n // Design Patent\r\n | 'design_product_name'\r\n | 'design_usage'\r\n | 'design_description'\r\n | 'design_views'\r\n | 'design_brief';\r\n\r\n\r\nconst SECTION_TITLE_I18N_KEYS: Record<PatentSectionType, string> = {\r\n technical_field: 'sectionTitle_technical_field',\r\n background_art: 'sectionTitle_background_art',\r\n summary: 'sectionTitle_summary',\r\n drawing_description: 'sectionTitle_drawing_description',\r\n detailed_description: 'sectionTitle_detailed_description',\r\n claims: 'sectionTitle_claims',\r\n abstract: 'sectionTitle_abstract',\r\n abstract_drawing: 'sectionTitle_abstract_drawing',\r\n drawing_figures: 'sectionTitle_drawing_figures',\r\n design_product_name: 'sectionTitle_design_product_name',\r\n design_usage: 'sectionTitle_design_usage',\r\n design_description: 'sectionTitle_design_description',\r\n design_views: 'sectionTitle_design_views',\r\n design_brief: 'sectionTitle_design_brief',\r\n};\r\n\r\n/** Sections that are top-level \"books\" in the CNIPA five-book structure */\r\nconst BOOK_LEVEL_SECTIONS = new Set<PatentSectionType>([\r\n 'abstract', 'abstract_drawing', 'claims', 'drawing_figures',\r\n // Design patent sections are also book-level\r\n 'design_product_name', 'design_usage', 'design_description', 'design_views', 'design_brief',\r\n]);\r\n\r\n/** Sub-sections that belong under 说明书 */\r\nconst DESCRIPTION_SUB_SECTIONS = new Set<PatentSectionType>([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\nconst hasMeaningfulContent = (node: PMNode): boolean => {\r\n if (node.isText) {\r\n return (node.text ?? '').trim().length > 0;\r\n }\r\n\r\n if (node.isAtom || node.isLeaf) {\r\n return true;\r\n }\r\n\r\n if (!['patent_section', 'patent_title', 'paragraph'].includes(node.type.name)) {\r\n return true;\r\n }\r\n\r\n let found = false;\r\n node.forEach((child) => {\r\n if (!found && hasMeaningfulContent(child)) {\r\n found = true;\r\n }\r\n });\r\n return found;\r\n};\r\n\r\n/* ──── Patent Title Node (standalone editable title, under 说明书) ──── */\r\n\r\nexport const PatentTitleNode = Node.create({\r\n name: 'patent_title',\r\n group: 'block',\r\n content: 'inline*',\r\n defining: true,\r\n isolating: true,\r\n draggable: false,\r\n\r\n parseHTML() {\r\n return [{ tag: 'h1[data-type=\"patent-title\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'h1',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'patent-title',\r\n class: 'patent-title',\r\n }),\r\n 0,\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n\r\n const dom = document.createElement('div');\r\n dom.className = 'pt-title';\r\n dom.setAttribute('data-type', 'patent-title');\r\n\r\n // \"说明书\" book-level header\r\n const bookHeading = document.createElement('div');\r\n bookHeading.className = 'pb-heading';\r\n bookHeading.contentEditable = 'false';\r\n\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'ps-placeholder';\r\n placeholder.contentEditable = 'false';\r\n\r\n const contentArea = document.createElement('h1');\r\n contentArea.className = 'pt-title-content';\r\n\r\n dom.append(bookHeading, placeholder, contentArea);\r\n\r\n const getNodePos = (): number | null => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n return typeof pos === 'number' ? pos : null;\r\n };\r\n\r\n const activateTitle = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n useEditorStore.getState().setActiveSection('patent_title', pos);\r\n };\r\n\r\n const onPlaceholderClick = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n useEditorStore.getState().openDraftingPanel('patent_title', pos);\r\n editor.commands.focus(pos + 1);\r\n };\r\n\r\n placeholder.addEventListener('click', onPlaceholderClick);\r\n contentArea.addEventListener('focusin', activateTitle);\r\n contentArea.addEventListener('click', activateTitle);\r\n\r\n const render = () => {\r\n const state = useEditorStore.getState();\r\n const i18n = getEditorText(state.editorLanguage) as Record<string, unknown>;\r\n\r\n const bookLabel = (typeof i18n['bookTitle_description'] === 'string'\r\n ? i18n['bookTitle_description'] : '说明书') as string;\r\n const titleLabel = (typeof i18n['patentTitlePlaceholder'] === 'string'\r\n ? i18n['patentTitlePlaceholder'] : '专利名称') as string;\r\n\r\n bookHeading.textContent = bookLabel;\r\n\r\n const hasContent = hasMeaningfulContent(currentNode);\r\n const isActive = state.rightPanel.activeSectionPos === getNodePos();\r\n\r\n placeholder.textContent = `[${titleLabel}]`;\r\n placeholder.style.display = hasContent ? 'none' : '';\r\n placeholder.classList.toggle('ps-placeholder--active', isActive && !hasContent);\r\n contentArea.classList.toggle('pt-title-content--has-content', hasContent);\r\n };\r\n\r\n let prevLang = useEditorStore.getState().editorLanguage;\r\n let prevActivePos = useEditorStore.getState().rightPanel.activeSectionPos;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n const langChanged = state.editorLanguage !== prevLang;\r\n const posChanged = state.rightPanel.activeSectionPos !== prevActivePos;\r\n prevLang = state.editorLanguage;\r\n prevActivePos = state.rightPanel.activeSectionPos;\r\n if (langChanged || posChanged) render();\r\n });\r\n\r\n render();\r\n\r\n return {\r\n dom,\r\n contentDOM: contentArea,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'patent_title') return false;\r\n currentNode = updatedNode;\r\n render();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n placeholder.removeEventListener('click', onPlaceholderClick);\r\n contentArea.removeEventListener('focusin', activateTitle);\r\n contentArea.removeEventListener('click', activateTitle);\r\n },\r\n };\r\n };\r\n },\r\n});\r\n\r\n/* ──── Patent Section Node ──── */\r\n\r\nexport const PatentSectionNode = Node.create({\r\n name: 'patent_section',\r\n group: 'block',\r\n content: 'block+',\r\n defining: true,\r\n isolating: true,\r\n draggable: false,\r\n\r\n addAttributes() {\r\n return {\r\n sectionType: { default: 'technical_field' as PatentSectionType },\r\n collapsed: { default: false },\r\n };\r\n },\r\n\r\n parseHTML() {\r\n return [{ tag: 'section[data-type=\"patent-section\"]' }];\r\n },\r\n\r\n renderHTML({ HTMLAttributes }) {\r\n return [\r\n 'section',\r\n mergeAttributes(HTMLAttributes, {\r\n 'data-type': 'patent-section',\r\n 'data-section-type': HTMLAttributes.sectionType,\r\n class: 'patent-section',\r\n }),\r\n 0,\r\n ];\r\n },\r\n\r\n addProseMirrorPlugins() {\r\n const stripSectionWrappers = (fragment: Fragment): Fragment => {\r\n const nodes: PMNode[] = [];\r\n fragment.forEach((node) => {\r\n if (node.type.name === 'patent_section' || node.type.name === 'patent_title') {\r\n // Unwrap: push the children instead of the wrapper\r\n const inner = stripSectionWrappers(node.content);\r\n inner.forEach((child) => nodes.push(child));\r\n } else {\r\n // Recurse into other block nodes that might contain nested sections\r\n if (node.isBlock && node.content.size > 0) {\r\n nodes.push(node.copy(stripSectionWrappers(node.content)));\r\n } else {\r\n nodes.push(node);\r\n }\r\n }\r\n });\r\n return Fragment.from(nodes);\r\n };\r\n\r\n return [\r\n new Plugin({\r\n key: new PluginKey('patentSectionLock'),\r\n props: {\r\n transformPasted: (slice) => {\r\n const cleaned = stripSectionWrappers(slice.content);\r\n return new Slice(cleaned, slice.openStart, slice.openEnd);\r\n },\r\n },\r\n filterTransaction: (tr, state) => {\r\n if (!tr.docChanged) return true;\r\n const oldOrder: string[] = [];\r\n const newOrder: string[] = [];\r\n state.doc.forEach((node) => {\r\n if (node.type.name === 'patent_section') {\r\n oldOrder.push(node.attrs.sectionType);\r\n }\r\n });\r\n tr.doc.forEach((node) => {\r\n if (node.type.name === 'patent_section') {\r\n newOrder.push(node.attrs.sectionType);\r\n }\r\n });\r\n if (oldOrder.length !== newOrder.length) return true;\r\n for (let i = 0; i < oldOrder.length; i++) {\r\n if (oldOrder[i] !== newOrder[i]) return false;\r\n }\r\n return true;\r\n },\r\n }),\r\n ];\r\n },\r\n\r\n addNodeView() {\r\n return ({ editor, node, getPos }) => {\r\n let currentNode = node;\r\n\r\n const dom = document.createElement('section');\r\n dom.setAttribute('data-type', 'patent-section');\r\n\r\n const heading = document.createElement('div');\r\n heading.contentEditable = 'false';\r\n\r\n const body = document.createElement('div');\r\n body.className = 'ps-body';\r\n\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'ps-placeholder';\r\n placeholder.contentEditable = 'false';\r\n\r\n const contentArea = document.createElement('div');\r\n contentArea.className = 'ps-content';\r\n\r\n body.append(placeholder, contentArea);\r\n dom.append(heading, body);\r\n\r\n const getNodePos = (): number | null => {\r\n const pos = typeof getPos === 'function' ? getPos() : null;\r\n return typeof pos === 'number' ? pos : null;\r\n };\r\n\r\n const activateSection = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n const store = useEditorStore.getState();\r\n store.setActiveSection(currentNode.attrs.sectionType, pos);\r\n };\r\n\r\n const openDraftingForSection = () => {\r\n const pos = getNodePos();\r\n if (pos === null) return;\r\n const store = useEditorStore.getState();\r\n store.openDraftingPanel(currentNode.attrs.sectionType, pos);\r\n editor.commands.focus(pos + 1);\r\n };\r\n\r\n placeholder.addEventListener('click', openDraftingForSection);\r\n contentArea.addEventListener('focusin', activateSection);\r\n contentArea.addEventListener('click', activateSection);\r\n\r\n const render = () => {\r\n const state = useEditorStore.getState();\r\n const i18n = getEditorText(state.editorLanguage) as Record<string, unknown>;\r\n\r\n const sectionType: PatentSectionType =\r\n (Object.keys(SECTION_TITLE_I18N_KEYS).includes(currentNode.attrs.sectionType))\r\n ? currentNode.attrs.sectionType as PatentSectionType\r\n : 'technical_field';\r\n\r\n const isBook = BOOK_LEVEL_SECTIONS.has(sectionType);\r\n const isSub = DESCRIPTION_SUB_SECTIONS.has(sectionType);\r\n const titleKey = SECTION_TITLE_I18N_KEYS[sectionType];\r\n const sectionTitle = (typeof i18n[titleKey] === 'string' ? i18n[titleKey] : sectionType) as string;\r\n\r\n const hasContent = hasMeaningfulContent(currentNode);\r\n const isActive = state.rightPanel.activeSectionPos === getNodePos();\r\n\r\n dom.className = `ps${hasContent ? '' : ' ps--empty'}${isSub ? ' ps--sub' : ''}`;\r\n dom.setAttribute('data-section-type', sectionType);\r\n\r\n heading.className = isBook ? 'pb-heading' : 'ps-heading ps-heading--sub';\r\n heading.textContent = sectionTitle;\r\n\r\n placeholder.textContent = `[${sectionTitle}]`;\r\n placeholder.style.display = hasContent ? 'none' : '';\r\n placeholder.classList.toggle('ps-placeholder--active', isActive && !hasContent);\r\n contentArea.classList.toggle('ps-content--has-content', hasContent);\r\n\r\n };\r\n\r\n let prevLang = useEditorStore.getState().editorLanguage;\r\n let prevActivePos = useEditorStore.getState().rightPanel.activeSectionPos;\r\n const unsub = useEditorStore.subscribe((state) => {\r\n const langChanged = state.editorLanguage !== prevLang;\r\n const posChanged = state.rightPanel.activeSectionPos !== prevActivePos;\r\n prevLang = state.editorLanguage;\r\n prevActivePos = state.rightPanel.activeSectionPos;\r\n if (langChanged || posChanged) render();\r\n });\r\n\r\n render();\r\n\r\n return {\r\n dom,\r\n contentDOM: contentArea,\r\n update: (updatedNode) => {\r\n if (updatedNode.type.name !== 'patent_section') return false;\r\n currentNode = updatedNode;\r\n render();\r\n return true;\r\n },\r\n destroy: () => {\r\n unsub();\r\n placeholder.removeEventListener('click', openDraftingForSection);\r\n contentArea.removeEventListener('focusin', activateSection);\r\n contentArea.removeEventListener('click', activateSection);\r\n },\r\n };\r\n };\r\n },\r\n});\r\n","import type { JSONContent } from '@tiptap/react';\r\nimport type { PatentSectionType } from './sectionNode';\r\n\r\nexport type PatentType = 'invention' | 'utility_model' | 'design';\r\n\r\n/** Sections BEFORE 说明书 (patent_title inserted between these and description sub-sections) */\r\nconst PRE_DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'abstract', // 说明书摘要\r\n 'abstract_drawing', // 摘要附图\r\n];\r\n\r\n/** 说明书 sub-sections (patent_title is first, then these, then drawing_figures) */\r\nconst DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'technical_field',\r\n 'background_art',\r\n 'summary',\r\n 'drawing_description',\r\n 'detailed_description',\r\n];\r\n\r\n/** Sections AFTER 说明书 */\r\nconst POST_DESCRIPTION_SECTIONS: PatentSectionType[] = [\r\n 'drawing_figures', // 说明书附图\r\n];\r\n\r\nconst DESIGN_SECTIONS: PatentSectionType[] = [\r\n 'design_product_name',\r\n 'design_usage',\r\n 'design_description',\r\n 'design_views',\r\n 'design_brief',\r\n];\r\n\r\nconst buildSectionNode = (sectionType: PatentSectionType): JSONContent => ({\r\n type: 'patent_section',\r\n attrs: {\r\n sectionType,\r\n collapsed: false,\r\n },\r\n content: [\r\n {\r\n type: 'paragraph',\r\n },\r\n ],\r\n});\r\n\r\nconst buildTitleNode = (): JSONContent => ({\r\n type: 'patent_title',\r\n content: [],\r\n});\r\n\r\nconst buildInventionContent = (): JSONContent[] => [\r\n ...PRE_DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n buildTitleNode(),\r\n ...DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n ...POST_DESCRIPTION_SECTIONS.map(buildSectionNode),\r\n];\r\n\r\nconst buildDesignContent = (): JSONContent[] => [\r\n buildTitleNode(),\r\n ...DESIGN_SECTIONS.map(buildSectionNode),\r\n];\r\n\r\nexport const buildPatentDocument = (patentType: PatentType = 'invention'): JSONContent => {\r\n const content = patentType === 'design' ? buildDesignContent() : buildInventionContent();\r\n return { type: 'doc', content };\r\n};\r\n\r\nexport const buildPatentSections = (patentType: PatentType = 'invention'): JSONContent[] => {\r\n return patentType === 'design' ? buildDesignContent() : buildInventionContent();\r\n};\r\n","import { Editor } from '@tiptap/react';\r\nimport { findAncestorNode, findNodesByPredicate, updateNodeAttrs } from '../../commands';\r\nimport { EditorPlugin } from '../../../types/plugin';\r\nimport { FigureNode, FigureContentType } from './figureNode';\r\nimport { ReferenceNode } from './referenceNode';\r\nimport { PatentSectionNode, PatentTitleNode } from './sectionNode';\r\nimport { buildPatentDocument, PatentType } from './patentDocTemplate';\r\nimport { useEditorStore } from '../../../store/editorStore';\r\nimport { getEditorText } from '../../../lib/editorI18n';\r\n\r\ntype ReferenceLanguage = 'zh' | 'en';\r\n\r\ninterface SetReferenceLanguagePayload {\r\n lang: ReferenceLanguage;\r\n scope?: 'all' | 'current';\r\n}\r\n\r\ninterface UpdateFigurePayload {\r\n position?: number;\r\n id?: string | null;\r\n caption?: string;\r\n contentType?: FigureContentType;\r\n imageSrc?: string;\r\n mermaidCode?: string;\r\n drawioXml?: string;\r\n}\r\n\r\ninterface InsertFigurePayload {\r\n id?: string;\r\n contentType?: FigureContentType;\r\n captionText?: string;\r\n}\r\n\r\ninterface InsertFigureReferencePayload {\r\n targetFigureId?: string;\r\n displayText?: string;\r\n lang?: ReferenceLanguage;\r\n target?: string;\r\n}\r\n\r\ninterface InsertPatentDocumentPayload {\r\n patentType?: PatentType;\r\n}\r\n\r\ninterface ToggleSectionCollapsePayload {\r\n position?: number;\r\n}\r\n\r\nconst getFigureNodes = (editor: Editor) => {\r\n return findNodesByPredicate(editor, (node) => node.type.name === 'figure');\r\n};\r\n\r\nconst normalizeFigureId = (value: unknown) => {\r\n if (typeof value !== 'string') {\r\n return '';\r\n }\r\n return value.trim();\r\n};\r\n\r\nconst suggestNextFigureId = (editor: Editor) => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const prefix = language === 'en' ? 'Fig.' : '图';\r\n const used = new Set<string>();\r\n getFigureNodes(editor).forEach((item) => {\r\n const id = normalizeFigureId(item.node.attrs.id);\r\n if (id) {\r\n used.add(id);\r\n }\r\n });\r\n let index = 1;\r\n while (used.has(`${prefix}${index}`)) {\r\n index += 1;\r\n }\r\n return `${prefix}${index}`;\r\n};\r\n\r\nconst FIGURE_ID_PATTERN = /^(Fig\\.|图)(\\d+)$/;\r\n\r\nconst syncFigureOrder = (editor: Editor) => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const prefix = language === 'en' ? 'Fig.' : '图';\r\n const figures = getFigureNodes(editor);\r\n if (figures.length === 0) return;\r\n\r\n const updates: { pos: number; expectedId: string; currentId: string }[] = [];\r\n let seqIndex = 1;\r\n\r\n for (const fig of figures) {\r\n const currentId = normalizeFigureId(fig.node.attrs.id);\r\n const match = FIGURE_ID_PATTERN.exec(currentId);\r\n if (!match) continue;\r\n\r\n const expectedId = `${prefix}${seqIndex}`;\r\n if (currentId !== expectedId) {\r\n updates.push({ pos: fig.pos, expectedId, currentId });\r\n }\r\n seqIndex++;\r\n }\r\n\r\n if (updates.length === 0) return;\r\n\r\n const { tr } = editor.state;\r\n for (const u of updates) {\r\n const node = tr.doc.nodeAt(u.pos);\r\n if (!node || node.type.name !== 'figure') continue;\r\n tr.setNodeMarkup(u.pos, undefined, { ...node.attrs, id: u.expectedId });\r\n }\r\n if (tr.steps.length > 0) {\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n }\r\n};\r\n\r\nconst getFigureIndex = (editor: Editor) => {\r\n const figureIndex = new Map<string, { id: string; pos: number }>();\r\n getFigureNodes(editor).forEach((match) => {\r\n const id = normalizeFigureId(match.node.attrs.id);\r\n if (!id) {\r\n return;\r\n }\r\n figureIndex.set(id, {\r\n id,\r\n pos: match.pos,\r\n });\r\n });\r\n return figureIndex;\r\n};\r\n\r\nconst getGlobalReferenceLanguage = (): ReferenceLanguage => {\r\n const language = useEditorStore.getState().editorLanguage;\r\n return language === 'en' ? 'en' : 'zh';\r\n};\r\n\r\nconst buildFigureReferenceText = (\r\n lang: ReferenceLanguage,\r\n resolvedFigureId: string | null,\r\n invalid: boolean\r\n) => {\r\n const i18n = getEditorText(lang);\r\n if (invalid) {\r\n return i18n.invalidFigureReference;\r\n }\r\n if (resolvedFigureId) {\r\n return resolvedFigureId;\r\n }\r\n return lang === 'en' ? 'Figure ?' : '附图?';\r\n};\r\n\r\nconst syncFigureReferenceState = (editor: Editor) => {\r\n const figureIndex = getFigureIndex(editor);\r\n const globalLanguage = getGlobalReferenceLanguage();\r\n editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference') {\r\n return true;\r\n }\r\n if (node.attrs.targetType !== 'figure') {\r\n return true;\r\n }\r\n const targetFigureId =\r\n typeof node.attrs.targetFigureId === 'string' && node.attrs.targetFigureId\r\n ? normalizeFigureId(node.attrs.targetFigureId)\r\n : null;\r\n const matchedFigure = targetFigureId ? figureIndex.get(targetFigureId) : undefined;\r\n const resolvedFigureId = matchedFigure ? matchedFigure.id : null;\r\n const invalid = !matchedFigure;\r\n const displayText = buildFigureReferenceText(globalLanguage, resolvedFigureId, invalid);\r\n const nextAttrs = {\r\n ...node.attrs,\r\n targetType: 'figure',\r\n targetFigureId,\r\n resolvedFigureId,\r\n invalid,\r\n lang: globalLanguage,\r\n displayText,\r\n target: resolvedFigureId || node.attrs.target || targetFigureId || null,\r\n };\r\n const hasChanged = Object.keys(nextAttrs).some(\r\n key => nextAttrs[key as keyof typeof nextAttrs] !== node.attrs[key]\r\n );\r\n if (hasChanged) {\r\n tr.setNodeMarkup(pos, undefined, nextAttrs);\r\n changed = true;\r\n }\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport const PatentPlugin: EditorPlugin = {\r\n name: 'patent',\r\n version: '1.0.0',\r\n extensions: [FigureNode, ReferenceNode, PatentTitleNode, PatentSectionNode],\r\n toolbarItems: [\r\n {\r\n id: 'patent-figure-insert',\r\n label: 'Figure',\r\n command: 'insertFigure',\r\n group: 'patent',\r\n tooltip: 'Insert figure block',\r\n tooltipZh: '插入附图',\r\n icon: 'Image',\r\n shortcut: 'Ctrl+Shift+F',\r\n },\r\n ],\r\n commands: {\r\n setReferenceLanguage: {\r\n description: 'Set reference language for current or all references',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as SetReferenceLanguagePayload) : null;\r\n if (!data?.lang) {\r\n return false;\r\n }\r\n const lang: ReferenceLanguage = data.lang === 'en' ? 'en' : 'zh';\r\n useEditorStore.getState().setEditorLanguage(lang);\r\n const scope = data.scope || 'all';\r\n const currentReference = scope === 'current' ? findAncestorNode(editor, 'reference') : null;\r\n const updated = editor.commands.command(({ tr, state, dispatch }) => {\r\n let changed = false;\r\n state.doc.descendants((node, pos) => {\r\n if (node.type.name !== 'reference') {\r\n return true;\r\n }\r\n if (currentReference && pos !== currentReference.pos) {\r\n return true;\r\n }\r\n if (node.attrs.lang !== lang) {\r\n tr.setNodeMarkup(pos, undefined, {\r\n ...node.attrs,\r\n lang,\r\n });\r\n changed = true;\r\n }\r\n return true;\r\n });\r\n if (changed && dispatch) {\r\n dispatch(tr);\r\n }\r\n return true;\r\n });\r\n if (!updated) {\r\n return false;\r\n }\r\n return syncFigureReferenceState(editor), true;\r\n },\r\n },\r\n insertFigure: {\r\n description: 'Insert patent figure block',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+F',\r\n isActive: ({ editor }) => editor.isActive('figure'),\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertFigurePayload) : {};\r\n const id = normalizeFigureId(data.id) || suggestNextFigureId(editor);\r\n const contentType: FigureContentType =\r\n data.contentType && ['image', 'mermaid', 'drawio'].includes(data.contentType)\r\n ? data.contentType : 'image';\r\n return editor.chain().focus().insertContent({\r\n type: 'figure',\r\n attrs: { id, contentType, imageSrc: '', mermaidCode: '', drawioXml: '' },\r\n content: data.captionText ? [{ type: 'text', text: data.captionText }] : [],\r\n }).run();\r\n },\r\n },\r\n updateFigure: {\r\n description: 'Update figure attributes',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as UpdateFigurePayload) : {};\r\n const figureNode = findAncestorNode(editor, 'figure');\r\n const targetPos = typeof data.position === 'number' ? data.position : figureNode?.pos;\r\n if (typeof targetPos !== 'number') {\r\n return false;\r\n }\r\n const target = editor.state.doc.nodeAt(targetPos);\r\n if (!target || target.type.name !== 'figure') {\r\n return false;\r\n }\r\n const nextId = typeof data.id === 'string' ? normalizeFigureId(data.id) : normalizeFigureId(target.attrs.id);\r\n const candidateId = nextId || suggestNextFigureId(editor);\r\n const duplicated = getFigureNodes(editor).some((item) => {\r\n if (item.pos === targetPos) {\r\n return false;\r\n }\r\n return normalizeFigureId(item.node.attrs.id) === candidateId;\r\n });\r\n if (duplicated) {\r\n return false;\r\n }\r\n const attrsPatch: Record<string, unknown> = { id: candidateId };\r\n if (typeof data.contentType === 'string' && ['image', 'mermaid', 'drawio'].includes(data.contentType)) {\r\n attrsPatch.contentType = data.contentType;\r\n }\r\n if (typeof data.imageSrc === 'string') {\r\n attrsPatch.imageSrc = data.imageSrc;\r\n }\r\n if (typeof data.mermaidCode === 'string') {\r\n attrsPatch.mermaidCode = data.mermaidCode;\r\n }\r\n if (typeof data.drawioXml === 'string') {\r\n attrsPatch.drawioXml = data.drawioXml;\r\n }\r\n return updateNodeAttrs(editor, {\r\n type: 'figure',\r\n position: targetPos,\r\n attrs: attrsPatch,\r\n });\r\n },\r\n },\r\n validateFigureIds: {\r\n description: 'Validate figure id uniqueness',\r\n category: 'patent',\r\n execute: ({ editor }) => {\r\n const used = new Set<string>();\r\n let duplicated = false;\r\n getFigureNodes(editor).forEach((item) => {\r\n const id = normalizeFigureId(item.node.attrs.id);\r\n if (!id) {\r\n return;\r\n }\r\n if (used.has(id)) {\r\n duplicated = true;\r\n return;\r\n }\r\n used.add(id);\r\n });\r\n return !duplicated;\r\n },\r\n },\r\n insertFigureReference: {\r\n description: 'Insert patent figure reference inline node',\r\n category: 'patent',\r\n shortcut: 'Ctrl+Shift+G',\r\n isActive: ({ editor }) => editor.isActive('reference'),\r\n canExecute: (_, payload) => {\r\n if (!payload || typeof payload !== 'object') {\r\n return false;\r\n }\r\n const data = payload as InsertFigureReferencePayload;\r\n return typeof data.targetFigureId === 'string' && data.targetFigureId.trim().length > 0;\r\n },\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertFigureReferencePayload) : {};\r\n const figureIndex = getFigureIndex(editor);\r\n const figureId = typeof data.targetFigureId === 'string' ? normalizeFigureId(data.targetFigureId) : '';\r\n if (!figureId) {\r\n return false;\r\n }\r\n const matchedFigure = figureIndex.get(figureId);\r\n if (!matchedFigure) {\r\n return false;\r\n }\r\n const language: ReferenceLanguage = data.lang || getGlobalReferenceLanguage();\r\n const displayText = data.displayText || buildFigureReferenceText(language, matchedFigure.id, false);\r\n const inserted = editor.chain().focus().insertContent({\r\n type: 'reference',\r\n attrs: {\r\n targetType: 'figure',\r\n targetClaimId: null,\r\n targetFigureId: matchedFigure.id,\r\n resolvedNumber: null,\r\n resolvedFigureId: matchedFigure.id,\r\n lang: language,\r\n invalid: false,\r\n displayText,\r\n target: data.target || matchedFigure.id,\r\n highlight: false,\r\n },\r\n }).run();\r\n if (!inserted) {\r\n return false;\r\n }\r\n return syncFigureReferenceState(editor), true;\r\n },\r\n },\r\n insertPatentDocument: {\r\n description: 'Insert patent document skeleton with all sections',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as InsertPatentDocumentPayload) : {};\r\n const patentType: PatentType = data.patentType === 'utility_model' ? 'utility_model' : data.patentType === 'design' ? 'design' : 'invention';\r\n const doc = buildPatentDocument(patentType);\r\n return editor.commands.setContent(doc);\r\n },\r\n },\r\n toggleSectionCollapse: {\r\n description: 'Toggle patent section collapse state',\r\n category: 'patent',\r\n execute: ({ editor }, payload) => {\r\n const data = typeof payload === 'object' && payload ? (payload as ToggleSectionCollapsePayload) : {};\r\n const sectionNode = findAncestorNode(editor, 'patent_section');\r\n const targetPos = typeof data.position === 'number' ? data.position : sectionNode?.pos;\r\n if (typeof targetPos !== 'number') return false;\r\n const target = editor.state.doc.nodeAt(targetPos);\r\n if (!target || target.type.name !== 'patent_section') return false;\r\n return updateNodeAttrs(editor, {\r\n type: 'patent_section',\r\n position: targetPos,\r\n attrs: { collapsed: !target.attrs.collapsed },\r\n });\r\n },\r\n },\r\n },\r\n onStateChange: (editor) => {\r\n syncFigureOrder(editor);\r\n syncFigureReferenceState(editor);\r\n },\r\n};\r\n","import { MermaidPlugin } from './mermaid';\r\nimport { DrawioPlugin } from './drawio';\r\nimport { MathPlugin } from './math';\r\nimport { PatentPlugin } from './patent';\r\n\r\nexport const plugins = [MermaidPlugin, DrawioPlugin, MathPlugin, PatentPlugin];\r\n","import { Editor, EditorOptions } from '@tiptap/react';\r\nimport { schemaExtensions } from '../schema/schema';\r\nimport { pluginManager } from './PluginManager';\r\nimport { plugins as defaultPlugins } from '../plugins';\r\nimport { CommandExecutionContext, CommandExecutionOptions } from '../../types/plugin';\r\nimport {\r\n applyTransactionBatch,\r\n findAncestorNode,\r\n findCurrentBlock,\r\n findNodeByType,\r\n findNodesByPredicate,\r\n insertNode,\r\n removeNode,\r\n updateNodeAttrs,\r\n wrapSelection,\r\n} from '../commands';\r\nimport { useEditorStore } from '../../store/editorStore';\r\n\r\ndefaultPlugins.forEach(plugin => pluginManager.register(plugin));\r\n\r\nexport const createEditorConfig = (options: Partial<EditorOptions> = {}): Partial<EditorOptions> => {\r\n const extensions = [\r\n ...schemaExtensions,\r\n ...pluginManager.getExtensions(),\r\n ...(options.extensions || []),\r\n ];\r\n\r\n return {\r\n ...options,\r\n extensions,\r\n };\r\n};\r\n\r\nconst createCommandContext = (editor: Editor): CommandExecutionContext => {\r\n const { from, to } = editor.state.selection;\r\n return {\r\n editor,\r\n selection: { from, to },\r\n store: useEditorStore.getState(),\r\n };\r\n};\r\n\r\nexport const createCommandExecutor = (editor: Editor) => {\r\n return {\r\n execCommand: (name: string, payload?: unknown, options?: CommandExecutionOptions) => {\r\n return pluginManager.executeCommand(name, createCommandContext(editor), payload, options);\r\n },\r\n canExecCommand: (name: string, payload?: unknown) => {\r\n return pluginManager.canExecuteCommand(name, createCommandContext(editor), payload);\r\n },\r\n isCommandActive: (name: string) => {\r\n return pluginManager.isCommandActive(name, createCommandContext(editor));\r\n },\r\n listCommands: () => {\r\n return pluginManager.getCommandNames();\r\n },\r\n insertNode: (input: Parameters<typeof insertNode>[1]) => {\r\n return insertNode(editor, input);\r\n },\r\n updateNodeAttrs: (input: Parameters<typeof updateNodeAttrs>[1]) => {\r\n return updateNodeAttrs(editor, input);\r\n },\r\n removeNode: (input: Parameters<typeof removeNode>[1]) => {\r\n return removeNode(editor, input);\r\n },\r\n wrapSelection: (input: Parameters<typeof wrapSelection>[1]) => {\r\n return wrapSelection(editor, input);\r\n },\r\n applyTransactionBatch: (operations: Parameters<typeof applyTransactionBatch>[1]) => {\r\n return applyTransactionBatch(editor, operations);\r\n },\r\n findNodeByType: (typeName: Parameters<typeof findNodeByType>[1], scope?: Parameters<typeof findNodeByType>[2]) => {\r\n return findNodeByType(editor, typeName, scope);\r\n },\r\n findAncestorNode: (predicate: Parameters<typeof findAncestorNode>[1]) => {\r\n return findAncestorNode(editor, predicate);\r\n },\r\n findCurrentBlock: () => {\r\n return findCurrentBlock(editor);\r\n },\r\n findNodesByPredicate: (\r\n predicate: Parameters<typeof findNodesByPredicate>[1],\r\n scope?: Parameters<typeof findNodesByPredicate>[2]\r\n ) => {\r\n return findNodesByPredicate(editor, predicate, scope);\r\n },\r\n };\r\n};\r\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { Editor } from '@tiptap/react';\r\nimport {\r\n AlignCenter,\r\n AlignJustify,\r\n AlignLeft,\r\n AlignRight,\r\n Bold,\r\n Box,\r\n CheckSquare,\r\n ChevronDown,\r\n Code,\r\n FileText,\r\n FileCode2,\r\n FunctionSquare,\r\n GitGraph,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n Image,\r\n Italic,\r\n Link2,\r\n List,\r\n ListOrdered,\r\n LucideIcon,\r\n Minus,\r\n Pilcrow,\r\n Quote,\r\n Redo2,\r\n Sigma,\r\n Square,\r\n Strikethrough,\r\n Subscript,\r\n Superscript,\r\n Table as TableIcon,\r\n Underline,\r\n Undo2,\r\n Workflow,\r\n} from 'lucide-react';\r\nimport clsx from 'clsx';\r\nimport { createCommandExecutor } from '../editor/core/EditorCore';\r\nimport { pluginManager } from '../editor/core/PluginManager';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\n// export functions no longer used in toolbar — export moved to host app's bottom bar\r\n\r\ninterface ToolbarProps {\r\n editor: Editor | null;\r\n groupOrder?: string[];\r\n collapsibleGroups?: boolean;\r\n defaultCollapsedGroups?: string[];\r\n}\r\n\r\ninterface ToolbarButton {\r\n id: string;\r\n label: string;\r\n group: string;\r\n icon: LucideIcon;\r\n tooltip: string;\r\n isActive: boolean;\r\n disabled: boolean;\r\n run: () => void;\r\n}\r\n\r\nconst defaultGroupOrder = ['history', 'text', 'structure', 'format', 'technical', 'patent'];\r\n\r\nconst groupI18nKeyMap: Record<string, string> = {\r\n history: 'groupHistory',\r\n text: 'groupText',\r\n structure: 'groupStructure',\r\n format: 'groupFormat',\r\n technical: 'groupTechnical',\r\n patent: 'groupPatent',\r\n};\r\n\r\nconst formatGroupLabel = (group: string, i18n?: Record<string, unknown>) => {\r\n if (i18n) {\r\n const key = groupI18nKeyMap[group];\r\n if (key && typeof i18n[key] === 'string') return i18n[key] as string;\r\n }\r\n return group\r\n .split('_')\r\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\r\n .join(' ');\r\n};\r\n\r\nconst DropdownButton: React.FC<{\r\n btn: ToolbarButton;\r\n items: { label: string; onClick: () => void }[];\r\n}> = ({ btn, items }) => {\r\n const [open, setOpen] = useState(false);\r\n const triggerRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const [pos, setPos] = useState({ top: 0, left: 0 });\r\n\r\n const updatePosition = useCallback(() => {\r\n if (!triggerRef.current) return;\r\n const rect = triggerRef.current.getBoundingClientRect();\r\n setPos({ top: rect.bottom + 4, left: rect.left });\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (!open) return;\r\n updatePosition();\r\n const handleClickOutside = (e: MouseEvent) => {\r\n const target = e.target as Node;\r\n if (\r\n triggerRef.current?.contains(target) ||\r\n menuRef.current?.contains(target)\r\n ) return;\r\n setOpen(false);\r\n };\r\n const handleScroll = () => updatePosition();\r\n document.addEventListener('mousedown', handleClickOutside);\r\n window.addEventListener('scroll', handleScroll, true);\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n window.removeEventListener('scroll', handleScroll, true);\r\n };\r\n }, [open, updatePosition]);\r\n\r\n return (\r\n <div className=\"flex items-center\">\r\n <button\r\n onClick={btn.run}\r\n disabled={btn.disabled}\r\n className={clsx(\r\n 'p-2 rounded-l transition-colors',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200',\r\n btn.isActive ? 'bg-gray-300 text-blue-600' : 'text-gray-700'\r\n )}\r\n title={btn.tooltip}\r\n >\r\n <btn.icon size={18} />\r\n </button>\r\n <button\r\n ref={triggerRef}\r\n onClick={() => setOpen((v) => !v)}\r\n className={clsx(\r\n 'px-1 py-2 rounded-r transition-colors border-l border-gray-200',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200 text-gray-500'\r\n )}\r\n disabled={btn.disabled}\r\n >\r\n <ChevronDown size={12} />\r\n </button>\r\n {open && createPortal(\r\n <div\r\n ref={menuRef}\r\n className=\"bg-white border border-gray-200 rounded shadow-lg min-w-[160px] py-1\"\r\n style={{ position: 'fixed', top: pos.top, left: pos.left, zIndex: 9999 }}\r\n >\r\n {items.map((item, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => {\r\n item.onClick();\r\n setOpen(false);\r\n }}\r\n className=\"block w-full text-left px-3 py-1.5 text-xs text-gray-700 hover:bg-gray-100\"\r\n >\r\n {item.label}\r\n </button>\r\n ))}\r\n </div>,\r\n document.body\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport const Toolbar: React.FC<ToolbarProps> = ({\r\n editor,\r\n groupOrder = defaultGroupOrder,\r\n collapsibleGroups = true,\r\n defaultCollapsedGroups = [],\r\n}) => {\r\n const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(() => new Set(defaultCollapsedGroups));\r\n const { editorLanguage, setEditorLanguage } = useEditorStore();\r\n const i18n = getEditorText(editorLanguage);\r\n\r\n if (!editor) {\r\n return null;\r\n }\r\n\r\n const commandExecutor = createCommandExecutor(editor);\r\n const zh = editorLanguage === 'zh';\r\n\r\n const coreButtons: ToolbarButton[] = [\r\n {\r\n id: 'core-undo',\r\n label: i18n.undo,\r\n group: 'history',\r\n icon: Undo2,\r\n tooltip: `${i18n.undo} (Ctrl+Z)`,\r\n isActive: false,\r\n disabled: !editor.can().chain().focus().undo().run(),\r\n run: () => {\r\n editor.chain().focus().undo().run();\r\n },\r\n },\r\n {\r\n id: 'core-redo',\r\n label: i18n.redo,\r\n group: 'history',\r\n icon: Redo2,\r\n tooltip: `${i18n.redo} (Ctrl+Y)`,\r\n isActive: false,\r\n disabled: !editor.can().chain().focus().redo().run(),\r\n run: () => {\r\n editor.chain().focus().redo().run();\r\n },\r\n },\r\n {\r\n id: 'core-bold',\r\n label: i18n.bold,\r\n group: 'text',\r\n icon: Bold,\r\n tooltip: i18n.bold,\r\n isActive: editor.isActive('bold'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBold().run();\r\n },\r\n },\r\n {\r\n id: 'core-italic',\r\n label: i18n.italic,\r\n group: 'text',\r\n icon: Italic,\r\n tooltip: i18n.italic,\r\n isActive: editor.isActive('italic'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleItalic().run();\r\n },\r\n },\r\n {\r\n id: 'core-underline',\r\n label: i18n.underline,\r\n group: 'text',\r\n icon: Underline,\r\n tooltip: i18n.underline,\r\n isActive: editor.isActive('underline'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleUnderline().run();\r\n },\r\n },\r\n {\r\n id: 'core-strike',\r\n label: i18n.strike,\r\n group: 'text',\r\n icon: Strikethrough,\r\n tooltip: i18n.strike,\r\n isActive: editor.isActive('strike'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleStrike().run();\r\n },\r\n },\r\n {\r\n id: 'core-code',\r\n label: i18n.code,\r\n group: 'text',\r\n icon: Code,\r\n tooltip: i18n.code,\r\n isActive: editor.isActive('code'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleCode().run();\r\n },\r\n },\r\n {\r\n id: 'core-superscript',\r\n label: i18n.superscript,\r\n group: 'text',\r\n icon: Superscript,\r\n tooltip: `${i18n.superscript} (Ctrl+.)`,\r\n isActive: editor.isActive('superscript'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleSuperscript().run();\r\n },\r\n },\r\n {\r\n id: 'core-subscript',\r\n label: i18n.subscript,\r\n group: 'text',\r\n icon: Subscript,\r\n tooltip: `${i18n.subscript} (Ctrl+,)`,\r\n isActive: editor.isActive('subscript'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleSubscript().run();\r\n },\r\n },\r\n {\r\n id: 'core-paragraph',\r\n label: i18n.paragraph,\r\n group: 'structure',\r\n icon: Pilcrow,\r\n tooltip: i18n.paragraph,\r\n isActive: editor.isActive('paragraph'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().setParagraph().run();\r\n },\r\n },\r\n {\r\n id: 'core-heading1',\r\n label: 'H1',\r\n group: 'structure',\r\n icon: Heading1,\r\n tooltip: i18n.heading1,\r\n isActive: editor.isActive('heading', { level: 1 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 1 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-heading2',\r\n label: 'H2',\r\n group: 'structure',\r\n icon: Heading2,\r\n tooltip: i18n.heading2,\r\n isActive: editor.isActive('heading', { level: 2 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 2 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-heading3',\r\n label: 'H3',\r\n group: 'structure',\r\n icon: Heading3,\r\n tooltip: i18n.heading3,\r\n isActive: editor.isActive('heading', { level: 3 }),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleHeading({ level: 3 }).run();\r\n },\r\n },\r\n {\r\n id: 'core-align-left',\r\n label: i18n.alignLeft,\r\n group: 'format',\r\n icon: AlignLeft,\r\n tooltip: i18n.alignLeft,\r\n isActive: editor.isActive({ textAlign: 'left' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('left').run(); },\r\n },\r\n {\r\n id: 'core-align-center',\r\n label: i18n.alignCenter,\r\n group: 'format',\r\n icon: AlignCenter,\r\n tooltip: i18n.alignCenter,\r\n isActive: editor.isActive({ textAlign: 'center' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('center').run(); },\r\n },\r\n {\r\n id: 'core-align-right',\r\n label: i18n.alignRight,\r\n group: 'format',\r\n icon: AlignRight,\r\n tooltip: i18n.alignRight,\r\n isActive: editor.isActive({ textAlign: 'right' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('right').run(); },\r\n },\r\n {\r\n id: 'core-align-justify',\r\n label: i18n.alignJustify,\r\n group: 'format',\r\n icon: AlignJustify,\r\n tooltip: i18n.alignJustify,\r\n isActive: editor.isActive({ textAlign: 'justify' }),\r\n disabled: false,\r\n run: () => { editor.chain().focus().setTextAlign('justify').run(); },\r\n },\r\n {\r\n id: 'core-bullet-list',\r\n label: i18n.bulletList,\r\n group: 'structure',\r\n icon: List,\r\n tooltip: i18n.bulletList,\r\n isActive: editor.isActive('bulletList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBulletList().run();\r\n },\r\n },\r\n {\r\n id: 'core-ordered-list',\r\n label: i18n.orderedList,\r\n group: 'structure',\r\n icon: ListOrdered,\r\n tooltip: i18n.orderedList,\r\n isActive: editor.isActive('orderedList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleOrderedList().run();\r\n },\r\n },\r\n {\r\n id: 'core-blockquote',\r\n label: i18n.blockquote,\r\n group: 'structure',\r\n icon: Quote,\r\n tooltip: i18n.blockquote,\r\n isActive: editor.isActive('blockquote'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleBlockquote().run();\r\n },\r\n },\r\n {\r\n id: 'core-code-block',\r\n label: i18n.codeBlock,\r\n group: 'structure',\r\n icon: FileCode2,\r\n tooltip: i18n.codeBlock,\r\n isActive: editor.isActive('codeBlock'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleCodeBlock().run();\r\n },\r\n },\r\n {\r\n id: 'core-table',\r\n label: i18n.insertTable,\r\n group: 'structure',\r\n icon: TableIcon,\r\n tooltip: i18n.insertTable,\r\n isActive: false,\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();\r\n },\r\n },\r\n {\r\n id: 'core-horizontal-rule',\r\n label: i18n.horizontalRule,\r\n group: 'structure',\r\n icon: Minus,\r\n tooltip: i18n.horizontalRule,\r\n isActive: false,\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().setHorizontalRule().run();\r\n },\r\n },\r\n {\r\n id: 'core-task-list',\r\n label: i18n.taskList,\r\n group: 'structure',\r\n icon: CheckSquare,\r\n tooltip: i18n.taskList,\r\n isActive: editor.isActive('taskList'),\r\n disabled: false,\r\n run: () => {\r\n editor.chain().focus().toggleTaskList().run();\r\n },\r\n },\r\n ];\r\n\r\n const iconMap: Record<string, LucideIcon> = {\r\n GitGraph,\r\n Sigma,\r\n FunctionSquare,\r\n Workflow,\r\n Box,\r\n FileText,\r\n Link2,\r\n Image,\r\n };\r\n\r\n const pluginButtons: ToolbarButton[] = pluginManager.getToolbarItems().map((item) => {\r\n const commandMeta = pluginManager.getCommandMeta(item.command);\r\n const tooltip = (zh && item.tooltipZh) ? item.tooltipZh : (item.tooltip || commandMeta?.description || item.label);\r\n const shortcut = item.shortcut || commandMeta?.shortcut;\r\n const displayTooltip = shortcut ? `${tooltip} (${shortcut})` : tooltip;\r\n return {\r\n id: item.id,\r\n label: item.label,\r\n group: item.group || 'technical',\r\n icon: item.icon ? iconMap[item.icon] || Square : Square,\r\n isActive: commandExecutor.isCommandActive(item.command),\r\n disabled: !commandExecutor.canExecCommand(item.command),\r\n tooltip: displayTooltip,\r\n run: () => {\r\n void commandExecutor.execCommand(item.command);\r\n },\r\n };\r\n });\r\n\r\n const allButtons = [...coreButtons, ...pluginButtons];\r\n const extraGroups = allButtons\r\n .map((button) => button.group)\r\n .filter((group, index, source) => source.indexOf(group) === index && !groupOrder.includes(group));\r\n const normalizedGroupOrder = [...groupOrder, ...extraGroups];\r\n\r\n const groupedButtons = normalizedGroupOrder\r\n .map((group) => ({\r\n group,\r\n items: allButtons.filter((item) => item.group === group),\r\n }))\r\n .filter((entry) => entry.items.length > 0);\r\n\r\n const toggleGroup = (group: string) => {\r\n setCollapsedGroups((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(group)) {\r\n next.delete(group);\r\n } else {\r\n next.add(group);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const tableDropdownItems = [\r\n { label: zh ? '插入表格 3×3' : 'Insert Table 3×3', onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run() },\r\n { label: zh ? '上方插入行' : 'Add Row Before', onClick: () => editor.chain().focus().addRowBefore().run() },\r\n { label: zh ? '下方插入行' : 'Add Row After', onClick: () => editor.chain().focus().addRowAfter().run() },\r\n { label: zh ? '左侧插入列' : 'Add Column Before', onClick: () => editor.chain().focus().addColumnBefore().run() },\r\n { label: zh ? '右侧插入列' : 'Add Column After', onClick: () => editor.chain().focus().addColumnAfter().run() },\r\n { label: zh ? '删除行' : 'Delete Row', onClick: () => editor.chain().focus().deleteRow().run() },\r\n { label: zh ? '删除列' : 'Delete Column', onClick: () => editor.chain().focus().deleteColumn().run() },\r\n { label: zh ? '合并单元格' : 'Merge Cells', onClick: () => editor.chain().focus().mergeCells().run() },\r\n { label: zh ? '拆分单元格' : 'Split Cell', onClick: () => editor.chain().focus().splitCell().run() },\r\n { label: zh ? '切换表头' : 'Toggle Header Row', onClick: () => editor.chain().focus().toggleHeaderRow().run() },\r\n { label: zh ? '删除表格' : 'Delete Table', onClick: () => editor.chain().focus().deleteTable().run() },\r\n ];\r\n\r\n const figureDropdownItems = [\r\n { label: i18n.insertImageFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'image' }) },\r\n { label: i18n.insertMermaidFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'mermaid' }) },\r\n { label: i18n.insertDrawioFigure, onClick: () => void commandExecutor.execCommand('patent.insertFigure', { contentType: 'drawio' }) },\r\n ];\r\n\r\n const renderButton = (btn: ToolbarButton) => {\r\n if (btn.id === 'core-table') {\r\n return <DropdownButton key={btn.id} btn={btn} items={tableDropdownItems} />;\r\n }\r\n if (btn.id === 'patent-figure-insert') {\r\n return <DropdownButton key={btn.id} btn={btn} items={figureDropdownItems} />;\r\n }\r\n return (\r\n <button\r\n key={btn.id}\r\n onClick={btn.run}\r\n disabled={btn.disabled}\r\n className={clsx(\r\n 'p-2 rounded transition-colors',\r\n btn.disabled ? 'text-gray-400 cursor-not-allowed bg-gray-100' : 'hover:bg-gray-200',\r\n btn.isActive ? 'bg-gray-300 text-blue-600' : 'text-gray-700'\r\n )}\r\n title={btn.tooltip}\r\n >\r\n <btn.icon size={18} />\r\n </button>\r\n );\r\n };\r\n\r\n return (\r\n <div className=\"border-b border-gray-200 bg-gray-50 sticky top-0 z-10 overflow-x-auto\">\r\n <div className=\"flex flex-nowrap md:flex-wrap gap-2 p-2 min-w-max md:min-w-0\">\r\n <div className=\"flex items-center gap-1 pr-2 mr-2 border-r border-gray-200\">\r\n <span className=\"text-xs text-gray-500\">{i18n.language}</span>\r\n <select\r\n value={editorLanguage}\r\n onChange={(event) => {\r\n setEditorLanguage(event.target.value === 'en' ? 'en' : 'zh');\r\n }}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white text-gray-700\"\r\n >\r\n <option value=\"zh\">中文</option>\r\n <option value=\"en\">English</option>\r\n </select>\r\n </div>\r\n {groupedButtons.map((entry) => {\r\n const collapsed = collapsedGroups.has(entry.group);\r\n return (\r\n <div key={entry.group} className=\"flex items-center gap-1 pr-2 mr-2 border-r border-gray-200 last:border-r-0 last:mr-0 last:pr-0\">\r\n {collapsibleGroups && (\r\n <button\r\n onClick={() => {\r\n toggleGroup(entry.group);\r\n }}\r\n className=\"px-2 py-1 text-xs rounded bg-gray-200 text-gray-700 hover:bg-gray-300\"\r\n title={collapsed ? `${i18n.expand} ${formatGroupLabel(entry.group, i18n)}` : `${i18n.collapse} ${formatGroupLabel(entry.group, i18n)}`}\r\n >\r\n {formatGroupLabel(entry.group, i18n)}\r\n </button>\r\n )}\r\n {(!collapsibleGroups || !collapsed) &&\r\n entry.items.map(renderButton)}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState, useRef } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { Image, Trash2 } from 'lucide-react';\r\nimport { createCommandExecutor } from '../editor/core/EditorCore';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\n\r\ninterface NodeToolbarProps {\r\n editor: Editor | null;\r\n}\r\n\r\nexport const NodeToolbar: React.FC<NodeToolbarProps> = ({ editor }) => {\r\n const [version, setVersion] = useState(0);\r\n const [selectedFigureId, setSelectedFigureId] = useState<string>('');\r\n const editorLanguage = useEditorStore((state) => state.editorLanguage);\r\n const i18n = getEditorText(editorLanguage);\r\n\r\n useEffect(() => {\r\n if (!editor) return;\r\n const rerender = () => setVersion((v) => v + 1);\r\n editor.on('selectionUpdate', rerender);\r\n editor.on('update', rerender);\r\n return () => {\r\n editor.off('selectionUpdate', rerender);\r\n editor.off('update', rerender);\r\n };\r\n }, [editor]);\r\n\r\n if (!editor) return null;\r\n\r\n void version;\r\n\r\n const commandExecutor = createCommandExecutor(editor);\r\n\r\n const figureOptions: { id: string; label: string }[] = [];\r\n editor.state.doc.descendants((node) => {\r\n if (node.type.name !== 'figure') return true;\r\n const figureId = typeof node.attrs.id === 'string' ? node.attrs.id.trim() : '';\r\n if (!figureId) return true;\r\n figureOptions.push({ id: figureId, label: figureId });\r\n return true;\r\n });\r\n\r\n const activeFigure = commandExecutor.findAncestorNode('figure');\r\n const hasActiveFigure = Boolean(activeFigure);\r\n const activeFigureId = activeFigure\r\n ? (typeof activeFigure.node.attrs.id === 'string' ? activeFigure.node.attrs.id.trim() : '')\r\n : '';\r\n const activeFigureContentType: string = activeFigure\r\n ? (typeof activeFigure.node.attrs.contentType === 'string' ? activeFigure.node.attrs.contentType : 'image')\r\n : 'image';\r\n\r\n const [editingFigureId, setEditingFigureId] = useState('');\r\n const figureIdInputRef = useRef<HTMLInputElement>(null);\r\n const prevActiveFigurePos = useRef<number | null>(null);\r\n\r\n const currentFigurePos = activeFigure?.pos ?? null;\r\n if (currentFigurePos !== prevActiveFigurePos.current) {\r\n prevActiveFigurePos.current = currentFigurePos;\r\n if (hasActiveFigure && activeFigureId !== editingFigureId) {\r\n setEditingFigureId(activeFigureId);\r\n }\r\n }\r\n\r\n const handleFigureTypeChange = (newType: string) => {\r\n if (!activeFigure) return;\r\n void commandExecutor.execCommand('patent.updateFigure', {\r\n position: activeFigure.pos,\r\n contentType: newType,\r\n });\r\n };\r\n\r\n const handleFigureIdCommit = () => {\r\n if (!activeFigure) return;\r\n const trimmed = editingFigureId.trim();\r\n if (trimmed === activeFigureId) return;\r\n void commandExecutor.execCommand('patent.updateFigure', {\r\n position: activeFigure.pos,\r\n id: trimmed,\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"border-b border-gray-200 bg-gray-50 p-2\">\r\n <div className=\"bg-white border border-gray-200 rounded-md px-2 py-2 flex flex-wrap items-center gap-2\">\r\n\r\n {figureOptions.length > 0 && (\r\n <>\r\n <span className=\"text-xs text-gray-500\">{i18n.figureReferenceTarget}</span>\r\n <select\r\n value={selectedFigureId || '__none__'}\r\n onChange={(e) => setSelectedFigureId(e.target.value === '__none__' ? '' : e.target.value)}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white\"\r\n >\r\n <option value=\"__none__\">{i18n.figureReferenceTargetPlaceholder}</option>\r\n {figureOptions.map((item) => (\r\n <option key={item.id} value={item.id}>{item.label}</option>\r\n ))}\r\n </select>\r\n <button\r\n onClick={() => {\r\n if (!selectedFigureId) return;\r\n void commandExecutor.execCommand('patent.insertFigureReference', {\r\n targetType: 'figure',\r\n targetFigureId: selectedFigureId,\r\n });\r\n }}\r\n className=\"p-2 hover:bg-blue-50 text-blue-600 rounded\"\r\n title={i18n.insertFigureReference}\r\n >\r\n <Image size={16} />\r\n </button>\r\n </>\r\n )}\r\n\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n\r\n {hasActiveFigure && (\r\n <>\r\n <span className=\"text-xs font-medium text-gray-700\">\r\n {i18n.currentFigure}\r\n </span>\r\n <span className=\"text-xs text-gray-500\">{i18n.figureId}</span>\r\n <input\r\n ref={figureIdInputRef}\r\n type=\"text\"\r\n value={editingFigureId}\r\n onChange={(e) => setEditingFigureId(e.target.value)}\r\n onBlur={handleFigureIdCommit}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n handleFigureIdCommit();\r\n (e.target as HTMLInputElement).blur();\r\n }\r\n }}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white w-20\"\r\n placeholder={editorLanguage === 'en' ? 'Fig.1' : '图1'}\r\n />\r\n <span className=\"text-xs text-gray-500\">{i18n.switchFigureType}</span>\r\n <select\r\n value={activeFigureContentType}\r\n onChange={(e) => handleFigureTypeChange(e.target.value)}\r\n className=\"text-xs border border-gray-200 rounded px-2 py-1 bg-white\"\r\n >\r\n <option value=\"image\">{i18n.figureContentTypeImage}</option>\r\n <option value=\"mermaid\">{i18n.figureContentTypeMermaid}</option>\r\n <option value=\"drawio\">{i18n.figureContentTypeDrawio}</option>\r\n </select>\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n </>\r\n )}\r\n\r\n {editor.isActive('image') && (() => {\r\n const attrs = editor.getAttributes('image');\r\n const currentWidth = attrs.width || '';\r\n const widths = ['25%', '50%', '75%', '100%'];\r\n return (\r\n <>\r\n <span className=\"text-xs font-medium text-gray-700\">\r\n {editorLanguage === 'zh' ? '图片' : 'Image'}\r\n </span>\r\n {widths.map((w) => (\r\n <button\r\n key={w}\r\n onClick={() => editor.chain().focus().updateAttributes('image', { width: w }).run()}\r\n className={`text-xs px-2 py-0.5 rounded border ${\r\n currentWidth === w\r\n ? 'bg-blue-50 text-blue-700 border-blue-200'\r\n : 'bg-white text-gray-600 border-gray-200 hover:bg-gray-50'\r\n }`}\r\n >\r\n {w}\r\n </button>\r\n ))}\r\n <div className=\"h-6 w-px bg-gray-200 mx-1\" />\r\n </>\r\n );\r\n })()}\r\n\r\n <button\r\n onClick={async () => {\r\n if (editor.chain().focus().deleteSelection().run()) return;\r\n const { from } = editor.state.selection;\r\n if (from > 1) editor.chain().focus().deleteRange({ from: from - 1, to: from }).run();\r\n }}\r\n className=\"p-2 hover:bg-red-50 text-red-600 rounded\"\r\n title={i18n.deleteSelection}\r\n >\r\n <Trash2 size={16} />\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import type { PatentSectionType } from '../plugins/patent/sectionNode';\r\n\r\nexport const sectionContextDeps: Record<PatentSectionType, PatentSectionType[]> = {\r\n // Invention & Utility Model\r\n technical_field: [],\r\n background_art: ['technical_field'],\r\n summary: ['technical_field', 'background_art'],\r\n drawing_description: ['summary'],\r\n detailed_description: ['summary', 'claims', 'drawing_description'],\r\n claims: ['summary'],\r\n abstract: ['claims', 'summary'],\r\n abstract_drawing: ['drawing_description'],\r\n drawing_figures: ['drawing_description'],\r\n // Design Patent\r\n design_product_name: [],\r\n design_usage: ['design_product_name'],\r\n design_description: ['design_product_name', 'design_usage'],\r\n design_views: ['design_description'],\r\n design_brief: ['design_description', 'design_views'],\r\n};\r\n\r\nexport function getMissingSectionDeps(\r\n targetSection: PatentSectionType,\r\n completedSections: Set<PatentSectionType>\r\n): PatentSectionType[] {\r\n const deps = sectionContextDeps[targetSection] || [];\r\n return deps.filter(dep => !completedSections.has(dep));\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport type { PatentSectionType } from '../plugins/patent/sectionNode';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\nimport { useEditorStore } from '../../store/editorStore';\r\nimport { sectionContextDeps } from './sectionContextDeps';\r\n\r\nexport interface AIContext {\r\n scope: 'selection' | 'section' | 'document';\r\n sectionType?: PatentSectionType;\r\n targetSectionPos?: number;\r\n userInput?: string;\r\n selectedText?: string;\r\n dependencyContext?: {\r\n sectionType: PatentSectionType;\r\n content: string;\r\n }[];\r\n surroundingText?: string;\r\n language: EditorLanguage;\r\n}\r\n\r\nexport interface SectionInfo {\r\n sectionType: PatentSectionType;\r\n pos: number;\r\n content: string;\r\n}\r\n\r\nexport function getAllSections(editor: Editor): SectionInfo[] {\r\n const sections: SectionInfo[] = [];\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n sections.push({\r\n sectionType: 'patent_title' as unknown as PatentSectionType,\r\n pos,\r\n content: node.textContent || '',\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n sections.push({\r\n sectionType: node.attrs.sectionType as PatentSectionType,\r\n pos,\r\n content: node.textContent || '',\r\n });\r\n return false;\r\n }\r\n return true;\r\n });\r\n return sections;\r\n}\r\n\r\nexport function findSectionAtCursor(editor: Editor): SectionInfo | null {\r\n const { from } = editor.state.selection;\r\n const $pos = editor.state.doc.resolve(from);\r\n for (let depth = $pos.depth; depth >= 0; depth--) {\r\n const node = $pos.node(depth);\r\n if (node.type.name === 'patent_title') {\r\n return {\r\n sectionType: 'patent_title' as unknown as PatentSectionType,\r\n pos: $pos.before(depth),\r\n content: node.textContent || '',\r\n };\r\n }\r\n if (node.type.name === 'patent_section') {\r\n return {\r\n sectionType: node.attrs.sectionType as PatentSectionType,\r\n pos: $pos.before(depth),\r\n content: node.textContent || '',\r\n };\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nexport function serializeSectionContent(editor: Editor, sectionType: PatentSectionType): string {\r\n const sections = getAllSections(editor);\r\n const section = sections.find(s => s.sectionType === sectionType);\r\n if (!section) return '';\r\n return section.content.trim();\r\n}\r\n\r\nexport function buildDependencyContext(\r\n editor: Editor,\r\n targetSectionType: PatentSectionType\r\n): AIContext['dependencyContext'] {\r\n const deps = sectionContextDeps[targetSectionType];\r\n if (!deps || deps.length === 0) return [];\r\n\r\n const sections = getAllSections(editor);\r\n const sectionMap = new Map(sections.map(s => [s.sectionType, s]));\r\n\r\n return deps\r\n .map(depType => {\r\n const section = sectionMap.get(depType);\r\n if (!section || section.content.trim().length === 0) return null;\r\n return {\r\n sectionType: depType,\r\n content: section.content.trim(),\r\n };\r\n })\r\n .filter((item): item is NonNullable<typeof item> => item !== null && item.content.length > 0);\r\n}\r\n\r\nexport function buildAIContext(\r\n editor: Editor,\r\n options: {\r\n scope?: AIContext['scope'];\r\n sectionType?: PatentSectionType;\r\n targetSectionPos?: number;\r\n userInput?: string;\r\n } = {}\r\n): AIContext {\r\n const language = useEditorStore.getState().editorLanguage;\r\n const { from, to } = editor.state.selection;\r\n const selectedText = from !== to\r\n ? editor.state.doc.textBetween(from, to, ' ', '\\0')\r\n : undefined;\r\n\r\n let sectionType = options.sectionType;\r\n let targetSectionPos = options.targetSectionPos;\r\n\r\n if (!sectionType) {\r\n const current = findSectionAtCursor(editor);\r\n if (current) {\r\n sectionType = current.sectionType;\r\n targetSectionPos = current.pos;\r\n }\r\n }\r\n\r\n const scope = options.scope || (sectionType ? 'section' : (selectedText ? 'selection' : 'document'));\r\n\r\n const dependencyContext = sectionType\r\n ? buildDependencyContext(editor, sectionType)\r\n : undefined;\r\n\r\n let surroundingText: string | undefined;\r\n if (scope === 'selection' && from !== to) {\r\n const contextRange = 200;\r\n const beforeFrom = Math.max(0, from - contextRange);\r\n const afterTo = Math.min(editor.state.doc.content.size, to + contextRange);\r\n const before = editor.state.doc.textBetween(beforeFrom, from, ' ', '\\0');\r\n const after = editor.state.doc.textBetween(to, afterTo, ' ', '\\0');\r\n surroundingText = `...${before}[SELECTED]${after}...`;\r\n }\r\n\r\n return {\r\n scope,\r\n sectionType,\r\n targetSectionPos,\r\n userInput: options.userInput,\r\n selectedText,\r\n dependencyContext,\r\n surroundingText,\r\n language,\r\n };\r\n}\r\n","import React from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { BubbleMenu as TiptapBubbleMenu } from '@tiptap/react/menus';\r\nimport {\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strikethrough,\r\n Code,\r\n Superscript,\r\n Subscript,\r\n Link2,\r\n Highlighter,\r\n Sparkles,\r\n} from 'lucide-react';\r\nimport clsx from 'clsx';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { findSectionAtCursor } from '../editor/ai/aiContext';\r\n\r\ninterface EditorBubbleMenuProps {\r\n editor: Editor;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport const EditorBubbleMenu: React.FC<EditorBubbleMenuProps> = ({ editor, onSelectionOptimize }) => {\r\n const { addChatReference, openChatPanel, editorLanguage } = useEditorStore();\r\n const zh = editorLanguage === 'zh';\r\n\r\n const btnClass = (active: boolean) =>\r\n clsx(\r\n 'p-1.5 rounded transition-colors',\r\n active ? 'bg-blue-100 text-blue-600' : 'text-gray-600 hover:bg-gray-100'\r\n );\r\n\r\n const handleAIOptimize = () => {\r\n const { from, to } = editor.state.selection;\r\n if (from === to) return;\r\n const selectedText = editor.state.doc.textBetween(from, to, ' ');\r\n const section = findSectionAtCursor(editor);\r\n if (onSelectionOptimize) {\r\n onSelectionOptimize({ text: selectedText, from, to, sectionType: section?.sectionType });\r\n return;\r\n }\r\n addChatReference({ text: selectedText, from, to, sectionType: section?.sectionType });\r\n openChatPanel();\r\n };\r\n\r\n const handleLink = () => {\r\n const prev = editor.getAttributes('link').href;\r\n const url = window.prompt('URL', prev || 'https://');\r\n if (url === null) return;\r\n if (url === '') {\r\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\r\n } else {\r\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\r\n }\r\n };\r\n\r\n return (\r\n <TiptapBubbleMenu\r\n editor={editor}\r\n shouldShow={({ editor, state }) => {\r\n const { from, to } = state.selection;\r\n if (from === to) return false;\r\n if (editor.isActive('codeBlock')) return false;\r\n return true;\r\n }}\r\n >\r\n <div className=\"bubble-menu\">\r\n <button\r\n onClick={() => editor.chain().focus().toggleBold().run()}\r\n className={btnClass(editor.isActive('bold'))}\r\n title=\"Bold\"\r\n >\r\n <Bold size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleItalic().run()}\r\n className={btnClass(editor.isActive('italic'))}\r\n title=\"Italic\"\r\n >\r\n <Italic size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleUnderline().run()}\r\n className={btnClass(editor.isActive('underline'))}\r\n title=\"Underline\"\r\n >\r\n <Underline size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleStrike().run()}\r\n className={btnClass(editor.isActive('strike'))}\r\n title=\"Strikethrough\"\r\n >\r\n <Strikethrough size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleCode().run()}\r\n className={btnClass(editor.isActive('code'))}\r\n title=\"Code\"\r\n >\r\n <Code size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleSuperscript().run()}\r\n className={btnClass(editor.isActive('superscript'))}\r\n title=\"Superscript\"\r\n >\r\n <Superscript size={15} />\r\n </button>\r\n <button\r\n onClick={() => editor.chain().focus().toggleSubscript().run()}\r\n className={btnClass(editor.isActive('subscript'))}\r\n title=\"Subscript\"\r\n >\r\n <Subscript size={15} />\r\n </button>\r\n <div className=\"bubble-menu-divider\" />\r\n <button\r\n onClick={() => editor.chain().focus().toggleHighlight().run()}\r\n className={btnClass(editor.isActive('highlight'))}\r\n title=\"Highlight\"\r\n >\r\n <Highlighter size={15} />\r\n </button>\r\n <button\r\n onClick={handleLink}\r\n className={btnClass(editor.isActive('link'))}\r\n title=\"Link\"\r\n >\r\n <Link2 size={15} />\r\n </button>\r\n <div className=\"bubble-menu-divider\" />\r\n <button\r\n onClick={handleAIOptimize}\r\n className=\"p-1.5 rounded transition-colors text-purple-500 hover:bg-purple-50\"\r\n title={zh ? 'AI 优化' : 'AI Optimize'}\r\n >\r\n <Sparkles size={15} />\r\n </button>\r\n </div>\r\n </TiptapBubbleMenu>\r\n );\r\n};\r\n","import React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { X, ChevronUp, ChevronDown, Replace, ReplaceAll, CaseSensitive } from 'lucide-react';\r\nimport clsx from 'clsx';\r\n\r\ninterface FindReplaceProps {\r\n editor: Editor;\r\n}\r\n\r\nexport const FindReplace: React.FC<FindReplaceProps> = ({ editor }) => {\r\n const [visible, setVisible] = useState(false);\r\n const [showReplace, setShowReplace] = useState(false);\r\n const [searchTerm, setSearchTerm] = useState('');\r\n const [replaceTerm, setReplaceTerm] = useState('');\r\n const [caseSensitive, setCaseSensitive] = useState(false);\r\n const searchInputRef = useRef<HTMLInputElement>(null);\r\n\r\n const storage = (editor.extensionStorage as any).searchReplace;\r\n const resultCount = storage?.results?.length ?? 0;\r\n const currentIndex = storage?.currentIndex ?? -1;\r\n\r\n useEffect(() => {\r\n const handler = (e: Event) => {\r\n setVisible(true);\r\n const detail = (e as CustomEvent).detail;\r\n if (detail?.replace) setShowReplace(true);\r\n requestAnimationFrame(() => searchInputRef.current?.focus());\r\n };\r\n window.addEventListener('editor:toggleSearch', handler);\r\n return () => window.removeEventListener('editor:toggleSearch', handler);\r\n }, []);\r\n\r\n const doSearch = useCallback(\r\n (term: string) => {\r\n setSearchTerm(term);\r\n (editor.commands as any).setSearchTerm(term);\r\n },\r\n [editor]\r\n );\r\n\r\n const close = useCallback(() => {\r\n setVisible(false);\r\n (editor.commands as any).clearSearch();\r\n editor.commands.focus();\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape' && visible) {\r\n close();\r\n }\r\n };\r\n window.addEventListener('keydown', handler);\r\n return () => window.removeEventListener('keydown', handler);\r\n }, [visible, close]);\r\n\r\n const toggleCaseSensitive = () => {\r\n const next = !caseSensitive;\r\n setCaseSensitive(next);\r\n (editor.commands as any).setCaseSensitive(next);\r\n };\r\n\r\n if (!visible) return null;\r\n\r\n return (\r\n <div className=\"find-replace-bar\">\r\n <div className=\"find-replace-row\">\r\n <div className=\"find-replace-input-group\">\r\n <input\r\n ref={searchInputRef}\r\n type=\"text\"\r\n value={searchTerm}\r\n onChange={(e) => doSearch(e.target.value)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') {\r\n e.shiftKey\r\n ? (editor.commands as any).previousSearchResult()\r\n : (editor.commands as any).nextSearchResult();\r\n }\r\n }}\r\n placeholder=\"Find...\"\r\n className=\"find-replace-input\"\r\n />\r\n <span className=\"find-replace-count\">\r\n {resultCount > 0 ? `${currentIndex + 1}/${resultCount}` : searchTerm ? '0' : ''}\r\n </span>\r\n </div>\r\n <button\r\n onClick={toggleCaseSensitive}\r\n className={clsx('find-replace-btn', caseSensitive && 'find-replace-btn--active')}\r\n title=\"Case Sensitive\"\r\n >\r\n <CaseSensitive size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).previousSearchResult()} className=\"find-replace-btn\" title=\"Previous\">\r\n <ChevronUp size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).nextSearchResult()} className=\"find-replace-btn\" title=\"Next\">\r\n <ChevronDown size={15} />\r\n </button>\r\n <button\r\n onClick={() => setShowReplace((v) => !v)}\r\n className={clsx('find-replace-btn', showReplace && 'find-replace-btn--active')}\r\n title=\"Toggle Replace\"\r\n >\r\n <Replace size={15} />\r\n </button>\r\n <button onClick={close} className=\"find-replace-btn\" title=\"Close (Esc)\">\r\n <X size={15} />\r\n </button>\r\n </div>\r\n {showReplace && (\r\n <div className=\"find-replace-row\">\r\n <input\r\n type=\"text\"\r\n value={replaceTerm}\r\n onChange={(e) => {\r\n setReplaceTerm(e.target.value);\r\n (editor.commands as any).setReplaceTerm(e.target.value);\r\n }}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') (editor.commands as any).replaceCurrent();\r\n }}\r\n placeholder=\"Replace...\"\r\n className=\"find-replace-input\"\r\n />\r\n <button onClick={() => (editor.commands as any).replaceCurrent()} className=\"find-replace-btn\" title=\"Replace\">\r\n <Replace size={15} />\r\n </button>\r\n <button onClick={() => (editor.commands as any).replaceAll()} className=\"find-replace-btn\" title=\"Replace All\">\r\n <ReplaceAll size={15} />\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useMemo } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { useEditorStore } from '../store/editorStore';\r\n\r\ninterface WordCountProps {\r\n editor: Editor;\r\n}\r\n\r\nexport const WordCount: React.FC<WordCountProps> = ({ editor }) => {\r\n const { editorLanguage } = useEditorStore();\r\n const zh = editorLanguage === 'zh';\r\n\r\n const stats = useMemo(() => {\r\n const state = editor.state;\r\n const docText = state.doc.textBetween(0, state.doc.content.size, ' ', '\\0');\r\n const charCount = docText.replace(/\\s/g, '').length;\r\n\r\n const { from, to } = state.selection;\r\n let selectionCount = 0;\r\n if (from !== to) {\r\n const selText = state.doc.textBetween(from, to, ' ', '\\0');\r\n selectionCount = selText.replace(/\\s/g, '').length;\r\n }\r\n\r\n return { charCount, selectionCount };\r\n }, [editor.state.doc, editor.state.selection]);\r\n\r\n return (\r\n <div className=\"word-count-bar\">\r\n <span>{zh ? '字数' : 'Characters'}: {stats.charCount}</span>\r\n {stats.selectionCount > 0 && (\r\n <span>{zh ? '选区' : 'Selected'}: {stats.selectionCount}</span>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useState, useMemo } from 'react';\r\nimport { Editor } from '@tiptap/react';\r\nimport { ChevronRight, ChevronDown, FileText, PanelLeftClose, PanelLeft } from 'lucide-react';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport clsx from 'clsx';\r\n\r\ninterface OutlinePanelProps {\r\n editor: Editor;\r\n}\r\n\r\ninterface OutlineItem {\r\n type: 'section' | 'heading' | 'book-group';\r\n pos: number;\r\n title: string;\r\n state?: string;\r\n level?: number;\r\n charCount: number;\r\n indent?: boolean;\r\n}\r\n\r\nconst STATE_ICONS: Record<string, string> = {\r\n empty: '○',\r\n filled: '●',\r\n};\r\n\r\nconst STATE_COLORS: Record<string, string> = {\r\n empty: 'text-gray-400',\r\n filled: 'text-green-500',\r\n};\r\n\r\nconst DESCRIPTION_SUB_TYPES = new Set([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\nexport const OutlinePanel: React.FC<OutlinePanelProps> = ({ editor }) => {\r\n const { editorLanguage } = useEditorStore();\r\n const i18n = getEditorText(editorLanguage);\r\n const [collapsed, setCollapsed] = useState(false);\r\n const [version, setVersion] = useState(0);\r\n\r\n useEffect(() => {\r\n const handler = () => setVersion((v) => v + 1);\r\n editor.on('update', handler);\r\n return () => { editor.off('update', handler); };\r\n }, [editor]);\r\n\r\n const items = useMemo(() => {\r\n void version;\r\n const result: OutlineItem[] = [];\r\n let descriptionGroupInserted = false;\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n // Insert \"说明书\" group header before the first title/sub-section\r\n if (!descriptionGroupInserted) {\r\n const bookLabel = (typeof (i18n as Record<string, unknown>)['bookTitle_description'] === 'string'\r\n ? (i18n as Record<string, unknown>)['bookTitle_description'] : '说明书') as string;\r\n result.push({\r\n type: 'book-group',\r\n pos,\r\n title: bookLabel,\r\n charCount: 0,\r\n });\r\n descriptionGroupInserted = true;\r\n }\r\n const text = node.textContent || '';\r\n const hasContent = text.trim().length > 0;\r\n const placeholder = (typeof i18n['patentTitlePlaceholder'] === 'string'\r\n ? i18n['patentTitlePlaceholder'] : 'Patent Title') as string;\r\n result.push({\r\n type: 'section',\r\n pos,\r\n title: hasContent ? text.trim() : placeholder,\r\n state: hasContent ? 'filled' : 'empty',\r\n charCount: text.replace(/\\s/g, '').length,\r\n indent: true,\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const isSub = DESCRIPTION_SUB_TYPES.has(sectionType);\r\n const key = `sectionTitle_${sectionType}` as keyof typeof i18n;\r\n const title = (typeof i18n[key] === 'string' ? i18n[key] : sectionType) as string;\r\n const text = node.textContent || '';\r\n const hasContent = text.trim().length > 0;\r\n result.push({\r\n type: 'section',\r\n pos,\r\n title,\r\n state: hasContent ? 'filled' : 'empty',\r\n charCount: text.replace(/\\s/g, '').length,\r\n indent: isSub,\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'heading') {\r\n const level = node.attrs.level as number;\r\n const text = node.textContent || '';\r\n if (text.trim()) {\r\n result.push({\r\n type: 'heading',\r\n pos,\r\n title: text,\r\n level,\r\n charCount: text.replace(/\\s/g, '').length,\r\n });\r\n }\r\n return false;\r\n }\r\n return true;\r\n });\r\n return result;\r\n }, [editor, version, i18n]);\r\n\r\n if (collapsed) {\r\n return (\r\n <div className=\"outline-panel outline-panel--collapsed\">\r\n <button\r\n onClick={() => setCollapsed(false)}\r\n className=\"outline-panel-toggle\"\r\n title={editorLanguage === 'zh' ? '展开大纲' : 'Expand Outline'}\r\n >\r\n <PanelLeft size={16} />\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"outline-panel\">\r\n <div className=\"outline-panel-header\">\r\n <FileText size={14} />\r\n <span>{editorLanguage === 'zh' ? '文档大纲' : 'Outline'}</span>\r\n <button\r\n onClick={() => setCollapsed(true)}\r\n className=\"outline-panel-toggle ml-auto\"\r\n title={editorLanguage === 'zh' ? '收起大纲' : 'Collapse Outline'}\r\n >\r\n <PanelLeftClose size={14} />\r\n </button>\r\n </div>\r\n <div className=\"outline-panel-list\">\r\n {items.length === 0 && (\r\n <div className=\"outline-panel-empty\">\r\n {editorLanguage === 'zh' ? '暂无章节' : 'No sections yet'}\r\n </div>\r\n )}\r\n {items.map((item, idx) => (\r\n <button\r\n key={`${item.pos}-${idx}`}\r\n className={clsx(\r\n 'outline-panel-item',\r\n item.type === 'heading' && `outline-panel-item--h${item.level}`,\r\n item.type === 'book-group' && 'outline-panel-item--book',\r\n item.indent && 'outline-panel-item--indent',\r\n )}\r\n onClick={() => {\r\n if (item.type === 'book-group') return;\r\n editor.chain().setTextSelection(item.pos + 1).focus().run();\r\n requestAnimationFrame(() => {\r\n const el = editor.view.nodeDOM(item.pos) as HTMLElement | null;\r\n el?.scrollIntoView({ behavior: 'smooth', block: 'start' });\r\n });\r\n }}\r\n >\r\n {item.type === 'section' && item.state && (\r\n <span className={clsx('outline-item-state', STATE_COLORS[item.state])}>\r\n {STATE_ICONS[item.state] || '○'}\r\n </span>\r\n )}\r\n <span className=\"outline-item-title\">{item.title}</span>\r\n {item.type !== 'book-group' && (\r\n <span className=\"outline-item-count\">{item.charCount}</span>\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect } from 'react';\r\nimport { Editor, EditorContent } from '@tiptap/react';\r\nimport clsx from 'clsx';\r\n\r\ntype RenderMode = 'edit' | 'readonly';\r\n\r\ninterface NodeRendererProps {\r\n editor: Editor;\r\n mode?: RenderMode;\r\n className?: string;\r\n}\r\n\r\nexport const NodeRenderer: React.FC<NodeRendererProps> = ({\r\n editor,\r\n mode = 'edit',\r\n className,\r\n}) => {\r\n useEffect(() => {\r\n editor.setEditable(mode === 'edit');\r\n }, [editor, mode]);\r\n\r\n return (\r\n <div\r\n className={clsx(\r\n 'h-full',\r\n mode === 'readonly' ? 'cursor-default' : 'cursor-text',\r\n className\r\n )}\r\n >\r\n <EditorContent editor={editor} className=\"h-full\" />\r\n </div>\r\n );\r\n};\r\n","import React, { useEffect, useRef, useCallback } from 'react';\r\nimport { useEditor, JSONContent, Editor } from '@tiptap/react';\r\nimport { createEditorConfig } from '../editor/core/EditorCore';\r\nimport { pluginManager } from '../editor/core/PluginManager';\r\nimport { Toolbar } from './Toolbar';\r\nimport { NodeToolbar } from './NodeToolbar';\r\n\r\nimport { EditorBubbleMenu } from './BubbleMenu';\r\nimport { FindReplace } from './FindReplace';\r\nimport { WordCount } from './WordCount';\r\nimport { OutlinePanel } from './OutlinePanel';\r\n\r\nimport { NodeRenderer } from '../editor/renderer';\r\nimport { useEditorStore } from '../store/editorStore';\r\nimport { getEditorText } from '../lib/editorI18n';\r\nimport '../styles/editor.css';\r\n\r\nconst AUTO_SAVE_KEY = 'patent-editor-draft';\r\nconst AUTO_SAVE_DEBOUNCE_MS = 1500;\r\n\r\nconst loadDraftFromStorage = (): JSONContent | null => {\r\n try {\r\n const raw = localStorage.getItem(AUTO_SAVE_KEY);\r\n if (!raw) return null;\r\n return JSON.parse(raw) as JSONContent;\r\n } catch {\r\n return null;\r\n }\r\n};\r\n\r\ninterface EditorViewProps {\r\n initialContent?: JSONContent;\r\n onChange?: (content: JSONContent) => void;\r\n className?: string;\r\n readOnly?: boolean;\r\n /** Disable content editing without hiding toolbar/UI (unlike readOnly). */\r\n editable?: boolean;\r\n onEditorReady?: (editor: Editor) => void;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport const EditorView: React.FC<EditorViewProps> = ({\r\n initialContent,\r\n onChange,\r\n className,\r\n readOnly = false,\r\n editable = true,\r\n onEditorReady,\r\n onSelectionOptimize,\r\n}) => {\r\n const { setEditor, setDocument, editorLanguage, autoSaveStatus, ai } = useEditorStore();\r\n const { setAutoSaveStatus, setLastSavedAt } = useEditorStore();\r\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n\r\n const resolvedInitialContent = initialContent || (!onChange ? loadDraftFromStorage() : null) || {\r\n type: 'doc',\r\n content: [\r\n {\r\n type: 'paragraph',\r\n content: [{ type: 'text', text: '' }],\r\n },\r\n ],\r\n };\r\n\r\n const saveToStorage = useCallback((json: JSONContent) => {\r\n try {\r\n setAutoSaveStatus('saving');\r\n localStorage.setItem(AUTO_SAVE_KEY, JSON.stringify(json));\r\n setAutoSaveStatus('saved');\r\n setLastSavedAt(new Date());\r\n } catch {\r\n setAutoSaveStatus('error');\r\n }\r\n }, [setAutoSaveStatus, setLastSavedAt]);\r\n\r\n const editor = useEditor(\r\n createEditorConfig({\r\n content: resolvedInitialContent,\r\n onUpdate: ({ editor }) => {\r\n const json = editor.getJSON();\r\n setDocument(json);\r\n pluginManager.notifyStateChange(editor);\r\n if (onChange) {\r\n onChange(json);\r\n }\r\n if (!onChange) {\r\n if (debounceRef.current) {\r\n clearTimeout(debounceRef.current);\r\n }\r\n debounceRef.current = setTimeout(() => {\r\n saveToStorage(json);\r\n }, AUTO_SAVE_DEBOUNCE_MS);\r\n }\r\n },\r\n onCreate: ({ editor }) => {\r\n setEditor(editor);\r\n onEditorReady?.(editor);\r\n pluginManager.initializePlugins(editor);\r\n pluginManager.notifyStateChange(editor);\r\n },\r\n onSelectionUpdate: ({ editor }) => {\r\n pluginManager.notifySelectionChange(editor);\r\n },\r\n editorProps: {\r\n attributes: {\r\n class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none',\r\n },\r\n },\r\n })\r\n );\r\n\r\n const initialContentAppliedRef = useRef(false);\r\n useEffect(() => {\r\n if (!editor || !initialContent) return;\r\n if (!initialContentAppliedRef.current) {\r\n initialContentAppliedRef.current = true;\r\n return;\r\n }\r\n editor.commands.setContent(initialContent);\r\n }, [editor, initialContent]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (debounceRef.current) {\r\n clearTimeout(debounceRef.current);\r\n }\r\n if (editor) {\r\n pluginManager.destroyPlugins(editor);\r\n editor.destroy();\r\n }\r\n };\r\n }, [editor]);\r\n\r\n useEffect(() => {\r\n if (!editor) {\r\n return;\r\n }\r\n pluginManager.notifyStateChange(editor);\r\n }, [editor, editorLanguage]);\r\n\r\n if (!editor) {\r\n return null;\r\n }\r\n\r\n const i18n = getEditorText(editorLanguage);\r\n const saveLabel =\r\n autoSaveStatus === 'saving' ? i18n.autoSaveSaving :\r\n autoSaveStatus === 'saved' ? i18n.autoSaveSaved :\r\n autoSaveStatus === 'error' ? i18n.autoSaveError : '';\r\n\r\n return (\r\n <div className={`editor-container flex flex-col h-full ${className}`}>\r\n {!readOnly && (\r\n <div className=\"flex items-center\">\r\n <Toolbar editor={editor} />\r\n {saveLabel && (\r\n <span className={`auto-save-indicator auto-save-indicator--${autoSaveStatus} ml-2`}>\r\n {saveLabel}\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n {!readOnly && editor && <NodeToolbar editor={editor} />}\r\n {!readOnly && editor && <EditorBubbleMenu editor={editor} onSelectionOptimize={onSelectionOptimize} />}\r\n {!readOnly && editor && <FindReplace editor={editor} />}\r\n <div className=\"flex flex-1 overflow-hidden\">\r\n {!readOnly && editor && <OutlinePanel editor={editor} />}\r\n <div className=\"flex-1 overflow-y-auto bg-white p-4 relative\">\r\n <NodeRenderer\r\n editor={editor}\r\n mode={readOnly || !editable || (ai.status === 'streaming' && ai.activeSectionType === 'claims') ? 'readonly' : 'edit'}\r\n />\r\n </div>\r\n </div>\r\n {!readOnly && <WordCount editor={editor} />}\r\n </div>\r\n );\r\n};\r\n","import type { PatentSectionType } from '../plugins/patent/sectionNode';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\n\r\n// ── AI Completion Request (stateless, for generate) ──\r\n\r\nexport type AIAction = 'generate';\r\n\r\nexport interface AIRequest {\r\n action: AIAction;\r\n sectionType?: PatentSectionType;\r\n instruction?: string;\r\n content?: string;\r\n dependencyContext?: { sectionType: string; content: string }[];\r\n language: EditorLanguage;\r\n}\r\n\r\n// ── Chat Session Types ──\r\n\r\nexport interface ChatReference {\r\n text: string;\r\n source?: string;\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport interface ChatMessageRequest {\r\n content: string;\r\n references?: ChatReference[];\r\n language: EditorLanguage;\r\n}\r\n\r\nexport interface ChatMessageResponse {\r\n messageId: string;\r\n sessionId: string;\r\n status: 'processing' | 'done' | 'error';\r\n}\r\n\r\nexport interface ChatSession {\r\n sessionId: string;\r\n patentId?: string;\r\n title: string;\r\n lastMessage?: string;\r\n messageCount: number;\r\n createdAt: string;\r\n updatedAt: string;\r\n}\r\n\r\nexport interface ChatMessage {\r\n messageId: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n references?: ChatReference[];\r\n patches?: AIPatchData[];\r\n usage?: { tokens: number };\r\n status: 'processing' | 'done' | 'error';\r\n createdAt: string;\r\n}\r\n\r\n// ── Response events (SSE) ──\r\n\r\nexport interface AIPatchTarget {\r\n type: 'section' | 'ref' | 'search';\r\n sectionType?: PatentSectionType;\r\n refIndex?: number;\r\n searchText?: string;\r\n}\r\n\r\nexport interface AIPatchData {\r\n op: 'replace' | 'insert' | 'delete';\r\n target: AIPatchTarget;\r\n search?: string;\r\n content: string;\r\n reason?: string;\r\n // Legacy fields (backward compat with old protocol)\r\n from?: number;\r\n to?: number;\r\n}\r\n\r\nexport type AIResponseEvent =\r\n | { type: 'delta'; content: string }\r\n | { type: 'patch'; patch: AIPatchData }\r\n | { type: 'done'; usage?: { tokens: number } }\r\n | { type: 'error'; message: string };\r\n\r\n// ── Adapter interface ──\r\n\r\nexport interface AIServiceAdapter {\r\n request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>>;\r\n abort(): void;\r\n}\r\n\r\n// ── Chat Session API client ──\r\n\r\nexport interface ChatSessionAPI {\r\n createSession(patentId?: string, title?: string, language?: EditorLanguage): Promise<ChatSession>;\r\n listSessions(patentId?: string, page?: number, pageSize?: number): Promise<{ total: number; items: ChatSession[] }>;\r\n getMessages(sessionId: string, page?: number, pageSize?: number): Promise<{ total: number; items: ChatMessage[] }>;\r\n deleteSession(sessionId: string): Promise<void>;\r\n sendMessage(sessionId: string, req: ChatMessageRequest): Promise<ChatMessageResponse>;\r\n subscribeStream(sessionId: string, messageId: string): Promise<ReadableStream<AIResponseEvent>>;\r\n abort(): void;\r\n}\r\n\r\n// ── Default SSE implementation ──\r\n\r\nfunction parseSSEStream(body: ReadableStream<Uint8Array>): ReadableStream<AIResponseEvent> {\r\n const reader = body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n\r\n return new ReadableStream<AIResponseEvent>({\r\n async pull(controller) {\r\n // eslint-disable-next-line no-constant-condition\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) {\r\n controller.close();\r\n return;\r\n }\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n let currentEvent = '';\r\n\r\n for (const line of lines) {\r\n if (line.startsWith('event: ')) {\r\n currentEvent = line.slice(7).trim();\r\n continue;\r\n }\r\n\r\n if (!line.startsWith('data: ')) continue;\r\n const raw = line.slice(6).trim();\r\n if (raw === '[DONE]') {\r\n controller.enqueue({ type: 'done' });\r\n controller.close();\r\n return;\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(raw);\r\n const eventType = currentEvent || parsed.type;\r\n\r\n if (eventType === 'delta' || (!eventType && parsed.content != null)) {\r\n controller.enqueue({\r\n type: 'delta',\r\n content: parsed.content ?? parsed.text ?? parsed.delta?.content ?? '',\r\n });\r\n } else if (eventType === 'patch') {\r\n controller.enqueue({ type: 'patch', patch: parsed });\r\n } else if (eventType === 'done') {\r\n controller.enqueue({ type: 'done', usage: parsed.usage });\r\n controller.close();\r\n return;\r\n } else if (eventType === 'error') {\r\n controller.enqueue({ type: 'error', message: parsed.message || 'Unknown error' });\r\n }\r\n } catch {\r\n // skip non-JSON lines\r\n }\r\n\r\n currentEvent = '';\r\n }\r\n }\r\n },\r\n cancel() {\r\n reader.cancel();\r\n },\r\n });\r\n}\r\n\r\nexport function createSSEAdapter(\r\n baseUrl: string,\r\n headers?: Record<string, string>,\r\n): AIServiceAdapter {\r\n let controller: AbortController | null = null;\r\n\r\n return {\r\n async request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>> {\r\n controller = new AbortController();\r\n\r\n const url = baseUrl.replace(/\\/+$/, '') + '/ai/completion';\r\n const resp = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream', ...headers },\r\n body: JSON.stringify(req),\r\n signal: controller.signal,\r\n });\r\n\r\n if (!resp.ok) {\r\n throw new Error(`AI service error: ${resp.status} ${resp.statusText}`);\r\n }\r\n\r\n if (!resp.body) {\r\n throw new Error('AI service returned no body');\r\n }\r\n\r\n return parseSSEStream(resp.body);\r\n },\r\n\r\n abort() {\r\n controller?.abort();\r\n controller = null;\r\n },\r\n };\r\n}\r\n\r\n// ── Chat Session API (REST + SSE) ──\r\n\r\nexport function createChatSessionAPI(\r\n baseUrl: string,\r\n headers?: Record<string, string>,\r\n): ChatSessionAPI {\r\n let controller: AbortController | null = null;\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n\r\n async function json<T>(url: string, init?: RequestInit): Promise<T> {\r\n const resp = await fetch(url, {\r\n ...init,\r\n headers: { 'Content-Type': 'application/json', ...headers, ...init?.headers },\r\n });\r\n if (!resp.ok) throw new Error(`Chat API error: ${resp.status} ${resp.statusText}`);\r\n const body = await resp.json();\r\n return body.data ?? body;\r\n }\r\n\r\n return {\r\n async createSession(patentId, title, language) {\r\n return json<ChatSession>(`${base}/api/v1/chat/sessions`, {\r\n method: 'POST',\r\n body: JSON.stringify({ patentId, title, language }),\r\n });\r\n },\r\n\r\n async listSessions(patentId, page = 1, pageSize = 20) {\r\n const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\r\n if (patentId) params.set('patentId', patentId);\r\n return json(`${base}/api/v1/chat/sessions?${params}`);\r\n },\r\n\r\n async getMessages(sessionId, page = 1, pageSize = 50) {\r\n const params = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });\r\n return json(`${base}/api/v1/chat/sessions/${sessionId}/messages?${params}`);\r\n },\r\n\r\n async deleteSession(sessionId) {\r\n await fetch(`${base}/api/v1/chat/sessions/${sessionId}`, {\r\n method: 'DELETE',\r\n headers: { ...headers },\r\n });\r\n },\r\n\r\n async sendMessage(sessionId, req) {\r\n return json<ChatMessageResponse>(`${base}/api/v1/chat/sessions/${sessionId}/messages`, {\r\n method: 'POST',\r\n body: JSON.stringify(req),\r\n });\r\n },\r\n\r\n async subscribeStream(sessionId, messageId) {\r\n controller = new AbortController();\r\n const url = `${base}/api/v1/chat/sessions/${sessionId}/stream?messageId=${messageId}`;\r\n const resp = await fetch(url, {\r\n headers: { Accept: 'text/event-stream', ...headers },\r\n signal: controller.signal,\r\n });\r\n if (!resp.ok) throw new Error(`Chat stream error: ${resp.status} ${resp.statusText}`);\r\n if (!resp.body) throw new Error('Chat stream returned no body');\r\n return parseSSEStream(resp.body);\r\n },\r\n\r\n abort() {\r\n controller?.abort();\r\n controller = null;\r\n },\r\n };\r\n}\r\n","import React, { forwardRef, useImperativeHandle, useRef, useCallback } from 'react';\r\nimport { JSONContent, Editor } from '@tiptap/react';\r\nimport { EditorView } from './components/EditorView';\r\nimport { useEditorStore, EditorLanguage } from './store/editorStore';\r\nimport { createCommandExecutor } from './editor/core/EditorCore';\r\nimport { createSSEAdapter, createChatSessionAPI } from './editor/ai/aiService';\r\nimport { buildPatentDocument } from './editor/plugins/patent/patentDocTemplate';\r\nimport type { PatentType } from './editor/plugins/patent/patentDocTemplate';\r\nimport type { AIServiceAdapter, ChatSessionAPI } from './editor/ai/aiService';\r\nimport './styles/editor.css';\r\n\r\nexport interface PatentEditorProps {\r\n initialContent?: JSONContent;\r\n patentType?: PatentType;\r\n onChange?: (content: JSONContent) => void;\r\n className?: string;\r\n readOnly?: boolean;\r\n /** Disable content editing without hiding toolbar/UI (unlike readOnly). */\r\n editable?: boolean;\r\n language?: EditorLanguage;\r\n aiService?: AIServiceAdapter;\r\n chatSessionAPI?: ChatSessionAPI;\r\n aiBaseUrl?: string;\r\n aiHeaders?: Record<string, string>;\r\n onSelectionOptimize?: (selection: {\r\n text: string;\r\n from: number;\r\n to: number;\r\n sectionType?: string;\r\n }) => void;\r\n}\r\n\r\nexport interface PatentEditorRef {\r\n getContent: () => JSONContent | null;\r\n setContent: (content: JSONContent) => void;\r\n getEditor: () => any;\r\n execCommand: (name: string, payload?: unknown) => Promise<unknown>;\r\n focus: () => void;\r\n}\r\n\r\nexport const PatentEditor = forwardRef<PatentEditorRef, PatentEditorProps>(\r\n ({ initialContent, patentType, onChange, className, readOnly = false, editable = true, language, aiService, chatSessionAPI, aiBaseUrl, aiHeaders, onSelectionOptimize }, ref) => {\r\n const { setEditorLanguage, setAIService, setChatSessionAPI } = useEditorStore();\r\n const localEditorRef = useRef<Editor | null>(null);\r\n\r\n const handleEditorReady = useCallback((editor: Editor) => {\r\n localEditorRef.current = editor;\r\n }, []);\r\n\r\n const resolvedContent = React.useMemo(() => {\r\n if (initialContent) return initialContent;\r\n if (patentType) return buildPatentDocument(patentType);\r\n return undefined;\r\n }, [initialContent, patentType]);\r\n\r\n React.useEffect(() => {\r\n if (language) setEditorLanguage(language);\r\n }, [language, setEditorLanguage]);\r\n\r\n React.useEffect(() => {\r\n if (aiService) {\r\n setAIService(aiService);\r\n } else if (aiBaseUrl) {\r\n setAIService(createSSEAdapter(aiBaseUrl, aiHeaders));\r\n }\r\n }, [aiService, aiBaseUrl, aiHeaders, setAIService]);\r\n\r\n React.useEffect(() => {\r\n if (chatSessionAPI) {\r\n setChatSessionAPI(chatSessionAPI);\r\n } else if (aiBaseUrl) {\r\n setChatSessionAPI(createChatSessionAPI(aiBaseUrl, aiHeaders));\r\n }\r\n }, [chatSessionAPI, aiBaseUrl, aiHeaders, setChatSessionAPI]);\r\n\r\n useImperativeHandle(ref, () => ({\r\n getContent: () => localEditorRef.current?.getJSON() ?? null,\r\n setContent: (content: JSONContent) => {\r\n localEditorRef.current?.commands.setContent(content);\r\n },\r\n getEditor: () => localEditorRef.current,\r\n execCommand: async (name: string, payload?: unknown) => {\r\n if (!localEditorRef.current) return null;\r\n const executor = createCommandExecutor(localEditorRef.current);\r\n return executor.execCommand(name, payload);\r\n },\r\n focus: () => { localEditorRef.current?.commands.focus(); },\r\n }));\r\n\r\n return (\r\n <EditorView\r\n initialContent={resolvedContent}\r\n onChange={onChange}\r\n onEditorReady={handleEditorReady}\r\n className={className}\r\n readOnly={readOnly}\r\n editable={editable}\r\n onSelectionOptimize={onSelectionOptimize}\r\n />\r\n );\r\n }\r\n);\r\n\r\nPatentEditor.displayName = 'PatentEditor';\r\n","import { Editor } from '@tiptap/react';\r\n\r\nexport type StreamWriteMode = 'cursor' | 'section';\r\n\r\nexport interface StreamWriterOptions {\r\n mode: StreamWriteMode;\r\n targetSectionPos?: number;\r\n onStart?: () => void;\r\n onChunk?: (text: string) => void;\r\n onComplete?: () => void;\r\n onError?: (error: Error) => void;\r\n onAbort?: () => void;\r\n}\r\n\r\nexport interface StreamWriterHandle {\r\n abort: () => void;\r\n isRunning: () => boolean;\r\n}\r\n\r\nexport function createStreamWriter(\r\n editor: Editor,\r\n options: StreamWriterOptions\r\n): StreamWriterHandle {\r\n let aborted = false;\r\n let running = false;\r\n\r\n return {\r\n abort: () => {\r\n aborted = true;\r\n if (running) {\r\n running = false;\r\n options.onAbort?.();\r\n }\r\n },\r\n isRunning: () => running,\r\n };\r\n}\r\n\r\nexport async function writeStream(\r\n editor: Editor,\r\n reader: ReadableStreamDefaultReader<string>,\r\n options: StreamWriterOptions\r\n): Promise<void> {\r\n let aborted = false;\r\n const abortController = { abort: () => { aborted = true; } };\r\n\r\n options.onStart?.();\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n clearSectionContent(editor, options.targetSectionPos);\r\n }\r\n\r\n try {\r\n let insertPos = getInsertPosition(editor, options);\r\n\r\n while (true) {\r\n if (aborted) {\r\n options.onAbort?.();\r\n return;\r\n }\r\n\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n if (!value) continue;\r\n\r\n options.onChunk?.(value);\r\n\r\n const tr = editor.state.tr.insertText(value, insertPos);\r\n editor.view.dispatch(tr);\r\n // 用 bias=1 将旧插入点映射到新文档中插入内容之后的位置\r\n // 这样无论 \\n 是否触发段落分割,position 都正确\r\n insertPos = tr.mapping.map(insertPos, 1);\r\n }\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n\r\n options.onComplete?.();\r\n } catch (err) {\r\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\r\n }\r\n}\r\n\r\nexport async function writeStreamFromSSE(\r\n editor: Editor,\r\n url: string,\r\n body: object,\r\n options: StreamWriterOptions\r\n): Promise<{ abort: () => void }> {\r\n const abortController = new AbortController();\r\n\r\n options.onStart?.();\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n clearSectionContent(editor, options.targetSectionPos);\r\n }\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(body),\r\n signal: abortController.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) throw new Error('No response body');\r\n\r\n const decoder = new TextDecoder();\r\n let insertPos = getInsertPosition(editor, options);\r\n let buffer = '';\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (!line.startsWith('data: ')) continue;\r\n const data = line.slice(6).trim();\r\n if (data === '[DONE]') {\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n options.onComplete?.();\r\n return { abort: () => abortController.abort() };\r\n }\r\n\r\n try {\r\n const parsed = JSON.parse(data);\r\n const text = parsed.content || parsed.text || parsed.delta?.content || '';\r\n if (!text) continue;\r\n\r\n options.onChunk?.(text);\r\n const ssetr = editor.state.tr.insertText(text, insertPos);\r\n editor.view.dispatch(ssetr);\r\n insertPos = ssetr.mapping.map(insertPos, 1);\r\n } catch {\r\n // skip non-JSON lines\r\n }\r\n }\r\n }\r\n\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n removeEmptyParagraphs(editor, options.targetSectionPos);\r\n }\r\n options.onComplete?.();\r\n } catch (err) {\r\n if ((err as Error).name === 'AbortError') {\r\n options.onAbort?.();\r\n } else {\r\n options.onError?.(err instanceof Error ? err : new Error(String(err)));\r\n }\r\n }\r\n\r\n return { abort: () => abortController.abort() };\r\n}\r\n\r\nfunction getInsertPosition(editor: Editor, options: StreamWriterOptions): number {\r\n if (options.mode === 'section' && typeof options.targetSectionPos === 'number') {\r\n const node = editor.state.doc.nodeAt(options.targetSectionPos);\r\n if (node && node.type.name === 'patent_section') {\r\n return options.targetSectionPos + 2;\r\n }\r\n }\r\n return editor.state.selection.from;\r\n}\r\n\r\nfunction clearSectionContent(editor: Editor, sectionPos: number): void {\r\n const node = editor.state.doc.nodeAt(sectionPos);\r\n if (!node || node.type.name !== 'patent_section') return;\r\n\r\n const contentStart = sectionPos + 1;\r\n const contentEnd = sectionPos + node.nodeSize - 1;\r\n\r\n if (contentEnd > contentStart + 2) {\r\n const tr = editor.state.tr;\r\n const paragraph = editor.state.schema.nodes.paragraph.create();\r\n tr.replaceWith(contentStart, contentEnd, paragraph);\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n }\r\n}\r\n\r\n/**\r\n * Remove empty paragraph nodes from a patent_section after streaming.\r\n * ProseMirror's insertText splits on every \\n, so \\n\\n produces empty paragraphs\r\n * that need to be cleaned up. Always keeps at least one paragraph in the section.\r\n */\r\nfunction removeEmptyParagraphs(editor: Editor, sectionPos: number): void {\r\n const node = editor.state.doc.nodeAt(sectionPos);\r\n if (!node || node.type.name !== 'patent_section') return;\r\n\r\n const tr = editor.state.tr;\r\n const toDelete: { from: number; to: number }[] = [];\r\n\r\n let offset = sectionPos + 1;\r\n let totalChildren = 0;\r\n node.forEach((child) => { totalChildren++; });\r\n\r\n let nonEmptyCount = 0;\r\n node.forEach((child) => {\r\n if (child.type.name === 'paragraph' && child.textContent.trim().length > 0) {\r\n nonEmptyCount++;\r\n }\r\n });\r\n\r\n offset = sectionPos + 1;\r\n node.forEach((child) => {\r\n const childStart = offset;\r\n const childEnd = offset + child.nodeSize;\r\n if (\r\n child.type.name === 'paragraph' &&\r\n child.textContent.trim().length === 0 &&\r\n (nonEmptyCount > 0 || toDelete.length < totalChildren - 1)\r\n ) {\r\n toDelete.push({ from: childStart, to: childEnd });\r\n }\r\n offset = childEnd;\r\n });\r\n\r\n if (toDelete.length === 0) return;\r\n\r\n for (let i = toDelete.length - 1; i >= 0; i--) {\r\n tr.delete(toDelete[i].from, toDelete[i].to);\r\n }\r\n tr.setMeta('addToHistory', false);\r\n editor.view.dispatch(tr);\r\n}\r\n","/**\r\n * Mock AI Service — 用于演示 AI 流式写入 和 Chat 会话(含 target 化 patch)\r\n *\r\n * 模块 1: AIServiceAdapter — generate action(流式章节生成)\r\n * 模块 2: ChatSessionAPI — 会话制对话(含 session CRUD + 两步式 SSE)\r\n */\r\n\r\nimport type {\r\n AIServiceAdapter, AIRequest, AIResponseEvent,\r\n ChatSessionAPI, ChatSession, ChatMessage,\r\n ChatMessageRequest, ChatMessageResponse, ChatReference,\r\n} from './aiService';\r\n\r\n/* ═══════════════════ 各章节 Mock 文本 ═══════════════════ */\r\n\r\nconst SECTION_TEXTS: Record<string, { zh: string; en: string }> = {\r\n technical_field: {\r\n zh: '本发明涉及航天器自主导航与控制技术领域,具体涉及一种基于多传感器融合的航天器自主避障控制方法、系统、电子设备及计算机可读存储介质。该方法综合利用激光雷达、红外传感器和星敏感器的探测数据,通过实时环境感知与路径规划算法,实现航天器在复杂空间环境中的自主安全避障机动。',\r\n en: 'The present invention relates to the field of autonomous navigation and control technology for spacecraft, and specifically to a method, system, electronic device, and computer-readable storage medium for autonomous obstacle avoidance control of spacecraft based on multi-sensor fusion.',\r\n },\r\n background_art: {\r\n zh: '随着人类空间活动日益频繁,近地轨道空间碎片数量持续增长,对在轨航天器的安全运行构成了严重威胁。传统的空间碎片避碰方法主要依赖地面监测站的跟踪数据和人工决策,存在响应时间长、决策链路复杂、无法应对突发碰撞风险等缺点。\\n\\n现有技术中,部分航天器采用预设轨道机动策略进行避碰,但该方法对碎片轨道预报精度要求极高,且无法适应非合作目标的不确定运动。也有研究提出基于人工势场法的避障方案,但存在局部最优陷阱问题,在密集碎片环境中表现不佳。\\n\\n因此,亟需一种能够实现航天器自主感知、自主决策、自主机动的避障控制方法,以提高航天器的在轨生存能力。',\r\n en: 'With the increasing frequency of human space activities, the number of space debris in low Earth orbit continues to grow, posing a serious threat to the safe operation of on-orbit spacecraft. Traditional space debris collision avoidance methods mainly rely on tracking data from ground monitoring stations and manual decision-making.',\r\n },\r\n summary: {\r\n zh: '为解决上述技术问题,本发明提供了一种航天器自主避障控制方法,包括以下步骤:\\n\\n步骤一:通过多传感器融合模块实时获取航天器周围空间环境信息,构建三维障碍物地图;\\n\\n步骤二:基于改进的快速搜索随机树(RRT*)算法进行全局路径规划,生成无碰撞参考轨迹;\\n\\n步骤三:采用模型预测控制(MPC)策略进行局部路径跟踪与实时避障,在满足燃料约束和姿态约束的条件下,计算最优推力控制量;\\n\\n步骤四:通过安全验证模块对控制指令进行合规性检查,确保机动轨迹不会与已知空间目标产生二次碰撞风险。\\n\\n本发明的有益效果在于:显著缩短碰撞告警到规避机动的响应时间,从传统方法的数小时级缩短至分钟级;提高避障成功率至99.7%以上;降低单次避障机动的燃料消耗约35%。',\r\n en: 'To solve the above technical problems, the present invention provides a method for autonomous obstacle avoidance control of spacecraft, comprising the following steps...',\r\n },\r\n claims: {\r\n zh: '1. 一种航天器自主避障控制方法,其特征在于,包括以下步骤:\\n通过多传感器融合模块实时获取航天器周围空间环境信息,构建三维障碍物分布地图;\\n基于改进的快速搜索随机树算法进行全局路径规划,生成无碰撞参考轨迹;\\n采用模型预测控制策略进行局部路径跟踪与实时避障控制。\\n\\n2. 根据权利要求1所述的方法,其特征在于,所述多传感器融合模块包括激光雷达传感器、红外传感器和星敏感器,采用扩展卡尔曼滤波算法对多源传感器数据进行融合处理。\\n\\n3. 根据权利要求1所述的方法,其特征在于,所述改进的快速搜索随机树算法引入了自适应采样策略和路径平滑优化机制。',\r\n en: '1. A method for autonomous obstacle avoidance control of a spacecraft, characterized in that it comprises the following steps...',\r\n },\r\n abstract: {\r\n zh: '本发明公开了一种航天器自主避障控制方法、系统、电子设备及存储介质。该方法通过多传感器融合模块实时感知空间环境,基于改进RRT*算法规划全局无碰撞路径,采用MPC策略实现局部实时避障控制。本发明显著缩短了碰撞告警响应时间,提高了避障成功率,降低了燃料消耗。',\r\n en: 'The present invention discloses a method, system, electronic device and storage medium for autonomous obstacle avoidance control of a spacecraft.',\r\n },\r\n drawing_description: {\r\n zh: '图1为本发明实施例提供的航天器自主避障控制方法的流程示意图;\\n\\n图2为本发明实施例提供的多传感器融合模块的结构框图;\\n\\n图3为本发明实施例提供的改进RRT*算法的路径规划效果示意图;\\n\\n图4为本发明实施例提供的模型预测控制策略的控制框图;\\n\\n图5为本发明实施例提供的航天器自主避障控制系统的架构示意图。',\r\n en: 'FIG. 1 is a schematic flow chart of the autonomous obstacle avoidance control method for a spacecraft provided by an embodiment of the present invention.',\r\n },\r\n detailed_description: {\r\n zh: '下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述。\\n\\n实施例一:\\n\\n如图1所示,本发明提供的航天器自主避障控制方法包括以下步骤:\\n\\nS101:多传感器数据采集与融合。航天器搭载的激光雷达以10Hz频率扫描前方120°锥形区域,红外传感器以5Hz频率探测周围热辐射目标,星敏感器以1Hz频率提供高精度姿态信息。采用扩展卡尔曼滤波(EKF)算法对上述多源数据进行时间同步和空间配准,生成统一坐标系下的三维障碍物分布地图。\\n\\nS102:全局路径规划。基于步骤S101获得的障碍物地图,采用改进的RRT*算法进行路径规划。改进之处在于:引入目标导向采样策略,以概率p=0.3直接向目标点采样,加速收敛;引入路径平滑机制,对生成路径进行B样条曲线拟合,确保路径连续可微。\\n\\nS103:局部实时避障控制。采用模型预测控制(MPC)策略,以步骤S102的规划路径为参考,在预测时域N=20内求解带约束的最优控制问题。约束条件包括:推力幅值约束|F|≤Fmax、姿态角速度约束|ω|≤ωmax、最小安全距离约束d≥dmin。\\n\\nS104:安全验证。对计算得到的控制指令进行轨迹传播仿真,验证机动后轨迹在未来72小时内不会与TLE目录中的已知空间目标产生碰撞风险(miss distance > 1km)。',\r\n en: 'The technical solution of the embodiments of the present invention will be described clearly and completely below with reference to the drawings.',\r\n },\r\n};\r\n\r\n/* ═══════════════════ Chat Mock 回复 ═══════════════════ */\r\n\r\nconst CHAT_RESPONSES: Record<string, { zh: string; en: string }> = {\r\n 'help-draft': {\r\n zh: '当然可以帮你撰写技术方案!请先描述以下信息:\\n\\n1. **技术领域**:你的发明属于哪个技术领域?\\n2. **技术问题**:现有技术存在什么缺陷或不足?\\n3. **核心创新**:你的发明的关键创新点是什么?\\n4. **实施方式**:大致的技术实现路径是怎样的?\\n\\n提供这些信息后,我可以帮你生成完整的技术方案初稿。',\r\n en: 'Sure, I can help draft the technical solution! Please describe the following...',\r\n },\r\n review: {\r\n zh: '好的,我将对当前专利文档进行全面审查,主要检查以下方面:\\n\\n**格式规范性**\\n- 各章节是否完整\\n- 权利要求书格式是否符合要求\\n- 摘要字数是否在50-300字范围\\n\\n**内容质量**\\n- 技术方案是否清楚完整\\n- 权利要求保护范围是否合理\\n- 说明书是否充分公开\\n\\n**一致性检查**\\n- 术语使用是否统一\\n- 附图标记是否一致\\n- 权利要求与说明书是否对应\\n\\n请稍候,我正在分析文档内容...',\r\n en: 'I will review the current patent document comprehensively...',\r\n },\r\n claims: {\r\n zh: '针对当前权利要求书,我有以下优化建议:\\n\\n1. **独立权利要求1** 中的技术特征可以进一步上位化,扩大保护范围。建议将\"激光雷达\"上位为\"距离探测传感器\"\\n\\n2. **从属权利要求** 数量偏少,建议补充:\\n - 传感器融合算法的具体实现方式\\n - 路径规划的采样策略参数范围\\n - MPC控制器的预测时域和约束条件\\n\\n3. 建议增加 **方法+系统** 双重保护的权利要求布局\\n\\n需要我帮你自动生成优化后的权利要求书吗?',\r\n en: 'For the current claims, I have the following optimization suggestions...',\r\n },\r\n default: {\r\n zh: '这是一个很好的问题。作为AI专利撰写助手,我可以帮助你:\\n\\n- **生成章节草稿**:基于已有内容和你的描述,自动撰写各章节\\n- **优化表达**:使文本更符合专利撰写规范\\n- **审查文档**:检查格式规范性和内容完整性\\n- **权利要求优化**:调整保护范围和层次布局\\n\\n你可以选中文档中的文字使用浮动菜单的AI操作,或者在左侧面板点击章节的\"AI生成\"按钮来体验这些功能。',\r\n en: 'That is a great question. As an AI patent writing assistant, I can help you with...',\r\n },\r\n};\r\n\r\n/* ═══════════════════ Helper: 延迟 ═══════════════════ */\r\n\r\nconst delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\r\n\r\n/* ═══════════════════ 创建 Mock 流 ═══════════════════ */\r\n\r\nfunction createMockStream(events: AIResponseEvent[], chunkDelayMs = 30): ReadableStream<AIResponseEvent> {\r\n let cancelled = false;\r\n return new ReadableStream<AIResponseEvent>({\r\n async pull(controller) {\r\n for (const evt of events) {\r\n if (cancelled) {\r\n controller.close();\r\n return;\r\n }\r\n controller.enqueue(evt);\r\n if (evt.type === 'delta') {\r\n await delay(chunkDelayMs);\r\n }\r\n }\r\n controller.close();\r\n },\r\n cancel() {\r\n cancelled = true;\r\n },\r\n });\r\n}\r\n\r\n/* ═══════════════════ 场景 1: 流式写入 ═══════════════════ */\r\n\r\nfunction buildStreamingEvents(text: string): AIResponseEvent[] {\r\n const events: AIResponseEvent[] = [];\r\n // 按字符逐个发送(中文按字,英文按词+空格分组提高效率)\r\n const chunks = splitTextIntoChunks(text, 3);\r\n for (const chunk of chunks) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n events.push({ type: 'done', usage: { tokens: text.length * 2 } });\r\n return events;\r\n}\r\n\r\nfunction splitTextIntoChunks(text: string, chunkSize: number): string[] {\r\n const chunks: string[] = [];\r\n for (let i = 0; i < text.length; i += chunkSize) {\r\n chunks.push(text.slice(i, i + chunkSize));\r\n }\r\n return chunks;\r\n}\r\n\r\n/* ═══════════════════ Chat 回复构建(含 target 化 patch) ═══════════════════ */\r\n\r\nfunction buildChatStreamEvents(\r\n userContent: string,\r\n refs: ChatReference[],\r\n language: string,\r\n): AIResponseEvent[] {\r\n const zh = language === 'zh';\r\n const events: AIResponseEvent[] = [];\r\n\r\n // 匹配预设回复\r\n let responseText: string;\r\n if (userContent.includes('技术方案') || userContent.includes('draft')) {\r\n responseText = CHAT_RESPONSES['help-draft'][zh ? 'zh' : 'en'];\r\n } else if (userContent.includes('审查') || userContent.includes('review') || userContent.includes('Review')) {\r\n responseText = CHAT_RESPONSES['review'][zh ? 'zh' : 'en'];\r\n } else if (userContent.includes('权利要求') || userContent.includes('claims') || userContent.includes('Optimize')) {\r\n responseText = CHAT_RESPONSES['claims'][zh ? 'zh' : 'en'];\r\n } else {\r\n responseText = CHAT_RESPONSES['default'][zh ? 'zh' : 'en'];\r\n }\r\n\r\n // 如果有引用,返回 target 化 patch\r\n if (refs.length > 0) {\r\n // 先返回分析文字\r\n const analysis = zh\r\n ? `正在分析引用的 ${refs.length} 段文本并生成优化建议...\\n\\n`\r\n : `Analyzing ${refs.length} referenced text(s) and generating suggestions...\\n\\n`;\r\n for (const chunk of splitTextIntoChunks(analysis, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n for (const chunk of splitTextIntoChunks(responseText, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n\r\n // 为每个引用生成一个 target 化的 patch\r\n for (let i = 0; i < refs.length; i++) {\r\n const ref = refs[i];\r\n const original = ref.text;\r\n let optimized: string;\r\n if (zh) {\r\n optimized = original\r\n .replace(/一种/g, '一种基于本发明的')\r\n .replace(/方法/g, '技术方案')\r\n .replace(/包括/g, '具体包括');\r\n if (optimized === original) {\r\n optimized = `根据本发明优选实施例,${original}`;\r\n }\r\n } else {\r\n optimized = `According to a preferred embodiment, ${original.charAt(0).toLowerCase()}${original.slice(1)}`;\r\n }\r\n\r\n // 优先使用 ref target(精确 from/to),避免 search 匹配歧义\r\n // 仅当 ref 没有位置信息时才降级为 section+search(使用完整原文)\r\n if (ref.from != null && ref.to != null) {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'ref', refIndex: i },\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n } else if (ref.source) {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'section', sectionType: ref.source as any },\r\n search: original,\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n } else {\r\n events.push({\r\n type: 'patch',\r\n patch: {\r\n op: 'replace',\r\n target: { type: 'search', searchText: original },\r\n content: optimized,\r\n reason: zh ? '优化为更专业的专利表述' : 'Optimized for professional patent language',\r\n },\r\n });\r\n }\r\n }\r\n } else {\r\n // 纯文字对话回复\r\n for (const chunk of splitTextIntoChunks(responseText, 4)) {\r\n events.push({ type: 'delta', content: chunk });\r\n }\r\n }\r\n\r\n events.push({ type: 'done', usage: { tokens: responseText.length * 2 } });\r\n return events;\r\n}\r\n\r\n/* ═══════════════════ Mock AI Adapter (generate only) ═══════════════════ */\r\n\r\nexport function createMockAIService(): AIServiceAdapter {\r\n let abortController: AbortController | null = null;\r\n\r\n return {\r\n async request(req: AIRequest): Promise<ReadableStream<AIResponseEvent>> {\r\n abortController = new AbortController();\r\n\r\n // 模拟网络延迟\r\n await delay(300);\r\n\r\n if (abortController.signal.aborted) {\r\n throw new DOMException('Aborted', 'AbortError');\r\n }\r\n\r\n const lang = req.language === 'zh' ? 'zh' : 'en';\r\n const sectionKey = req.sectionType || 'technical_field';\r\n const sectionText = SECTION_TEXTS[sectionKey]?.[lang]\r\n || SECTION_TEXTS['technical_field'][lang];\r\n\r\n let fullText = sectionText;\r\n if (req.instruction) {\r\n const prefix = lang === 'zh'\r\n ? `[基于指令\"${req.instruction}\"生成]\\n\\n`\r\n : `[Generated based on instruction \"${req.instruction}\"]\\n\\n`;\r\n fullText = prefix + sectionText;\r\n }\r\n\r\n const events = buildStreamingEvents(fullText);\r\n return createMockStream(events, 25);\r\n },\r\n\r\n abort() {\r\n abortController?.abort();\r\n abortController = null;\r\n },\r\n };\r\n}\r\n\r\n/* ═══════════════════ Mock Chat Session API ═══════════════════ */\r\n\r\ninterface MockSession {\r\n session: ChatSession;\r\n messages: ChatMessage[];\r\n}\r\n\r\nexport function createMockChatSessionAPI(): ChatSessionAPI {\r\n const sessions = new Map<string, MockSession>();\r\n let abortController: AbortController | null = null;\r\n // pending stream for the latest message\r\n let pendingStream: { messageId: string; events: AIResponseEvent[] } | null = null;\r\n\r\n return {\r\n async createSession(patentId, title, language) {\r\n await delay(100);\r\n const sessionId = `sess_${Date.now()}`;\r\n const session: ChatSession = {\r\n sessionId,\r\n patentId: patentId || undefined,\r\n title: title || (language === 'zh' ? '新对话' : 'New Chat'),\r\n messageCount: 0,\r\n createdAt: new Date().toISOString(),\r\n updatedAt: new Date().toISOString(),\r\n };\r\n sessions.set(sessionId, { session, messages: [] });\r\n return session;\r\n },\r\n\r\n async listSessions() {\r\n await delay(50);\r\n const items = Array.from(sessions.values()).map((s) => s.session);\r\n return { total: items.length, items };\r\n },\r\n\r\n async getMessages(sessionId) {\r\n await delay(50);\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n return { total: s.messages.length, items: s.messages };\r\n },\r\n\r\n async deleteSession(sessionId) {\r\n await delay(50);\r\n sessions.delete(sessionId);\r\n },\r\n\r\n async sendMessage(sessionId, req: ChatMessageRequest): Promise<ChatMessageResponse> {\r\n await delay(150);\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n\r\n const messageId = `msg_${Date.now()}`;\r\n\r\n // Store user message\r\n s.messages.push({\r\n messageId,\r\n role: 'user',\r\n content: req.content,\r\n references: req.references,\r\n status: 'done',\r\n createdAt: new Date().toISOString(),\r\n });\r\n s.session.messageCount = s.messages.length;\r\n s.session.lastMessage = req.content;\r\n s.session.updatedAt = new Date().toISOString();\r\n\r\n // Build events for the response stream\r\n const events = buildChatStreamEvents(\r\n req.content,\r\n req.references || [],\r\n req.language,\r\n );\r\n pendingStream = { messageId, events };\r\n\r\n return { messageId, sessionId, status: 'processing' };\r\n },\r\n\r\n async subscribeStream(sessionId, messageId) {\r\n abortController = new AbortController();\r\n await delay(100);\r\n\r\n const s = sessions.get(sessionId);\r\n if (!s) throw new Error('Session not found');\r\n\r\n if (!pendingStream || pendingStream.messageId !== messageId) {\r\n // Already completed or not found — return done\r\n return createMockStream([{ type: 'done' }]);\r\n }\r\n\r\n const events = pendingStream.events;\r\n pendingStream = null;\r\n\r\n // After stream, store the assistant message\r\n const stream = createMockStream(events, 18);\r\n\r\n // Collect assistant content for storage (fire-and-forget)\r\n const asstId = `${messageId}_a`;\r\n let content = '';\r\n for (const evt of events) {\r\n if (evt.type === 'delta') content += evt.content;\r\n }\r\n s.messages.push({\r\n messageId: asstId,\r\n role: 'assistant',\r\n content,\r\n status: 'done',\r\n createdAt: new Date().toISOString(),\r\n });\r\n s.session.messageCount = s.messages.length;\r\n s.session.updatedAt = new Date().toISOString();\r\n\r\n return stream;\r\n },\r\n\r\n abort() {\r\n abortController?.abort();\r\n abortController = null;\r\n },\r\n };\r\n}\r\n","/**\r\n * Utilities for parsing claims text and building TipTap paragraph content.\r\n *\r\n * Claims are represented as standard paragraph nodes whose text starts\r\n * with \"N. \" (e.g. \"1. 一种方法,其特征在于...\").\r\n */\r\n\r\ninterface ParsedClaim {\r\n number: number;\r\n text: string;\r\n dependsOn: number[];\r\n}\r\n\r\n/**\r\n * Parse plain text into individual claims.\r\n * Splits by the pattern \"N. \" or \"N、\" at the start of a line.\r\n */\r\nexport function parseClaimsText(text: string): ParsedClaim[] {\r\n const claims: ParsedClaim[] = [];\r\n\r\n const normalized = text.replace(/\\r\\n/g, '\\n').trim();\r\n if (!normalized) return claims;\r\n\r\n const claimPattern = /(?:^|\\n)\\s*(\\d+)\\s*[.、]\\s*/g;\r\n const matches: { index: number; number: number; matchLength: number }[] = [];\r\n\r\n let match: RegExpExecArray | null;\r\n while ((match = claimPattern.exec(normalized)) !== null) {\r\n matches.push({\r\n index: match.index,\r\n number: parseInt(match[1], 10),\r\n matchLength: match[0].length,\r\n });\r\n }\r\n\r\n if (matches.length === 0) {\r\n claims.push({ number: 1, text: normalized, dependsOn: [] });\r\n return claims;\r\n }\r\n\r\n for (let i = 0; i < matches.length; i++) {\r\n const start = matches[i].index + matches[i].matchLength;\r\n const end = i + 1 < matches.length ? matches[i + 1].index : normalized.length;\r\n const claimText = normalized.slice(start, end).trim();\r\n const claimNumber = matches[i].number;\r\n const dependsOn = extractDependencies(claimText, claimNumber);\r\n claims.push({ number: claimNumber, text: claimText, dependsOn });\r\n }\r\n\r\n return claims;\r\n}\r\n\r\nfunction extractDependencies(text: string, selfNumber: number): number[] {\r\n const deps: number[] = [];\r\n\r\n const zhPattern = /根据权利要求(\\d+)(?:\\s*[-~至到]\\s*(\\d+))?/g;\r\n let m: RegExpExecArray | null;\r\n while ((m = zhPattern.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n const enPattern = /claims?\\s+(\\d+)(?:\\s*[-~to]+\\s*(\\d+))?/gi;\r\n while ((m = enPattern.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n return [...new Set(deps)].sort((a, b) => a - b);\r\n}\r\n\r\n/**\r\n * Build structured JSONContent paragraphs for claims from text.\r\n * Each claim becomes a standard paragraph: \"N. claim body text\".\r\n */\r\nexport function buildClaimsJSONContent(text: string): Array<{\r\n type: string;\r\n content?: Array<{ type: string; text: string }>;\r\n}> {\r\n const parsedClaims = parseClaimsText(text);\r\n return parsedClaims.map((parsed) => ({\r\n type: 'paragraph',\r\n content: parsed.text\r\n ? [{ type: 'text', text: `${parsed.number}. ${parsed.text}` }]\r\n : [{ type: 'text', text: `${parsed.number}. ` }],\r\n }));\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\nimport { diff_match_patch } from 'diff-match-patch';\r\nimport { buildTextMap, textOffsetToDocPos } from './patchDiff';\r\n\r\nconst DIFF_DELETE = -1;\r\nconst DIFF_INSERT = 1;\r\nconst DIFF_EQUAL = 0;\r\n\r\nconst DocDiffPluginKey = new PluginKey('docDiff');\r\n\r\nlet _dmp: InstanceType<typeof diff_match_patch> | null = null;\r\nfunction getDmp() {\r\n if (!_dmp) _dmp = new diff_match_patch();\r\n return _dmp;\r\n}\r\n\r\n/**\r\n * Split an inline range into per-textblock sub-ranges so that\r\n * Decoration.inline never crosses block boundaries.\r\n */\r\nfunction getInlineRanges(\r\n doc: import('@tiptap/pm/model').Node,\r\n from: number,\r\n to: number,\r\n): Array<{ from: number; to: number }> {\r\n const ranges: Array<{ from: number; to: number }> = [];\r\n doc.nodesBetween(from, to, (node, pos) => {\r\n if (node.isTextblock) {\r\n const blockStart = pos + 1;\r\n const blockEnd = pos + node.nodeSize - 1;\r\n const rangeFrom = Math.max(blockStart, from);\r\n const rangeTo = Math.min(blockEnd, to);\r\n if (rangeTo > rangeFrom) {\r\n ranges.push({ from: rangeFrom, to: rangeTo });\r\n }\r\n return false;\r\n }\r\n return true;\r\n });\r\n return ranges;\r\n}\r\n\r\n/**\r\n * Apply document-level diff decorations to a read-only editor.\r\n *\r\n * @param editor - The TipTap editor instance (should be loaded with the \"current\" document)\r\n * @param originalText - Plain text of the original document, extracted using the same\r\n * separator rules as ProseMirror's textBetween (\\0 separators).\r\n */\r\nexport function applyDocDiffDecorations(editor: Editor, originalText: string): void {\r\n const doc = editor.state.doc;\r\n const docSize = doc.content.size;\r\n const { text: currentText, segments } = buildTextMap(editor, 0, docSize);\r\n\r\n const dmp = getDmp();\r\n const diffs = dmp.diff_main(originalText, currentText);\r\n dmp.diff_cleanupEfficiency(diffs);\r\n\r\n const decorations: Decoration[] = [];\r\n let curOffset = 0;\r\n\r\n for (const [op, text] of diffs) {\r\n if (op === DIFF_EQUAL) {\r\n curOffset += text.length;\r\n } else if (op === DIFF_INSERT) {\r\n let i = 0;\r\n while (i < text.length) {\r\n while (i < text.length && text[i] === '\\0') i++;\r\n if (i >= text.length) break;\r\n const runStart = i;\r\n while (i < text.length && text[i] !== '\\0') i++;\r\n\r\n const from = textOffsetToDocPos(segments, curOffset + runStart);\r\n const to = textOffsetToDocPos(segments, curOffset + i);\r\n if (from >= 0 && to >= 0 && to > from) {\r\n for (const range of getInlineRanges(doc, from, to)) {\r\n decorations.push(\r\n Decoration.inline(range.from, range.to, { class: 'patch-diff-insert-inline' }),\r\n );\r\n }\r\n }\r\n }\r\n curOffset += text.length;\r\n } else if (op === DIFF_DELETE) {\r\n const pos = textOffsetToDocPos(segments, curOffset);\r\n if (pos >= 0) {\r\n const display = text.replace(/\\0/g, ' ');\r\n decorations.push(\r\n Decoration.widget(\r\n pos,\r\n () => {\r\n const el = document.createElement('span');\r\n el.className = 'patch-diff-delete';\r\n el.textContent = display;\r\n return el;\r\n },\r\n { side: -1 },\r\n ),\r\n );\r\n }\r\n }\r\n }\r\n\r\n const decoSet = DecorationSet.create(doc, decorations);\r\n const plugin = new Plugin({\r\n key: DocDiffPluginKey,\r\n props: {\r\n decorations() {\r\n return decoSet;\r\n },\r\n },\r\n });\r\n\r\n editor.registerPlugin(plugin);\r\n}\r\n\r\n/**\r\n * Remove the doc-diff decoration plugin from the editor.\r\n */\r\nexport function removeDocDiffDecorations(editor: Editor): void {\r\n editor.unregisterPlugin(DocDiffPluginKey);\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport {\r\n Document,\r\n Packer,\r\n Paragraph,\r\n TextRun,\r\n AlignmentType,\r\n convertMillimetersToTwip,\r\n ISectionOptions,\r\n} from 'docx';\r\nimport { saveAs } from 'file-saver';\r\nimport { getEditorText } from '../../lib/editorI18n';\r\nimport type { EditorLanguage } from '../../store/editorStore';\r\n\r\n/** Sections that are top-level \"books\" */\r\nconst BOOK_SECTIONS = new Set([\r\n 'abstract', 'abstract_drawing', 'claims', 'drawing_figures',\r\n]);\r\n\r\n/** Sub-sections under 说明书 */\r\nconst DESCRIPTION_SUBS = new Set([\r\n 'technical_field', 'background_art', 'summary', 'drawing_description', 'detailed_description',\r\n]);\r\n\r\ninterface DocNode {\r\n type: 'patent_title' | 'patent_section';\r\n sectionType: string;\r\n title: string;\r\n paragraphs: string[];\r\n}\r\n\r\nfunction extractDocNodes(editor: Editor, language: EditorLanguage): DocNode[] {\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const nodes: DocNode[] = [];\r\n\r\n editor.state.doc.descendants((node) => {\r\n if (node.type.name === 'patent_title') {\r\n const text = node.textContent.trim();\r\n nodes.push({\r\n type: 'patent_title',\r\n sectionType: 'patent_title',\r\n title: '',\r\n paragraphs: text ? [text] : [],\r\n });\r\n return false;\r\n }\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const titleKey = `sectionTitle_${sectionType}`;\r\n const title = (typeof i18n[titleKey] === 'string' ? i18n[titleKey] : sectionType) as string;\r\n const paragraphs: string[] = [];\r\n\r\n node.forEach((child) => {\r\n const text = child.textContent.trim();\r\n if (text) paragraphs.push(text);\r\n });\r\n\r\n nodes.push({ type: 'patent_section', sectionType, title, paragraphs });\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n return nodes;\r\n}\r\n\r\n/** Book-level heading: centered, 三号黑体 (16pt = size 32 half-points) */\r\nfunction bookHeading(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 32, font: '黑体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 400, after: 200 },\r\n });\r\n}\r\n\r\n/** Sub-section heading: centered, 四号黑体 (14pt = size 28 half-points) */\r\nfunction subSectionHeading(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 28, font: '黑体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 240, after: 120 },\r\n });\r\n}\r\n\r\n/** Patent title: centered, 二号宋体 bold (18pt = size 36 half-points) */\r\nfunction patentTitleParagraph(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, bold: true, size: 36, font: '宋体' })],\r\n alignment: AlignmentType.CENTER,\r\n spacing: { before: 200, after: 200 },\r\n });\r\n}\r\n\r\n/** Body paragraph: 宋体 小四 (12pt = size 24), first-line indent ~2字符 */\r\nfunction bodyParagraph(text: string): Paragraph {\r\n return new Paragraph({\r\n children: [new TextRun({ text, size: 24, font: '宋体' })],\r\n spacing: { line: 360 },\r\n indent: { firstLine: convertMillimetersToTwip(7) },\r\n });\r\n}\r\n\r\nfunction buildDocxParagraphs(nodes: DocNode[], language: EditorLanguage): Paragraph[] {\r\n const i18n = getEditorText(language) as Record<string, unknown>;\r\n const paragraphs: Paragraph[] = [];\r\n let descriptionBookInserted = false;\r\n\r\n for (const node of nodes) {\r\n // Book-level sections: add book heading + content\r\n if (BOOK_SECTIONS.has(node.sectionType)) {\r\n paragraphs.push(bookHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Patent title: insert \"说明书\" book heading first, then title\r\n if (node.type === 'patent_title') {\r\n if (!descriptionBookInserted) {\r\n const bookLabel = (typeof i18n['bookTitle_description'] === 'string'\r\n ? i18n['bookTitle_description'] : '说明书') as string;\r\n paragraphs.push(bookHeading(bookLabel));\r\n descriptionBookInserted = true;\r\n }\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(patentTitleParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Description sub-sections: sub-heading + content\r\n if (DESCRIPTION_SUBS.has(node.sectionType)) {\r\n paragraphs.push(subSectionHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n continue;\r\n }\r\n\r\n // Fallback: treat as section heading + content\r\n paragraphs.push(subSectionHeading(node.title));\r\n for (const text of node.paragraphs) {\r\n paragraphs.push(bodyParagraph(text));\r\n }\r\n }\r\n\r\n return paragraphs;\r\n}\r\n\r\nexport async function exportToWord(editor: Editor, language: EditorLanguage): Promise<void> {\r\n const nodes = extractDocNodes(editor, language);\r\n const paragraphs = buildDocxParagraphs(nodes, language);\r\n\r\n const patentTitle = nodes.find(n => n.type === 'patent_title');\r\n const fileName = patentTitle?.paragraphs[0]\r\n ? `${patentTitle.paragraphs[0]}.docx`\r\n : 'patent-document.docx';\r\n\r\n const sectionOptions: ISectionOptions = {\r\n properties: {\r\n page: {\r\n margin: {\r\n top: convertMillimetersToTwip(25),\r\n bottom: convertMillimetersToTwip(25),\r\n left: convertMillimetersToTwip(25),\r\n right: convertMillimetersToTwip(20),\r\n },\r\n },\r\n },\r\n children: paragraphs,\r\n };\r\n\r\n const doc = new Document({\r\n sections: [sectionOptions],\r\n });\r\n\r\n const blob = await Packer.toBlob(doc);\r\n saveAs(blob, fileName);\r\n}\r\n\r\nexport async function exportToPdf(editor: Editor): Promise<void> {\r\n window.print();\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport type { EditorLanguage } from '../../../store/editorStore';\r\n\r\nexport type ValidationSeverity = 'error' | 'warning' | 'suggestion';\r\n\r\nexport interface ValidationIssue {\r\n id: string;\r\n severity: ValidationSeverity;\r\n message: string;\r\n sectionType?: string;\r\n pos?: number;\r\n}\r\n\r\nexport function validatePatentDocument(editor: Editor, language: EditorLanguage): ValidationIssue[] {\r\n const issues: ValidationIssue[] = [];\r\n const zh = language === 'zh';\r\n let issueIdx = 0;\r\n const nextId = () => `v_${++issueIdx}`;\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_title') {\r\n const text = node.textContent.trim();\r\n if (text.length === 0) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? '专利名称为空' : 'Patent title is empty',\r\n sectionType: 'patent_title',\r\n pos,\r\n });\r\n } else {\r\n const charCount = text.replace(/\\s/g, '').length;\r\n if (charCount > 25 && zh) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'error',\r\n message: `专利名称超过25个汉字(当前${charCount}字)`,\r\n sectionType: 'patent_title',\r\n pos,\r\n });\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n if (node.type.name === 'patent_section') {\r\n const sectionType = node.attrs.sectionType as string;\r\n const text = node.textContent.trim();\r\n\r\n if (text.length === 0) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh\r\n ? `章节\"${sectionType}\"内容为空`\r\n : `Section \"${sectionType}\" is empty`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n\r\n if (sectionType === 'abstract') {\r\n const charCount = text.replace(/\\s/g, '').length;\r\n if (charCount > 0 && charCount < 50) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? `摘要字数过少(${charCount}字),建议50~300字` : `Abstract too short (${charCount} chars), recommend 50-300`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n if (charCount > 300) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh ? `摘要字数过多(${charCount}字),建议不超过300字` : `Abstract too long (${charCount} chars), recommend ≤300`,\r\n sectionType,\r\n pos,\r\n });\r\n }\r\n }\r\n\r\n if (sectionType === 'claims') {\r\n const claimPattern = /^(\\d+)\\s*[.、]/;\r\n node.forEach((child, offset) => {\r\n if (child.type.name !== 'paragraph') return;\r\n const childText = child.textContent.trim();\r\n const match = claimPattern.exec(childText);\r\n if (!match) return;\r\n const claimNumber = match[1];\r\n if (childText.length > 0 && !childText.endsWith('。') && !childText.endsWith('.')) {\r\n issues.push({\r\n id: nextId(),\r\n severity: 'warning',\r\n message: zh\r\n ? `权利要求${claimNumber}末尾应以句号结束`\r\n : `Claim ${claimNumber} should end with a period`,\r\n pos: pos + 1 + offset,\r\n });\r\n }\r\n });\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return true;\r\n });\r\n\r\n return issues;\r\n}\r\n","import { Editor } from '@tiptap/react';\r\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model';\r\n\r\nexport interface ClaimSnapshot {\r\n claimId: string;\r\n number: number;\r\n dependsOn: number[];\r\n dependsOnClaimIds: string[];\r\n body: string;\r\n pos: number;\r\n}\r\n\r\nconst CLAIM_NUMBER_PATTERN = /^(\\d+)\\s*[.、]\\s*/;\r\n\r\nconst DEPENDENCY_PATTERN_ZH = /根据权利要求(\\d+)(?:\\s*[-~至到]\\s*(\\d+))?/g;\r\nconst DEPENDENCY_PATTERN_EN = /claims?\\s+(\\d+)(?:\\s*[-~to]+\\s*(\\d+))?/gi;\r\n\r\nfunction extractDependencies(text: string, selfNumber: number): number[] {\r\n const deps: number[] = [];\r\n let m: RegExpExecArray | null;\r\n\r\n DEPENDENCY_PATTERN_ZH.lastIndex = 0;\r\n while ((m = DEPENDENCY_PATTERN_ZH.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n DEPENDENCY_PATTERN_EN.lastIndex = 0;\r\n while ((m = DEPENDENCY_PATTERN_EN.exec(text)) !== null) {\r\n const start = parseInt(m[1], 10);\r\n const end = m[2] ? parseInt(m[2], 10) : start;\r\n for (let n = start; n <= end; n++) {\r\n if (n !== selfNumber && n > 0) deps.push(n);\r\n }\r\n }\r\n\r\n return [...new Set(deps)].sort((a, b) => a - b);\r\n}\r\n\r\nexport const serializeClaimBodyText = (node: ProseMirrorNode): string => {\r\n if (node.type.name === 'reference') {\r\n return buildReferenceInlineText(node);\r\n }\r\n if (node.type.name === 'hardBreak') {\r\n return '\\n';\r\n }\r\n if (node.isText) {\r\n return node.text || '';\r\n }\r\n let text = '';\r\n node.forEach((child) => {\r\n text += serializeClaimBodyText(child);\r\n });\r\n return text;\r\n};\r\n\r\nexport const buildReferenceInlineText = (node: ProseMirrorNode) => {\r\n const language = node.attrs.lang === 'en' ? 'en' : 'zh';\r\n const targetType = node.attrs.targetType === 'figure' ? 'figure' : 'claim';\r\n const displayText = typeof node.attrs.displayText === 'string' ? node.attrs.displayText.trim() : '';\r\n if (displayText) {\r\n return displayText;\r\n }\r\n if (targetType === 'figure') {\r\n const resolvedFigureId =\r\n typeof node.attrs.resolvedFigureId === 'string' ? node.attrs.resolvedFigureId.trim() : '';\r\n if (resolvedFigureId) {\r\n return resolvedFigureId;\r\n }\r\n return language === 'en' ? 'Figure ?' : '附图?';\r\n }\r\n const resolvedNumber = Number(node.attrs.resolvedNumber);\r\n if (Number.isFinite(resolvedNumber)) {\r\n return language === 'en' ? `Claim ${resolvedNumber}` : `权利要求${resolvedNumber}`;\r\n }\r\n return language === 'en' ? 'Claim ?' : '权利要求?';\r\n};\r\n\r\n/**\r\n * Extract claims from paragraphs within patent_section(sectionType: 'claims').\r\n * Each paragraph starting with \"N. \" or \"N、\" is treated as a claim.\r\n */\r\nexport const extractClaimsFromEditor = (editor: Editor): ClaimSnapshot[] => {\r\n const claims: ClaimSnapshot[] = [];\r\n\r\n editor.state.doc.descendants((node, pos) => {\r\n if (node.type.name === 'patent_section') {\r\n return node.attrs.sectionType === 'claims';\r\n }\r\n if (node.type.name !== 'paragraph') return true;\r\n\r\n const text = serializeClaimBodyText(node).trim();\r\n const match = CLAIM_NUMBER_PATTERN.exec(text);\r\n if (!match) return true;\r\n\r\n const number = parseInt(match[1], 10);\r\n if (!Number.isFinite(number) || number <= 0) return true;\r\n\r\n const body = text.slice(match[0].length).trim();\r\n const dependsOn = extractDependencies(body, number);\r\n\r\n claims.push({\r\n claimId: `claim_${number}`,\r\n number,\r\n dependsOn,\r\n dependsOnClaimIds: dependsOn.map(n => `claim_${n}`),\r\n body,\r\n pos,\r\n });\r\n return true;\r\n });\r\n\r\n return claims;\r\n};\r\n"],"names":["SlashCommandPluginKey","PluginKey","SlashCommand","Extension","editor","range","props","Suggestion","defaultRightPanel","useEditorStore","create","set","document","selection","editorLanguage","autoSaveStatus","lastSavedAt","status","sectionType","state","abortFn","adapter","api","id","sectionPos","regenerate","tab","ref","msg","SlashMenuList","forwardRef","items","command","selectedIndex","setSelectedIndex","useState","useEffect","selectItem","useCallback","index","item","useImperativeHandle","event","prev","jsx","jsxs","getSlashCommandItems","lang","zh","url","createSlashSuggestion","query","all","lower","component","popup","ReactRenderer","tippy","_a","_b","SearchReplacePluginKey","findMatches","doc","searchTerm","caseSensitive","results","text","term","haystack","pos","idx","charCount","fromPos","toPos","node","nodePos","nodeText","i","SearchReplace","val","r","scrollToSelection","replaceTerm","matches","tr","offset","m","from","to","storage","Plugin","DecorationSet","decorations","className","Decoration","dom","el","DIFF_DELETE","DIFF_INSERT","DIFF_EQUAL","_dmp","getDmp","diff_match_patch","PatchDiffPluginKey","findSectionRange","result","buildTextMap","rangeFrom","rangeTo","segments","separated","nodeStart","sliceFrom","sliceTo","slice","textOffsetToDocPos","seg","searchTextInRange","searchText","skipPositions","searchStart","matchFrom","matchTo","resolvePatchTarget","patchData","refs","patchIndex","alreadyResolved","target","claimedPositions","p","finalRange","narrowed","origText","pendingPatches","patchChangeListeners","onPatchChange","listener","l","notifyPatchChange","getPatches","setPatches","patches","clearPatches","acceptPatch","patchId","patch","isBlockContainerContentRange","nodes","textToParagraphs","mapping","newFrom","newTo","refreshDecorations","rejectPatch","acceptAllPatches","sorted","b","rejectAllPatches","getInlineRanges","ranges","blockStart","blockEnd","computeFineDiff","$from","$to","inst","diffs","equalLen","op","sum","docPos","delEnd","createPatchDiffPlugin","pending","fineDiffs","widgetPos","isLong","schema","content","HardBreak","Node","nodeType","DragDropUX","dropCursor","gapCursor","PatchDiffExtension","baseNodes","Document","Paragraph","Text","Heading","BulletList","OrderedList","ListItem","Blockquote","CodeBlock","HorizontalRule","TaskList","TaskItem","Image","element","attributes","Table","TableRow","TableCell","TableHeader","Placeholder","History","TextAlign","baseMarks","Bold","Italic","Underline","Strike","Code","Superscript","Subscript","Link","TextStyle","Color","Highlight","schemaExtensions","CommandRegistry","__publicField","name","namespace","options","fullName","context","payload","startedAt","useTransaction","rollbackOnFail","snapshot","success","completed","_c","error","_d","commandRegistry","PluginManager","stage","pluginName","a","plugin","commandName","missingDependencies","dependency","extensions","pluginManager","dict","count","number","claimType","getEditorText","language","mermaidIdCounter","cleanupOrphans","MermaidNode","HTMLAttributes","mergeAttributes","getPos","currentNode","editMode","viewContainer","preview","viewHint","editContainer","textarea","toolbar","errorMsg","cancelBtn","saveBtn","setNodeAttrs","dispatch","lastRenderedCode","doRender","code","trimmed","mermaid","renderId","svg","enterEditMode","renderUI","exitEditMode","saveAndRender","e","i18n","hasCode","hasSvg","currentLanguage","unsub","updatedNode","MermaidPlugin","DrawioNode","previewImg","drawioMessageHandler","drawioModal","drawioIframe","modalContent","modalHeader","modalTitle","closeBtn","iframeRef","ev","existingXml","xml","svgData","DrawioPlugin","MathComponent","updateAttributes","selected","mfRef","useRef","isEditing","setIsEditing","isBlock","isEditingRef","latestUpdateAttrs","latestLatex","enterEdit","exitEdit","latex","isCollapsed","mf","onFocusOut","active","onKeyDown","markup","katex","NodeViewWrapper","MathInline","ReactNodeViewRenderer","MathBlock","MathPlugin","findNodeByType","typeName","scope","matched","findNodesByPredicate","predicate","findAncestorNode","depth","findCurrentBlock","getNodeType","buildNodeContent","input","normalizedContent","insertNode","updateNodeAttrs","targetPos","attrs","removeNode","wrapSelection","wrapping","findWrapping","applyTransactionBatch","operations","operation","_svgGenQueue","_svgGenBusy","_SVG_GEN_TIMEOUT_MS","_IDLE_DESTROY_MS","_sharedIframe","_sharedIframeReady","_currentMsgHandler","_idleTimer","_svgCache","_destroySharedIframe","queueDrawioSvgGen","callback","cached","_processNextSvgGen","timeoutId","done","sendLoad","cleanupMermaidOrphans","FigureNode","mermaidEditMode","drawioEditMode","visual","imgEl","uploadArea","uploadHint","fileInput","replaceBtn","mermaidViewContainer","mermaidPreview","mermaidViewHint","mermaidEditContainer","mermaidEditor","mermaidToolbar","mermaidSaveBtn","mermaidCancelBtn","mermaidErrorMsg","drawioViewContainer","drawioPreviewImg","drawioViewHint","caption","idLabel","captionContent","handleFiles","files","file","reader","enterMermaidEditMode","exitMermaidEditMode","saveMermaidAndRender","enterDrawioEditMode","exitDrawioEditMode","end","sel","TextSelection","drawioSvgGenQueued","drawioSvgDebounceTimer","drawioSvgRetryTimer","drawioSvgRetries","_MAX_SVG_RETRIES","_SVG_DEBOUNCE_MS","_SVG_RETRY_DELAY_MS","lastRenderedMermaidCode","doInitialMermaidRender","contentType","figureId","imageSrc","mermaidCode","isImage","isMermaid","isDrawio","drawioSvg","drawioXml","mutation","ReferenceNode","fallback","rerender","targetType","resolvedNumber","resolvedFigureId","targetFigureId","descendant","SECTION_TITLE_I18N_KEYS","BOOK_LEVEL_SECTIONS","DESCRIPTION_SUB_SECTIONS","hasMeaningfulContent","found","child","PatentTitleNode","bookHeading","placeholder","contentArea","getNodePos","activateTitle","onPlaceholderClick","render","bookLabel","titleLabel","hasContent","isActive","prevLang","prevActivePos","langChanged","posChanged","PatentSectionNode","stripSectionWrappers","fragment","Fragment","cleaned","Slice","oldOrder","newOrder","heading","body","activateSection","openDraftingForSection","isBook","isSub","titleKey","sectionTitle","PRE_DESCRIPTION_SECTIONS","DESCRIPTION_SECTIONS","POST_DESCRIPTION_SECTIONS","DESIGN_SECTIONS","buildSectionNode","buildTitleNode","buildInventionContent","buildDesignContent","buildPatentDocument","patentType","getFigureNodes","normalizeFigureId","value","suggestNextFigureId","prefix","used","FIGURE_ID_PATTERN","syncFigureOrder","figures","updates","seqIndex","fig","currentId","expectedId","u","getFigureIndex","figureIndex","match","getGlobalReferenceLanguage","buildFigureReferenceText","invalid","syncFigureReferenceState","globalLanguage","changed","matchedFigure","displayText","nextAttrs","key","PatentPlugin","data","currentReference","figureNode","candidateId","attrsPatch","duplicated","_","sectionNode","plugins","defaultPlugins","createEditorConfig","createCommandContext","createCommandExecutor","defaultGroupOrder","groupI18nKeyMap","formatGroupLabel","group","part","DropdownButton","btn","open","setOpen","triggerRef","menuRef","setPos","updatePosition","rect","handleClickOutside","handleScroll","clsx","v","ChevronDown","createPortal","Toolbar","groupOrder","collapsibleGroups","defaultCollapsedGroups","collapsedGroups","setCollapsedGroups","setEditorLanguage","commandExecutor","coreButtons","Undo2","Redo2","Strikethrough","Pilcrow","Heading1","Heading2","Heading3","AlignLeft","AlignCenter","AlignRight","AlignJustify","List","ListOrdered","Quote","FileCode2","TableIcon","Minus","CheckSquare","iconMap","GitGraph","Sigma","FunctionSquare","Workflow","Box","FileText","Link2","pluginButtons","commandMeta","tooltip","shortcut","displayTooltip","Square","allButtons","extraGroups","button","source","groupedButtons","entry","toggleGroup","next","tableDropdownItems","figureDropdownItems","renderButton","collapsed","NodeToolbar","version","setVersion","selectedFigureId","setSelectedFigureId","figureOptions","activeFigure","hasActiveFigure","activeFigureId","activeFigureContentType","editingFigureId","setEditingFigureId","figureIdInputRef","prevActiveFigurePos","currentFigurePos","handleFigureTypeChange","newType","handleFigureIdCommit","currentWidth","w","Trash2","sectionContextDeps","getMissingSectionDeps","targetSection","completedSections","dep","getAllSections","sections","findSectionAtCursor","$pos","buildDependencyContext","targetSectionType","deps","sectionMap","s","depType","section","buildAIContext","selectedText","targetSectionPos","current","dependencyContext","surroundingText","beforeFrom","afterTo","before","after","EditorBubbleMenu","onSelectionOptimize","addChatReference","openChatPanel","btnClass","handleAIOptimize","handleLink","TiptapBubbleMenu","Highlighter","Sparkles","FindReplace","visible","setVisible","showReplace","setShowReplace","setSearchTerm","setReplaceTerm","setCaseSensitive","searchInputRef","resultCount","currentIndex","handler","detail","doSearch","close","toggleCaseSensitive","CaseSensitive","ChevronUp","Replace","X","ReplaceAll","WordCount","stats","useMemo","selectionCount","STATE_ICONS","STATE_COLORS","DESCRIPTION_SUB_TYPES","OutlinePanel","setCollapsed","descriptionGroupInserted","title","level","PanelLeft","PanelLeftClose","NodeRenderer","mode","EditorContent","AUTO_SAVE_KEY","AUTO_SAVE_DEBOUNCE_MS","loadDraftFromStorage","raw","EditorView","initialContent","onChange","readOnly","editable","onEditorReady","setEditor","setDocument","ai","setAutoSaveStatus","setLastSavedAt","debounceRef","resolvedInitialContent","saveToStorage","json","useEditor","initialContentAppliedRef","saveLabel","parseSSEStream","decoder","buffer","controller","lines","currentEvent","line","parsed","eventType","createSSEAdapter","baseUrl","headers","req","resp","createChatSessionAPI","base","init","patentId","page","pageSize","params","sessionId","messageId","PatentEditor","aiService","chatSessionAPI","aiBaseUrl","aiHeaders","setAIService","setChatSessionAPI","localEditorRef","handleEditorReady","resolvedContent","React","writeStream","aborted","clearSectionContent","insertPos","getInsertPosition","removeEmptyParagraphs","err","writeStreamFromSSE","abortController","response","_e","ssetr","_f","_g","_h","contentStart","contentEnd","paragraph","toDelete","totalChildren","nonEmptyCount","childStart","childEnd","SECTION_TEXTS","CHAT_RESPONSES","delay","ms","createMockStream","events","chunkDelayMs","cancelled","evt","buildStreamingEvents","chunks","splitTextIntoChunks","chunk","chunkSize","buildChatStreamEvents","userContent","responseText","analysis","original","optimized","createMockAIService","sectionKey","sectionText","fullText","createMockChatSessionAPI","sessions","pendingStream","session","stream","asstId","parseClaimsText","claims","normalized","claimPattern","start","claimText","claimNumber","dependsOn","extractDependencies","selfNumber","zhPattern","n","enPattern","buildClaimsJSONContent","DocDiffPluginKey","applyDocDiffDecorations","originalText","docSize","currentText","dmp","curOffset","runStart","display","decoSet","removeDocDiffDecorations","BOOK_SECTIONS","DESCRIPTION_SUBS","extractDocNodes","paragraphs","TextRun","AlignmentType","subSectionHeading","patentTitleParagraph","bodyParagraph","convertMillimetersToTwip","buildDocxParagraphs","descriptionBookInserted","exportToWord","patentTitle","fileName","sectionOptions","blob","Packer","saveAs","exportToPdf","validatePatentDocument","issues","issueIdx","nextId","childText","CLAIM_NUMBER_PATTERN","DEPENDENCY_PATTERN_ZH","DEPENDENCY_PATTERN_EN","serializeClaimBodyText","buildReferenceInlineText","extractClaimsFromEditor"],"mappings":"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"}
|