Repository: codexu/note-gen Branch: dev Commit: 67bb0200a36b Files: 605 Total size: 3.5 MB Directory structure: gitextract_k__2zx16/ ├── .eslintrc.json ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── feature_request.yml │ └── workflows/ │ └── release.yml ├── .gitignore ├── .vscode/ │ └── settings.json ├── LICENSE ├── README.md ├── components.json ├── messages/ │ ├── en.json │ ├── ja.json │ ├── pt-BR.json │ ├── zh-TW.json │ └── zh.json ├── next.config.ts ├── package.json ├── postcss.config.mjs ├── public/ │ └── markdown/ │ ├── github-markdown-dark.css │ └── github-markdown-light.css ├── scripts/ │ └── sync-version.sh ├── src/ │ ├── app/ │ │ ├── core/ │ │ │ ├── index.d.ts │ │ │ ├── layout.tsx │ │ │ ├── main/ │ │ │ │ ├── chat/ │ │ │ │ │ ├── agent-execution-status.tsx │ │ │ │ │ ├── agent-history.tsx │ │ │ │ │ ├── agent-panel-with-rag.tsx │ │ │ │ │ ├── chat-clipboard.tsx │ │ │ │ │ ├── chat-content.tsx │ │ │ │ │ ├── chat-empty.tsx │ │ │ │ │ ├── chat-footer.tsx │ │ │ │ │ ├── chat-header.tsx │ │ │ │ │ ├── chat-images.tsx │ │ │ │ │ ├── chat-input.tsx │ │ │ │ │ ├── chat-preview.tsx │ │ │ │ │ ├── chat-send.tsx │ │ │ │ │ ├── chat-thinking.tsx │ │ │ │ │ ├── chat.css │ │ │ │ │ ├── clear-chat.tsx │ │ │ │ │ ├── clear-context.tsx │ │ │ │ │ ├── clipboard-listener.tsx │ │ │ │ │ ├── clipboard-monitor.tsx │ │ │ │ │ ├── file-link.tsx │ │ │ │ │ ├── file-selector.tsx │ │ │ │ │ ├── history-dropdown.tsx │ │ │ │ │ ├── image-attachments.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mcp-button.tsx │ │ │ │ │ ├── mcp-tool-call.tsx │ │ │ │ │ ├── message-control/ │ │ │ │ │ │ ├── condensed-indicator.tsx │ │ │ │ │ │ ├── copy-control.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── mark-text.tsx │ │ │ │ │ │ ├── message-info.tsx │ │ │ │ │ │ ├── note-output.tsx │ │ │ │ │ │ ├── read-aloud-control.tsx │ │ │ │ │ │ └── translate-control.tsx │ │ │ │ │ ├── model-select.tsx │ │ │ │ │ ├── new-chat.tsx │ │ │ │ │ ├── onboarding-typing.ts │ │ │ │ │ ├── prompt-select.tsx │ │ │ │ │ ├── quote-display.tsx │ │ │ │ │ ├── quote-preview.ts │ │ │ │ │ ├── rag-switch.tsx │ │ │ │ │ └── streaming-smoother.ts │ │ │ │ ├── editor/ │ │ │ │ │ ├── editor-layout.tsx │ │ │ │ │ ├── empty-state-actions.ts │ │ │ │ │ ├── empty-state.tsx │ │ │ │ │ ├── folder/ │ │ │ │ │ │ ├── folder-stats.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── skill-detail.tsx │ │ │ │ │ │ └── skills-list.tsx │ │ │ │ │ ├── image/ │ │ │ │ │ │ ├── image-editor.css │ │ │ │ │ │ ├── image-editor.tsx │ │ │ │ │ │ └── image-footer.tsx │ │ │ │ │ ├── markdown/ │ │ │ │ │ │ ├── ai-completion.tsx │ │ │ │ │ │ ├── ai-suggestion-floating.tsx │ │ │ │ │ │ ├── ai-suggestion.ts │ │ │ │ │ │ ├── bubble-menu.tsx │ │ │ │ │ │ ├── export-menu.tsx │ │ │ │ │ │ ├── floating-table-menu.tsx │ │ │ │ │ │ ├── footer-bar/ │ │ │ │ │ │ │ ├── copy-button.tsx │ │ │ │ │ │ │ ├── export-button.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── outline-toggle.tsx │ │ │ │ │ │ │ ├── vector-calc.tsx │ │ │ │ │ │ │ └── word-count.tsx │ │ │ │ │ │ ├── image-bubble-menu.tsx │ │ │ │ │ │ ├── markdown-input-rules.ts │ │ │ │ │ │ ├── markdown-paragraph.ts │ │ │ │ │ │ ├── math-editor-dialog.tsx │ │ │ │ │ │ ├── math-extension.tsx │ │ │ │ │ │ ├── md-editor-wrapper.tsx │ │ │ │ │ │ ├── mermaid-extension.tsx │ │ │ │ │ │ ├── mobile-editor-context-bar-view-model.ts │ │ │ │ │ │ ├── mobile-editor-context-bar.tsx │ │ │ │ │ │ ├── mobile-editor-more-sheet.tsx │ │ │ │ │ │ ├── mobile-selection-context.ts │ │ │ │ │ │ ├── outline.tsx │ │ │ │ │ │ ├── quote-mark.ts │ │ │ │ │ │ ├── quote-session.ts │ │ │ │ │ │ ├── search-navigation.ts │ │ │ │ │ │ ├── search-replace-panel.tsx │ │ │ │ │ │ ├── slash-command/ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── slash-command-portal.tsx │ │ │ │ │ │ │ ├── slash-menu.tsx │ │ │ │ │ │ │ └── suggestion.tsx │ │ │ │ │ │ ├── style.css │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── conflict-dialog.tsx │ │ │ │ │ │ │ ├── history-sheet.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── pull-button.tsx │ │ │ │ │ │ │ ├── sync-button.tsx │ │ │ │ │ │ │ └── sync-tools.tsx │ │ │ │ │ │ ├── table-toolbar.tsx │ │ │ │ │ │ └── tiptap-editor.tsx │ │ │ │ │ ├── onboarding-state.ts │ │ │ │ │ ├── tab-bar.tsx │ │ │ │ │ └── unsupported-file.tsx │ │ │ │ ├── file/ │ │ │ │ │ ├── file-actions.tsx │ │ │ │ │ ├── file-footer.tsx │ │ │ │ │ ├── file-item.tsx │ │ │ │ │ ├── file-manager.tsx │ │ │ │ │ ├── file-toolbar.tsx │ │ │ │ │ ├── folder-item/ │ │ │ │ │ │ ├── copy-folder.tsx │ │ │ │ │ │ ├── cut-folder.tsx │ │ │ │ │ │ ├── delete-folder.tsx │ │ │ │ │ │ ├── duplicate-folder.tsx │ │ │ │ │ │ ├── folder-vector-menu.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── new-file.tsx │ │ │ │ │ │ ├── new-folder.tsx │ │ │ │ │ │ ├── paste-in-folder.tsx │ │ │ │ │ │ ├── paste-into-folder.js │ │ │ │ │ │ ├── paste-target.js │ │ │ │ │ │ ├── paste-target.spec.mjs │ │ │ │ │ │ ├── rename-folder.tsx │ │ │ │ │ │ ├── sync-folder.tsx │ │ │ │ │ │ └── view-directory.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mobile-action-menu.tsx │ │ │ │ │ ├── root-drop.js │ │ │ │ │ ├── root-drop.spec.mjs │ │ │ │ │ ├── vector-knowledge-menu.tsx │ │ │ │ │ └── workspace-selector.tsx │ │ │ │ ├── left-sidebar.tsx │ │ │ │ ├── mark/ │ │ │ │ │ ├── clipboard.tsx │ │ │ │ │ ├── control-file.tsx │ │ │ │ │ ├── control-image.tsx │ │ │ │ │ ├── control-link.tsx │ │ │ │ │ ├── control-recording.tsx │ │ │ │ │ ├── control-scan.tsx │ │ │ │ │ ├── control-text.tsx │ │ │ │ │ ├── control-todo.tsx │ │ │ │ │ ├── crop.css │ │ │ │ │ ├── image-gallery.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mark-actions.tsx │ │ │ │ │ ├── mark-empty.tsx │ │ │ │ │ ├── mark-filter-popover.tsx │ │ │ │ │ ├── mark-filters.mjs │ │ │ │ │ ├── mark-filters.spec.mjs │ │ │ │ │ ├── mark-header.tsx │ │ │ │ │ ├── mark-item.tsx │ │ │ │ │ ├── mark-list-card-view.tsx │ │ │ │ │ ├── mark-list-compact-view.tsx │ │ │ │ │ ├── mark-list-default-view.tsx │ │ │ │ │ ├── mark-list-item-content.tsx │ │ │ │ │ ├── mark-list.tsx │ │ │ │ │ ├── mark-loading.tsx │ │ │ │ │ ├── mark-mobile-actions.tsx │ │ │ │ │ ├── mark-toolbar.tsx │ │ │ │ │ ├── mark-type-meta.ts │ │ │ │ │ ├── mark-view-mode-toggle.tsx │ │ │ │ │ ├── mark-view-mode.mjs │ │ │ │ │ ├── mark-view-mode.spec.mjs │ │ │ │ │ ├── organize-notes.tsx │ │ │ │ │ ├── organize-onboarding.ts │ │ │ │ │ ├── tag-item.tsx │ │ │ │ │ ├── tag-manage.tsx │ │ │ │ │ ├── tag-mobile-actions.tsx │ │ │ │ │ ├── todo-edit-button.tsx │ │ │ │ │ ├── todo-edit-dialog.tsx │ │ │ │ │ ├── todo-form.tsx │ │ │ │ │ └── todo-item-content.tsx │ │ │ │ └── page.tsx │ │ │ └── setting/ │ │ │ ├── about/ │ │ │ │ ├── page.tsx │ │ │ │ ├── setting-about.tsx │ │ │ │ └── updater.tsx │ │ │ ├── ai/ │ │ │ │ ├── create.tsx │ │ │ │ ├── default-models.tsx │ │ │ │ ├── model-card.tsx │ │ │ │ ├── modelSelect.tsx │ │ │ │ └── page.tsx │ │ │ ├── audio/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── chat/ │ │ │ │ ├── condense-settings.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── primary-model-settings.tsx │ │ │ │ └── toolbar-settings.tsx │ │ │ ├── components/ │ │ │ │ ├── default-models-settings.tsx │ │ │ │ ├── model-select.tsx │ │ │ │ ├── setting-base.tsx │ │ │ │ ├── setting-tab.tsx │ │ │ │ └── upload-store.tsx │ │ │ ├── config.tsx │ │ │ ├── defaultModel/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── dev/ │ │ │ │ ├── page.tsx │ │ │ │ ├── set-config.tsx │ │ │ │ └── setting-dev.tsx │ │ │ ├── editor/ │ │ │ │ ├── centered-content.tsx │ │ │ │ ├── commit.tsx │ │ │ │ ├── completion.tsx │ │ │ │ ├── outline.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── show-undo-redo.tsx │ │ │ ├── file/ │ │ │ │ ├── page.tsx │ │ │ │ ├── setting-assets.tsx │ │ │ │ └── setting-workspace.tsx │ │ │ ├── general/ │ │ │ │ ├── interface-settings/ │ │ │ │ │ ├── content-text-scale.tsx │ │ │ │ │ ├── custom-theme.tsx │ │ │ │ │ ├── file-manager-text-size.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── language.tsx │ │ │ │ │ ├── record-text-size.tsx │ │ │ │ │ ├── scale.tsx │ │ │ │ │ ├── theme-color-picker.tsx │ │ │ │ │ ├── theme-presets.tsx │ │ │ │ │ └── theme.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── tool-settings.tsx │ │ │ ├── imageHosting/ │ │ │ │ ├── github.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── picgo.tsx │ │ │ │ ├── s3.tsx │ │ │ │ ├── setting-switch.tsx │ │ │ │ └── smms.tsx │ │ │ ├── imageMethod/ │ │ │ │ ├── ocr.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── setDefault.tsx │ │ │ │ └── vlm.tsx │ │ │ ├── layout.tsx │ │ │ ├── mcp/ │ │ │ │ ├── connection-test.tsx │ │ │ │ ├── json-import-dialog.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── runtime-environment-card.tsx │ │ │ │ ├── server-config-dialog.tsx │ │ │ │ ├── server-list.tsx │ │ │ │ └── tool-browser.tsx │ │ │ ├── memories/ │ │ │ │ └── page.tsx │ │ │ ├── page.tsx │ │ │ ├── prompt/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting-prompt.tsx │ │ │ ├── rag/ │ │ │ │ ├── model-setting.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── settings.tsx │ │ │ ├── readAloud/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── record/ │ │ │ │ ├── model-settings.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── toolbar-settings.tsx │ │ │ ├── shortcuts/ │ │ │ │ ├── page.tsx │ │ │ │ └── shorcut-input.tsx │ │ │ ├── skills/ │ │ │ │ ├── components/ │ │ │ │ │ ├── global-skills-manager.tsx │ │ │ │ │ ├── project-skills-list.tsx │ │ │ │ │ ├── skill-card.tsx │ │ │ │ │ └── skills-settings.tsx │ │ │ │ └── page.tsx │ │ │ ├── sync/ │ │ │ │ ├── components/ │ │ │ │ │ └── sync-platform-card.tsx │ │ │ │ ├── gitea-sync.tsx │ │ │ │ ├── gitee-sync.tsx │ │ │ │ ├── github-sync.tsx │ │ │ │ ├── gitlab-sync.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── s3-sync.tsx │ │ │ │ └── webdav-sync.tsx │ │ │ └── template/ │ │ │ ├── page.tsx │ │ │ └── setting-template.tsx │ │ ├── error.tsx │ │ ├── global-error.tsx │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── mobile/ │ │ │ ├── chat/ │ │ │ │ ├── components/ │ │ │ │ │ ├── chat-attachments-drawer.tsx │ │ │ │ │ ├── chat-settings-drawer.tsx │ │ │ │ │ ├── chat-tools-drawer.tsx │ │ │ │ │ ├── clear-chat.tsx │ │ │ │ │ ├── clear-context.tsx │ │ │ │ │ ├── clipboard-toggle.tsx │ │ │ │ │ ├── mcp-selector.tsx │ │ │ │ │ ├── mobile-chat-header.tsx │ │ │ │ │ ├── model-selector.tsx │ │ │ │ │ ├── new-chat.tsx │ │ │ │ │ ├── prompt-selector.tsx │ │ │ │ │ └── rag-toggle.tsx │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── mobile-styles.css │ │ │ ├── record/ │ │ │ │ ├── mobile-mark-header.tsx │ │ │ │ ├── mobile-record-stream.tsx │ │ │ │ └── page.tsx │ │ │ ├── setting/ │ │ │ │ ├── components/ │ │ │ │ │ └── setting-tab.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── pages/ │ │ │ │ ├── ai/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── audio/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── chat/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── defaultModel/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── dev/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── editor/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── file/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── general/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── imageHosting/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── imageMethod/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── mcp/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── prompt/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── rag/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── readAloud/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── record/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── skills/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── sync/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── template/ │ │ │ │ │ └── page.tsx │ │ │ │ └── theme/ │ │ │ │ └── page.tsx │ │ │ └── writing/ │ │ │ ├── browser-utils.ts │ │ │ ├── custom-header.tsx │ │ │ ├── entry-list-item.tsx │ │ │ ├── mobile-editor.tsx │ │ │ ├── name-input-dialog.tsx │ │ │ ├── page.tsx │ │ │ └── types.ts │ │ ├── model-config.ts │ │ ├── not-found.tsx │ │ └── page.tsx │ ├── components/ │ │ ├── activity/ │ │ │ ├── activity-day-detail.tsx │ │ │ ├── activity-drawer.tsx │ │ │ ├── activity-heatmap.tsx │ │ │ ├── activity-legend.tsx │ │ │ └── activity-panel.tsx │ │ ├── app-footbar.tsx │ │ ├── app-sidebar.tsx │ │ ├── app-status.tsx │ │ ├── audio-player.tsx │ │ ├── bottom-bar-icon-button.tsx │ │ ├── console-filter.tsx │ │ ├── draggable-toolbar-item.tsx │ │ ├── image-viewer.tsx │ │ ├── local-image.tsx │ │ ├── memories/ │ │ │ ├── memory-form.tsx │ │ │ ├── memory-item.tsx │ │ │ ├── memory-list.tsx │ │ │ └── memory-stats.tsx │ │ ├── mobile-record-tools.tsx │ │ ├── mobile-statusbar.tsx │ │ ├── onboarding-spotlight-position.ts │ │ ├── onboarding-spotlight.tsx │ │ ├── open-broswer.tsx │ │ ├── pin-toggle.tsx │ │ ├── providers/ │ │ │ └── NextIntlProvider.tsx │ │ ├── recording-dialog.tsx │ │ ├── recording-indicator.tsx │ │ ├── search-dialog.tsx │ │ ├── simple-mobile-tool.tsx │ │ ├── sync-confirm-dialog.tsx │ │ ├── sync-status-badge.tsx │ │ ├── theme-provider.tsx │ │ ├── title-bar-toolbars/ │ │ │ └── sync-toggle.tsx │ │ ├── title-bar.tsx │ │ ├── tooltip-button.tsx │ │ └── ui/ │ │ ├── accordion.tsx │ │ ├── agent-plan.tsx │ │ ├── alert-dialog.tsx │ │ ├── alert.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── calendar.tsx │ │ ├── card.tsx │ │ ├── carousel.tsx │ │ ├── checkbox.tsx │ │ ├── collapsible.tsx │ │ ├── command.tsx │ │ ├── context-menu.tsx │ │ ├── dialog.tsx │ │ ├── diff-viewer.tsx │ │ ├── drawer.tsx │ │ ├── dropdown-menu.tsx │ │ ├── empty.tsx │ │ ├── enhanced-context-menu.tsx │ │ ├── expandable-tabs.tsx │ │ ├── form.tsx │ │ ├── hover-card.tsx │ │ ├── input.tsx │ │ ├── item.tsx │ │ ├── kbd.tsx │ │ ├── label.tsx │ │ ├── popover.tsx │ │ ├── progress.tsx │ │ ├── radio-group.tsx │ │ ├── resizable.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.tsx │ │ ├── shine-border.tsx │ │ ├── sidebar.tsx │ │ ├── skeleton.tsx │ │ ├── slider.tsx │ │ ├── swipe-back.tsx │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── tabs.tsx │ │ ├── textarea.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle.tsx │ │ └── tooltip.tsx │ ├── config/ │ │ ├── emitters.ts │ │ ├── shortcut.ts │ │ └── sync-exclusions.ts │ ├── contexts/ │ │ └── text-size-context.tsx │ ├── db/ │ │ ├── activity.ts │ │ ├── chats.ts │ │ ├── conversations.ts │ │ ├── index.ts │ │ ├── marks.ts │ │ ├── memories.ts │ │ ├── notes.ts │ │ ├── tags.ts │ │ └── vector.ts │ ├── hooks/ │ │ ├── use-file-shortcuts.ts │ │ ├── use-mobile.tsx │ │ ├── use-sync-manager.ts │ │ ├── use-sync-settings.ts │ │ ├── use-toast.ts │ │ ├── use-toolbar-shortcuts.ts │ │ ├── use-username.ts │ │ ├── useAiCompletion.ts │ │ └── useI18n.ts │ ├── i18n/ │ │ └── request.ts │ ├── lib/ │ │ ├── activity/ │ │ │ ├── aggregate.ts │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── agent/ │ │ │ ├── agent-handler.ts │ │ │ ├── auto-final-answer.ts │ │ │ ├── i18n.ts │ │ │ ├── parse-action-input.ts │ │ │ ├── react-diff-helpers.ts │ │ │ ├── react.ts │ │ │ ├── session-approval.ts │ │ │ ├── tool-confirmation-display.ts │ │ │ ├── tool-policy.ts │ │ │ ├── tools/ │ │ │ │ ├── chat-tools.ts │ │ │ │ ├── editor-tools.ts │ │ │ │ ├── folder-tools.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mark-tools.ts │ │ │ │ ├── memory-tools.ts │ │ │ │ ├── note-tools.ts │ │ │ │ ├── system-tools.ts │ │ │ │ └── tag-tools.ts │ │ │ └── types.ts │ │ ├── ai/ │ │ │ ├── chat.ts │ │ │ ├── completion.ts │ │ │ ├── condense.ts │ │ │ ├── description.ts │ │ │ ├── embedding.ts │ │ │ ├── history-messages.ts │ │ │ ├── index.ts │ │ │ ├── placeholder.ts │ │ │ ├── rewrite.ts │ │ │ ├── token-counter.ts │ │ │ ├── translate.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── audio-converter.ts │ │ ├── audio.ts │ │ ├── bm25.ts │ │ ├── check.ts │ │ ├── context/ │ │ │ └── loader.ts │ │ ├── default-filename.ts │ │ ├── editor-layout-styles.ts │ │ ├── emitter.ts │ │ ├── event-report.ts │ │ ├── files.ts │ │ ├── folder-vector.ts │ │ ├── fuzzy-search.ts │ │ ├── image-handler.ts │ │ ├── imageHosting/ │ │ │ ├── github.ts │ │ │ ├── index.ts │ │ │ ├── picgo.ts │ │ │ ├── s3.ts │ │ │ └── smms.ts │ │ ├── infographic.ts │ │ ├── locales.ts │ │ ├── mark-to-markdown.ts │ │ ├── markdown.ts │ │ ├── mcp/ │ │ │ ├── client.ts │ │ │ ├── index.ts │ │ │ ├── init.ts │ │ │ ├── integration.ts │ │ │ ├── runtime-assistant.ts │ │ │ ├── server-manager.ts │ │ │ ├── tools.ts │ │ │ └── types.ts │ │ ├── ocr.ts │ │ ├── outline-preferences.ts │ │ ├── outline-styles.ts │ │ ├── path.ts │ │ ├── pdf.ts │ │ ├── rag.ts │ │ ├── record-navigation.ts │ │ ├── search-utils.ts │ │ ├── shortcut/ │ │ │ ├── quick-record-text.ts │ │ │ └── show-window.ts │ │ ├── skills/ │ │ │ ├── dependency-installer.ts │ │ │ ├── executor.ts │ │ │ ├── index.ts │ │ │ ├── manager.ts │ │ │ ├── parser.ts │ │ │ ├── path-utils.ts │ │ │ ├── runtime-paths.ts │ │ │ ├── runtime.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── validator.ts │ │ ├── speech/ │ │ │ ├── capabilities.ts │ │ │ ├── preferences.ts │ │ │ ├── resolver.ts │ │ │ ├── runtime.ts │ │ │ ├── transcription-fallback.ts │ │ │ └── types.ts │ │ ├── sync/ │ │ │ ├── auto-sync.ts │ │ │ ├── conflict-resolution.ts │ │ │ ├── encode-fetch.ts │ │ │ ├── filename-utils.ts │ │ │ ├── folder-sync-helper.ts │ │ │ ├── folder-sync.ts │ │ │ ├── gitea.ts │ │ │ ├── gitea.types.ts │ │ │ ├── gitee.ts │ │ │ ├── github.ts │ │ │ ├── github.types.ts │ │ │ ├── gitlab.ts │ │ │ ├── gitlab.types.ts │ │ │ ├── remote-file.ts │ │ │ ├── repo-utils.ts │ │ │ ├── s3.ts │ │ │ ├── sync-manager.ts │ │ │ ├── sync-push-queue.ts │ │ │ └── webdav.ts │ │ ├── template-range-utils.ts │ │ ├── theme-utils.ts │ │ ├── toolbar-shortcuts.ts │ │ ├── utils.ts │ │ ├── vector-document-key.js │ │ ├── vector-document-key.spec.mjs │ │ └── workspace.ts │ ├── stores/ │ │ ├── article.ts │ │ ├── chat.ts │ │ ├── clipboard.ts │ │ ├── imageHosting.ts │ │ ├── mark.ts │ │ ├── mcp.ts │ │ ├── memories.ts │ │ ├── prompt.ts │ │ ├── ragSettings.ts │ │ ├── recording.ts │ │ ├── setting.ts │ │ ├── settingsSync.ts │ │ ├── shortcut.ts │ │ ├── sidebar.ts │ │ ├── skills.ts │ │ ├── speech-recognition.ts │ │ ├── sync-confirm.ts │ │ ├── sync.ts │ │ ├── tag.ts │ │ ├── update.ts │ │ └── vector.ts │ └── types/ │ ├── sync.ts │ └── theme.ts ├── src-tauri/ │ ├── .gitignore │ ├── Cargo.toml │ ├── Info.plist │ ├── build.rs │ ├── capabilities/ │ │ ├── default.json │ │ └── desktop.json │ ├── icons/ │ │ └── icon.icns │ ├── src/ │ │ ├── app_setup.rs │ │ ├── backup.rs │ │ ├── device.rs │ │ ├── fuzzy_search.rs │ │ ├── keywords.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── mcp.rs │ │ ├── mcp_runtime.rs │ │ ├── screenshot.rs │ │ ├── skills.rs │ │ ├── statusbar.rs │ │ ├── tray.rs │ │ └── window.rs │ ├── tauri.conf.json │ └── tauri.ios.conf.json └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintrc.json ================================================ { "root": true, "extends": ["next/core-web-vitals", "next/typescript"], "rules": { "react-hooks/exhaustive-deps": "off", "@typescript-eslint/no-explicit-any": "off" }, "ignorePatterns": [ "docs/**" ] } ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: 🐞 提交 Bug title: '[bug] ' description: 详细的描述一个 Bug labels: ['type: bug'] body: - type: markdown attributes: value: | ## 首先请阅读 1. 请先搜索 [note-gen/issues](https://github.com/codexu/note-gen/issues) 中是否已存在此问题。 2. 尝试下载最新版本的 NoteGen 并测试是否还存在此问题。 3. 请确保这是 App 的问题,而不是 AI 或代理等问题。 4. 请按照提交要求详细的描述 Bug,提供全面的信息。 5. 请在社区内友善发言。 - type: textarea id: description attributes: label: 详细描述这个 Bug description: 请详细的描述这个 Bug,包括重现步骤、预期行为和实际行为,如果可以建议附带截图或视频。 placeholder: Bug description validations: required: true - type: input id: version attributes: label: NoteGen 版本 placeholder: 请填写你当前使用的 NoteGen 版本。 validations: required: true - type: dropdown id: os attributes: label: 操作系统 multiple: true options: - Windows - macOS - Linux - Android - iOS validations: required: true - type: textarea id: log attributes: label: 报错日志 description: 可以通过右键呼出开发者工具,将报错信息粘贴在此处。 placeholder: Bug logs ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ contact_links: - name: 💬 讨论问题 url: https://github.com/codexu/note-gen/discussions about: 提出问题并与其他 NoteGen 用户或维护者交谈 ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: 💡 改进建议 title: '[feat] ' description: 你有什么好的灵感? labels: ['type: feat'] body: - type: textarea id: problem attributes: label: 描述你的建议 description: 清楚的描述这个建议可以解决什么问题 validations: required: true ================================================ FILE: .github/workflows/release.yml ================================================ name: 'publish' on: push: branches: - release jobs: build-android: outputs: appVersion: ${{ steps.get_version.outputs.version }} runs-on: ubuntu-latest permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: lts/* cache: 'pnpm' - name: Install Rust stable uses: dtolnay/rust-toolchain@stable with: targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android - name: Setup Android SDK uses: android-actions/setup-android@v3 - name: Install Android NDK run: | echo "y" | sdkmanager "ndk;29.0.14206865" echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865" >> $GITHUB_ENV echo "NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865" >> $GITHUB_ENV - name: Cache Rust dependencies uses: actions/cache@v4 with: path: | ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db src-tauri/target key: ${{ runner.os }}-cargo-android-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-android- - name: Install frontend dependencies run: pnpm install - name: Build frontend run: pnpm build - name: Setup NDK toolchain run: | export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin ln -sf llvm-ranlib $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ranlib || true - name: Initialize and Build Android run: | export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin # Initialize Android project if not exists if [ ! -d "src-tauri/gen/android" ]; then echo "📱 Initializing Android project..." pnpm tauri android init else echo "✅ Android project already initialized" fi # Verify initialization if [ ! -d "src-tauri/gen/android" ]; then echo "❌ Android initialization failed" exit 1 fi # Set custom Android icon echo "🎨 Setting custom Android icon..." ICON_SOURCE="public/app-ios-icon.png" MIPMAP_DIRS=( "src-tauri/gen/android/app/src/main/res/mipmap-mdpi" "src-tauri/gen/android/app/src/main/res/mipmap-hdpi" "src-tauri/gen/android/app/src/main/res/mipmap-xhdpi" "src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi" "src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi" ) # Install ImageMagick for icon conversion sudo apt-get update && sudo apt-get install -y imagemagick # Generate different sizes convert "$ICON_SOURCE" -resize 48x48 "${MIPMAP_DIRS[0]}/ic_launcher.png" convert "$ICON_SOURCE" -resize 72x72 "${MIPMAP_DIRS[1]}/ic_launcher.png" convert "$ICON_SOURCE" -resize 96x96 "${MIPMAP_DIRS[2]}/ic_launcher.png" convert "$ICON_SOURCE" -resize 144x144 "${MIPMAP_DIRS[3]}/ic_launcher.png" convert "$ICON_SOURCE" -resize 192x192 "${MIPMAP_DIRS[4]}/ic_launcher.png" echo "✅ Android icon set successfully" echo "🔨 Building Android APK and AAB..." pnpm tauri android build --apk --aab - name: Decode keystore env: ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} run: | echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > src-tauri/android-release.keystore ls -la src-tauri/android-release.keystore - name: Get version id: get_version run: | VERSION=$(grep -o '"version": *"[^"]*"' src-tauri/tauri.conf.json | head -1 | sed 's/"version": *"\(.*\)"/\1/') echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - name: Sign and Rename APK env: ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} run: | cd src-tauri APK_PATH="gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk" VERSION="${{ steps.get_version.outputs.version }}" SIGNED_APK="gen/android/app/build/outputs/apk/universal/release/NoteGen_${VERSION}_android-universal.apk" if [ ! -f "$APK_PATH" ]; then echo "❌ APK file not found at $APK_PATH" ls -la gen/android/app/build/outputs/apk/universal/release/ || true exit 1 fi echo "📝 Signing APK with apksigner (V1 + V2 signatures)..." $ANDROID_HOME/build-tools/$(ls $ANDROID_HOME/build-tools | tail -n 1)/apksigner sign \ --ks android-release.keystore \ --ks-key-alias note-gen \ --ks-pass pass:"$ANDROID_KEYSTORE_PASSWORD" \ --key-pass pass:"$ANDROID_KEY_PASSWORD" \ --out "$SIGNED_APK" \ "$APK_PATH" echo "✅ APK signed successfully" # Verify signature echo "🔍 Verifying APK signature..." $ANDROID_HOME/build-tools/$(ls $ANDROID_HOME/build-tools | tail -n 1)/apksigner verify --verbose "$SIGNED_APK" # Show file info ls -lh "$SIGNED_APK" - name: Rename AAB run: | cd src-tauri VERSION="${{ steps.get_version.outputs.version }}" AAB_PATH="gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab" RENAMED_AAB="gen/android/app/build/outputs/bundle/universalRelease/NoteGen_${VERSION}_android-universal.aab" if [ -f "$AAB_PATH" ]; then mv "$AAB_PATH" "$RENAMED_AAB" echo "✅ AAB renamed to: $RENAMED_AAB" ls -lh "$RENAMED_AAB" fi - name: Upload APK as artifact uses: actions/upload-artifact@v4 with: name: android-apk path: src-tauri/gen/android/app/build/outputs/apk/universal/release/NoteGen_*.apk if-no-files-found: error - name: Upload AAB as artifact uses: actions/upload-artifact@v4 with: name: android-aab path: src-tauri/gen/android/app/build/outputs/bundle/universalRelease/NoteGen_*.aab if-no-files-found: warn - name: Upload to Release uses: softprops/action-gh-release@v1 with: tag_name: note-gen-v${{ steps.get_version.outputs.version }} files: | src-tauri/gen/android/app/build/outputs/apk/universal/release/NoteGen_*.apk src-tauri/gen/android/app/build/outputs/bundle/universalRelease/NoteGen_*.aab draft: false prerelease: false - name: Cleanup keystore if: always() run: | rm -f src-tauri/android-release.keystore upgradeLink-upload-android: needs: build-android permissions: contents: write runs-on: ubuntu-latest steps: - name: Send Android APK to UpgradeLink uses: toolsetlink/upgradelink-action@3.0.2 with: access_key: ${{ secrets.UPGRADE_LINK_ACCESS_KEY }} access_secret: ${{ secrets.UPGRADE_LINK_ACCESS_SECRET }} config: | { "app_type": "file", "request": { "app_key": "${{ secrets.UPGRADE_LINK_ANDROID_APP_KEY }}", "version": "${{ needs.build-android.outputs.appVersion }}", "url": "https://github.com/${{ github.repository }}/releases/download/note-gen-v${{ needs.build-android.outputs.appVersion }}/NoteGen_${{ needs.build-android.outputs.appVersion }}_android-universal.apk", "prompt_upgrade_content": "新版本已发布,包含重要功能更新和 bug 修复" } } publish-tauri: outputs: appVersion: ${{ steps.set_output.outputs.appVersion }} permissions: contents: write strategy: fail-fast: false matrix: include: - platform: 'macos-latest' args: '--target aarch64-apple-darwin' - platform: 'macos-latest' args: '--target x86_64-apple-darwin' - platform: 'ubuntu-24.04' args: '--bundles deb,rpm' - platform: 'windows-latest' args: '' runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: 9 run_install: true - name: setup node uses: actions/setup-node@v4 with: node-version: lts/* cache: 'pnpm' - name: install Rust stable uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - name: install dependencies (ubuntu only) if: matrix.platform == 'ubuntu-24.04' run: | sudo apt-get update sudo apt-get install pkg-config libclang-dev libxcb1-dev libxrandr-dev libdbus-1-dev libpipewire-0.3-dev libwayland-dev libegl-dev libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libgbm-dev libappindicator3-dev librsvg2-dev patchelf - name: install frontend dependencies run: pnpm install - name: Import Apple Certificate if: matrix.platform == 'macos-latest' env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD || 'temporary_keychain_password' }} run: | # Create variables CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db # Import certificate from secrets echo -n "$APPLE_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH # Create temporary keychain security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH security set-keychain-settings -lut 21600 $KEYCHAIN_PATH security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH # Import certificate to keychain security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH security list-keychain -d user -s $KEYCHAIN_PATH # Enable codesigning from a non user interactive shell security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - uses: tauri-apps/tauri-action@v0.5.23 id: tauri-action env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} with: tagName: note-gen-v__VERSION__ releaseName: 'NoteGen v__VERSION__' releaseBody: 'See the assets to download this version and install.' releaseDraft: false prerelease: false args: ${{ matrix.args }} - name: Generate release tag id: save_tag if: matrix.platform == 'ubuntu-24.04' run: | # 调试输出 echo ${{ steps.tauri-action.outputs.appVersion }} # 输出到步骤级 echo "appVersion=${{ steps.tauri-action.outputs.appVersion }}" >> $GITHUB_OUTPUT - name: Set job output id: set_output if: matrix.platform == 'ubuntu-24.04' run: | # 注意:这里引用的是 save_tag 步骤的 tag_name 输出 echo "appVersion=${{ steps.save_tag.outputs.appVersion }}" >> $GITHUB_OUTPUT - name: Cleanup keychain if: matrix.platform == 'macos-latest' && always() run: | KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db security delete-keychain $KEYCHAIN_PATH || true upgradeLink-upload: needs: publish-tauri permissions: contents: write runs-on: ubuntu-latest steps: - name: Send a request to UpgradeLink uses: toolsetlink/upgradelink-action@3.0.2 with: access_key: ${{ secrets.UPGRADE_LINK_ACCESS_KEY }} access_secret: ${{ secrets.UPGRADE_LINK_ACCESS_SECRET }} config: | { "app_type": "tauri", "request": { "app_key": "${{ secrets.UPGRADE_LINK_TAURI_KEY }}", "latest_json_url": "https://github.com/${{ github.repository }}/releases/download/note-gen-v${{ needs.publish-tauri.outputs.appVersion }}/latest.json" } } ================================================ FILE: .gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies node_modules ./dist dist-ssr src-tauri/gen/* !src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/ *.local target/* .claude/* .superpowers/* .agents/* /docs/*/* skills-lock.json /.pnp .pnp.* .yarn/* !.yarn/patches !.yarn/plugins !.yarn/releases !.yarn/versions # testing /coverage *.test.* # next.js /.next/ /out/ # production /build # misc .DS_Store *.pem # Android signing keys *.keystore *.jks android-app.keystore # debug npm-debug.log* yarn-debug.log* yarn-error.log* # env files (can opt-in for committing if needed) .env* # vercel .vercel # typescript *.tsbuildinfo next-env.d.ts docs/.vitepress/dist docs/.vitepress/cache .idea # Exclude all markdown files in root directory except README.md /*.md !README.md # backup files *.backup .backup # worktrees .worktrees ================================================ FILE: .vscode/settings.json ================================================ { "marscode.codeCompletionPro": { "enableCodeCompletionPro": false }, "marscode.enableInlineCommand": false, "i18n-ally.localesPaths": [ "messages", "src/i18n" ] } ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2025 codexu, https://notegen.top/. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: README.md ================================================ # NoteGen ![](https://img.shields.io/badge/free-pricing?logo=free&color=%20%23155EEF&label=pricing&labelColor=%20%23528bff) [![GitHub Repo stars](https://img.shields.io/github/stars/codexu/note-gen)](https://github.com/codexu/note-gen) [![](https://gitcode.com/codexu/note-gen/star/badge.svg)](https://gitcode.com/codexu/note-gen) ![](https://github.com/codexu/note-gen/actions/workflows/release.yml/badge.svg?branch=release) [![Netlify Status](https://api.netlify.com/api/v1/badges/8f7518c3-b627-4277-bc2f-e477960f5dc4/deploy-status)](https://app.netlify.com/projects/note-gen-docs/deploys) ![](https://img.shields.io/github/downloads/codexu/note-gen/total) ![](https://img.shields.io/github/issues-closed/codexu/note-gen)
codexu%2Fnote-gen | Trendshift Featured|HelloGitHub NoteGen - A cross-platform Markdown note-taking application | Product Hunt
## 我正在寻找工作 / Looking For Work 我是一名全栈(侧重前端)开发者,目前正在寻找新的工作机会,欢迎联系我! I am a full-stack (with a focus on front-end) developer, currently looking for new job opportunities. Feel free to contact me! 我希望可以获取一份远程办公的工作,或在北京的公司上班。 I am looking for a remote job or a position in a company based in Beijing. Email: xu461229187@gmail.com ## Guide 🖥️ Official Document: [English](https://notegen.top/en/) | [简体中文](https://notegen.top/cn/) 💬 Join [WeChat/QQ Group](https://github.com/codexu/note-gen/discussions/110), [Discord](https://discord.gg/SXyVZGpbpk), [Telegram](https://t.me/notegen) NoteGen is a cross-platform `Markdown` note-taking application dedicated to using AI to bridge recording and writing, organizing fragmented knowledge into a readable note. ![](https://s2.loli.net/2025/12/22/jlpEP2c6ogwHhIA.png) ## Features - 🚀 Lightweight (25MB), free, no ads. - 🌐 Cross-platform support. - 🆓 Free AI and sync solutions. - 📦 Out-of-the-box RAG support. - 🔌 MCP support for AI tool integration. - 🤖 Intelligent agents for automated note processing. - ✍️ Quick note-taking for fragmented information. - 📝 Native Markdown storage format. ## Download | ![Windows](https://img.shields.io/badge/Windows-0078D4?logo=windows&logoColor=white&style=for-the-badge) | ![macOS](https://img.shields.io/badge/macOS-000000?logo=apple&logoColor=white&style=for-the-badge) | ![Linux](https://img.shields.io/badge/Linux-FCC624?logo=linux&logoColor=black&style=for-the-badge) | ![Android](https://img.shields.io/badge/Android-3DDC84?logo=android&logoColor=white&style=for-the-badge) | ![iOS](https://img.shields.io/badge/iOS-000000?logo=apple&logoColor=white&style=for-the-badge) | | --- | --- | --- | --- | --- | | ✅ beta | ✅ beta | ✅ beta | 🛠️ alpha | 🛠️ alpha | | [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#android) | [TestFlight](https://testflight.apple.com/join/8KjFRTCq) | > [UpgradeLink offers application upgrade and download services](http://upgrade.toolsetlink.com/upgrade/example/tauri-example.html) ## From Recording to Writing Traditional note-taking apps typically don't offer note-taking functionality, but NoteGen makes it easier for you to record scattered knowledge points and avoid disrupting your train of thought while taking notes. NoteGen is divided into three parts: Recording, Notes, and AI Dialogue. They have the following features: - You don't need to consider the order and logic of recording, AI will help you organize the notes into well-organized and coherent ones. - AI Dialogue is a feature that allows you to interact with AI in real-time, helping you to better understand and remember the content you are recording. - The note-taking feature can help you optimize the details of your notes independently. ## Contribute - [Read contribution guide](https://notegen.top/en/docs/contributing) - [Update plans](https://github.com/codexu/note-gen/issues/46) - [Submit bugs or improvement suggestions](https://github.com/codexu/note-gen/issues) - [Discussions](https://github.com/codexu/note-gen/discussions) ## Contributors ## Thanks Special thanks to our technology partners who make NoteGen better: **[SiliconFlow](https://cloud.siliconflow.cn/i/O2ciJeZw)** - Providing free AI model services, powering NoteGen's intelligent features with high-quality AI capabilities. **[UpgradeLink](http://upgrade.toolsetlink.com/upgrade/example/tauri-example.html)** - Providing reliable installation and upgrade services, ensuring seamless software updates for users. --- We also thank other partners for their service support ================================================ FILE: components.json ================================================ { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": true, "tsx": true, "tailwind": { "config": "tailwind.config.ts", "css": "src/app/globals.css", "baseColor": "zinc", "cssVariables": true, "prefix": "" }, "iconLibrary": "lucide", "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "registries": { "@magicui": "https://magicui.design/r/{name}.json" } } ================================================ FILE: messages/en.json ================================================ { "app": { "title": "Note Generator", "description": "Your AI-powered note taking assistant" }, "common": { "save": "Save", "cancel": "Cancel", "delete": "Delete", "edit": "Edit", "create": "Create", "theme": "Theme", "light": "Light", "dark": "Dark", "system": "System", "pin": "Pin", "unpin": "Unpin", "settings": "Settings", "back": "Back", "sync": "Sync", "language": "Language", "confirm": "Confirm", "selectPrompt": "Select Prompt", "prompt": "Prompt", "success": "Success", "error": "Failed", "defaultFileName": "Untitled", "restartToApply": ", please restart the application for the configuration to take effect", "unsaved": "Unsaved", "saving": "Saving...", "close": "Close", "open": "Open", "add": "Add", "remove": "Remove", "search": "Search", "filter": "Filter", "sort": "Sort", "export": "Export", "import": "Import", "refresh": "Refresh", "loading": "Loading...", "all": "All", "today": "Today", "yesterday": "Yesterday", "warning": "Warning", "info": "Info", "configureSync": "Configure Sync" }, "settings": { "defaultModels": { "title": "Default Models" }, "others": "Advanced", "general": { "title": "General Settings", "desc": "Here, you can configure basic application settings, including interface theme, language and other options.", "interface": { "title": "Interface Settings", "theme": { "title": "Theme", "desc": "Choose the application's appearance theme", "options": { "light": "Light", "dark": "Dark", "system": "System" } }, "language": { "title": "Language", "desc": "Choose the application's display language" }, "scale": { "title": "Interface Scale", "desc": "Adjust the overall scale of the application interface", "placeholder": "Select scale ratio" }, "contentTextScale": { "title": "Content Scale", "desc": "Adjust the text size in editor and chat Markdown content" }, "fileManagerTextSize": { "title": "File Manager Text Size", "desc": "Adjust the text size of file and folder lists in the file manager" }, "recordTextSize": { "title": "Record Text Size", "desc": "Adjust the text size of record items in the record list" }, "customCss": { "title": "Custom CSS", "desc": "Add custom CSS styles to override the application's default styles", "button": "Edit CSS", "dialogTitle": "Custom CSS", "dialogDesc": "Enter custom CSS code below to override the application's default styles. Click save to apply changes.", "placeholder": "Enter custom CSS code here", "save": "Save", "cancel": "Cancel" }, "customTheme": { "title": "Custom Theme Colors", "desc": "Customize application theme colors including background, foreground, border, etc.", "button": "Edit Colors", "dialogTitle": "Custom Theme Colors", "dialogDesc": "Configure custom theme colors. Color changes are saved and applied in real-time, overriding both light and dark themes.", "close": "Close", "reset": "Reset All", "tabs": { "custom": "Custom", "presets": "Presets", "importExport": "Import/Export" }, "export": { "title": "Export Color Scheme", "button": "Generate Export Code", "placeholder": "Click the generate button to export current color scheme as code" }, "import": { "title": "Import Color Scheme", "button": "Import Scheme", "placeholder": "Paste the JSON code of the color scheme" }, "colors": { "background": "Background", "foreground": "Foreground", "card": "Card Background", "cardForeground": "Card Foreground", "primary": "Primary", "primaryForeground": "Primary Foreground", "secondary": "Secondary", "secondaryForeground": "Secondary Foreground", "third": "Third", "thirdForeground": "Third Foreground", "muted": "Muted", "mutedForeground": "Muted Foreground", "accent": "Accent", "accentForeground": "Accent Foreground", "border": "Border", "shadow": "Shadow" }, "presets": { "apply": "Apply", "reset": { "name": "Reset to Default" }, "default": { "name": "Default White" }, "ocean": { "name": "Ocean Blue" }, "forest": { "name": "Forest Green" }, "sunset": { "name": "Sunset Red" }, "lavender": { "name": "Lavender Purple" }, "midnight": { "name": "Midnight Dark" }, "deepSea": { "name": "Deep Sea" }, "darkForest": { "name": "Dark Forest" }, "darkViolet": { "name": "Dark Violet" }, "coralWarm": { "name": "Coral Warm" }, "slateGray": { "name": "Slate Gray" }, "darkGold": { "name": "Dark Gold" }, "beigeWarm": { "name": "Beige Warm" }, "beigeDark": { "name": "Beige Dark" } } }, "tray": { "enabled": { "title": "Enable Tray", "desc": "Choose to minimize to tray or close app when window is closed" } } }, "tools": { "title": "Tool Settings", "desc": "Configure display and sorting of various toolbar buttons", "chatToolbar": { "title": "Chat Toolbar", "desc": "Customize the display order and visibility of chat toolbar buttons", "button": "Configure", "dialogTitle": "Configure Chat Toolbar", "dialogDesc": "Drag tools to adjust order, use switches to show or hide", "groups": { "pc": "PC", "mobile": "Mobile", "bottom": "Bottom Toolbar", "topLeft": "Top Toolbar - Left", "topRight": "Top Toolbar - Right" } }, "recordToolbar": { "title": "Record Toolbar", "desc": "Customize the display order and visibility of record toolbar buttons", "button": "Configure", "dialogTitle": "Configure Record Toolbar", "dialogDesc": "Drag tools to adjust order, use switches to show or hide" } } }, "rag": { "title": "Knowledge Base", "desc": "Here, you can configure knowledge base related settings, knowledge base based on RAG technology, through embedding models to convert text into vectors, then through vector search to achieve intelligent search and intelligent answers.", "settingsTitle": "Parameter Settings", "settingsDesc": "By adjusting parameters, you can more precisely control the retrieval effect of the knowledge base.", "deleteVectorConfirm": "Are you sure you want to clear the knowledge base?", "deleteVectorSuccess": "Knowledge base cleared successfully", "enable": "Enable knowledge base search", "enableDesc": "Enabling it will make AI search your notes when answering questions, providing more accurate answers.", "chunkSize": "Chunk size", "chunkSizeDesc": "The maximum number of characters for text chunking. Larger chunks may contain more context, but will increase vector calculation complexity.", "chunkOverlap": "Chunk overlap", "chunkOverlapDesc": "The number of overlapping characters between text chunks. Larger overlaps can maintain context continuity.", "resultCount": "Result count", "resultCountDesc": "The number of related documents returned when searching. The more documents, the more information provided, but may also introduce noise.", "similarityThreshold": "Similarity threshold", "similarityThresholdDesc": "The minimum similarity threshold between documents and queries. Only documents exceeding this threshold will be returned. The value range is 0.0-1.0, the higher the threshold, the stricter the requirement.", "resetToDefaults": "Reset to defaults", "deleteVector": "Clear knowledge base", "topPDesc": "Top P parameter controls the diversity of text generated by the model. Smaller values make the output more deterministic, while larger values make it more diverse." }, "mcp": { "title": "MCP", "desc": "Model Context Protocol allows AI to call external tools and access resources, extending AI capabilities.", "enableTitle": "Enable MCP", "enableDesc": "When enabled, AI can call tools provided by configured MCP servers.", "servers": "Server List", "serversDesc": "Manage MCP server configurations. Each server can provide different tools and resources.", "addServer": "Add Server", "addFirstServer": "Add First Server", "editServer": "Edit Server", "serverName": "Server Name", "serverNamePlaceholder": "e.g., File System Server", "serverEnabled": "Enable Server", "serverEnabledDesc": "When enabled, this server will automatically connect and provide tools.", "serverType": "Server Type", "stdio": "Local Command", "http": "HTTP Service", "command": "Command", "args": "Arguments", "argsDesc": "Command line arguments, separated by spaces", "env": "Environment Variables", "envDesc": "Environment variable configuration in JSON format", "url": "Service URL", "headers": "Request Headers", "headersDesc": "HTTP request headers in JSON format", "testConnection": "Test Connection", "test": "Test", "testSuccess": "Connection test successful", "testFailed": "Connection test failed", "connected": "Connected", "connecting": "Connecting", "disconnected": "Disconnected", "error": "Error", "tools": "Tools", "noServers": "MCP service not enabled", "noServersFound": "No matching servers found", "serverAdded": "Server added successfully", "serverUpdated": "Server updated successfully", "serverDeleted": "Server deleted successfully", "deleteServerTitle": "Delete Server", "deleteServerDesc": "Are you sure you want to delete this server? This action cannot be undone.", "nameRequired": "Please enter server name", "commandRequired": "Please enter command", "urlRequired": "Please enter service URL", "toolBrowser": "Tool Browser", "searchTools": "Search tools...", "noToolsFound": "No tools found", "parameters": "Parameters", "testAll": "Test All Connections", "testAllCompleted": "All connection tests completed", "testAllFailed": "Connection test failed", "save": "Save", "cancel": "Cancel", "delete": "Delete", "importJson": "Import JSON", "jsonImportTitle": "Import Server Configuration from JSON", "jsonImportDesc": "Paste the mcpServers configuration format for MCP servers", "jsonInput": "JSON Configuration", "jsonInputHelp": "Supports mcpServers format, automatically uses server name as key", "jsonRequired": "Please enter JSON configuration", "jsonEmpty": "JSON configuration cannot be empty", "jsonInvalidJson": "Invalid JSON format", "jsonInvalidFormat": "Invalid configuration format, must contain name and type fields", "jsonInvalidType": "Server type must be stdio or http", "jsonMissingCommand": "stdio type server must specify command", "jsonMissingUrl": "http type server must specify url", "jsonImportSuccess": "Successfully imported {count} server(s)", "jsonImportSkipped": "Skipped {count} existing server(s)", "jsonImportNoServers": "No servers were imported", "import": "Import", "mobileHttpOnlyTitle": "Desktop-only local command MCP", "mobileHttpOnlyDesc": "Local command MCP servers are only supported on desktop. Mobile currently supports HTTP MCP only.", "runtimeEnvironment": "Runtime Environment", "runtimeEnvironmentDesc": "Check whether the required local runtime is available before testing the MCP server.", "checkEnvironment": "Check Environment", "recheckEnvironment": "Re-check Environment", "runtimeCheckFailed": "Environment check failed", "detectedLauncher": "Detected launcher", "runtimeInstalled": "Installed", "runtimeMissing": "Missing", "runtimeVersion": "Version", "runtimeInstalledSummary": "{installed}/{total} installed", "showRuntimeDetails": "Show runtime details", "hideRuntimeDetails": "Hide runtime details", "runtimeNotChecked": "This runtime has not been checked yet.", "runtimeCurrentUserScope": "Recommended command targets the current user environment when supported.", "runtimeManualOnly": "Automatic install is not available for this runtime on the current platform. Please install it manually and run the check again.", "installRuntime": "Install Runtime", "runtimeInstallTitle": "Install runtime", "runtimeInstallDesc": "NoteGen will run the following install command after confirmation.", "runtimeInstallPreparing": "Preparing install", "runtimeInstallRunning": "Installing", "runtimeInstallCompleted": "Install completed", "runtimeInstallCancelled": "Cancelled", "runtimeInstallFailedState": "Install failed", "runtimeInstallLogs": "Install logs", "runtimeInstallWaitingLogs": "Waiting for install output...", "runtimeInstallClose": "Close", "runtimeInstallCancel": "Stop install", "runtimeInstallCancelledByUser": "Cancellation requested by user.", "runtimeInstallCancelFailed": "Failed to stop install", "runtimeInstallSuccess": "Runtime installation completed", "runtimeInstallFailed": "Runtime installation failed", "runtimeNoGuidedSupport": "No guided runtime assistance is available for this command yet." }, "skills": { "title": "Skills", "desc": "Skills are reusable AI capability packages that allow AI assistants to automatically apply specific behavioral patterns based on tasks.", "enable": "Enable Skills", "enableDesc": "When enabled, AI can use configured Skills", "autoMatch": "Auto-match Skills", "autoMatchDesc": "Automatically select appropriate Skills based on user input", "project": "Workspace Skills", "global": "Global Skills", "globalPath": "Global Skills Storage Location", "openInFileManager": "Open in File Manager", "createSkill": "Create Skill", "editSkill": "Edit Skill", "deleteSkill": "Delete Skill", "exportSkill": "Export Skill", "importSkill": "Import Skill", "selectSkillZip": "Select Skill zip file", "importSuccess": "Import successful", "importError": "Import failed", "imported": "imported", "importing": "Importing...", "skillName": "Skill Name", "skillDescription": "Description", "skillVersion": "Version", "skillAuthor": "Author", "allowedTools": "Allowed Tools", "userInvocable": "Show in Slash Menu", "instructions": "Instructions", "instructionsPlaceholder": "Enter detailed instructions for AI...", "importHelp": "Support importing Skills in zip format. The zip file must contain a SKILL.md file.", "metadata": "Metadata", "content": "Instructions", "noSkills": "No Skills yet", "noSkillsDesc": "Create or import Skills to get started", "noSkillsGlobal": "No global Skills yet", "noSkillsGlobalDesc": "Create or import Skills to use across all projects", "emptyWorkspace": "No Skills in workspace", "emptyWorkspaceDesc": "Create SKILL.md files in the skills folder to add Skills", "basicSettings": "Basic Settings", "installedGlobalSkills": "Installed Global Skills", "nameRequired": "Please enter Skill name", "descriptionRequired": "Please enter description", "namePlaceholder": "note-organizer", "versionPlaceholder": "1.0.0", "descriptionPlaceholder": "Automatically organize and optimize note structure...", "authorPlaceholder": "Your Name", "descriptionHelp": "Used for AI matching, describes the Skill's functionality and use cases", "allowedToolsHelp": "These tools can be used without user confirmation", "userInvocableHelp": "Users can manually trigger via /skill-name", "instructionsHelp": "Detailed instructions for AI, supports Markdown format", "deleteSkillTitle": "Delete Skill", "deleteSkillDesc": "Are you sure you want to delete this Skill? This action cannot be undone.", "skillDeleted": "Skill deleted successfully" }, "editor": { "title": "Editor Settings", "interfaceSettings": "Interface Settings", "desc": "Here, you can customize the editor, creating a writing experience tailored to your needs.", "centeredContent": "Centered Content", "centeredContentDesc": "When enabled, editor content will be centered with margins on both sides.", "outlineEnable": "Default outline enabled", "outlineEnableDesc": "Enabling it will make the outline visible by default.", "outlinePosition": "Outline position", "outlinePositionDesc": "Set outline position.", "outlinePositionOptions": { "left": "Left", "right": "Right" }, "showUndoRedo": "Undo/Redo buttons", "showUndoRedoDesc": "Show undo and redo buttons in the editor tab bar.", "completion": { "title": "Auto Completion", "model": { "title": "Quick Completion Model", "desc": "Select the model for AI inline completion in editor" } }, "commit": { "title": "Auto Commit Message", "model": { "title": "Commit Model", "desc": "For automatically generating Git commit messages based on file changes" } }, "mermaid": { "title": "Diagram", "rendering": "Rendering...", "renderError": "Render error", "clickToEdit": "Click to edit source", "clickToAdd": "Click to add diagram", "placeholder": "Enter Mermaid diagram code...", "preview": "Preview", "done": "Done", "diagramTypes": { "flowchart": "Flowchart", "sequence": "Sequence", "classDiagram": "Class Diagram", "stateDiagram": "State Diagram", "er": "ER Diagram", "gantt": "Gantt", "pie": "Pie Chart", "journey": "Journey" }, "templates": { "flowchart": "graph TD\n A[Start] --> B[Process]\n B --> C[End]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Hello\n Bob-->>Alice: Reply", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title Project Plan\n dateFormat YYYY-MM-DD\n section Phase 1\n Task1 :a1, 2024-01-01, 30d\n section Phase 2\n Task2 :after a1, 20d", "pie": "pie title Resource Allocation\n \"CPU\" : 45\n \"Memory\" : 30\n \"Storage\" : 25", "journey": "journey\n title My Daily Work\n section Morning\n Commute : 7:00, 5\n Work : 9:00, 8" } } }, "record": { "title": "Record Settings", "desc": "Configure record-related settings here, including record description and toolbar configuration.", "model": { "title": "Model Settings", "markDesc": { "title": "Record Description", "desc": "For processing OCR-recognized records and generating record descriptions" } }, "toolbar": { "title": "Toolbar Settings", "recordToolbar": { "title": "Record Toolbar", "desc": "Customize the visibility and order of record toolbar buttons", "button": "Configure", "text": { "desc": "Record text content" }, "recording": { "desc": "Voice recording function" }, "scan": { "desc": "Scan and recognize text from images" }, "image": { "desc": "Upload images to notes" }, "link": { "desc": "Record web links" }, "file": { "desc": "Upload files to notes" }, "todo": { "desc": "Create todo items" } } } }, "uploadStore": { "uploadConfirm": "Upload configuration please ensure the sync repository is private, otherwise the data will be leaked!", "downloadConfirm": "Download configuration will cover local configuration and restart to take effect!", "uploadSuccess": "Upload success", "downloadSuccess": "Download success", "upload": "Upload", "download": "Download" }, "about": { "title": "About", "desc": "A note-taking assistant focused on record and writing.", "version": "NoteGen v{version}", "checkReleases": "Check Release History", "language": "Language", "checkUpdate": "Check for Updates", "checkError": "Failed to check for updates", "updateAvailable": "Update to new version", "updateDownloading": "Updating {downloaded} / {contentLength}", "updateInstalled": "Restart app", "noUpdate": "Current version is the latest", "ignoreVersion": "Ignore this version", "ignoreVersionSuccess": "This version update has been ignored", "items": { "home": { "title": "Home", "buttonName": "Open", "desc": "Visit the website to learn more about NoteGen." }, "guide": { "title": "Guide", "buttonName": "Open", "desc": "View configuration guide, learn how to configure models, sync, etc. information." }, "github": { "title": "GitHub", "buttonName": "View", "desc": "If NoteGen helps you, please give a star to encourage!" }, "releases": { "title": "Update Log", "buttonName": "View", "desc": "View update log, learn more about NoteGen's updates." }, "issues": { "title": "Issue Feedback", "buttonName": "Feedback", "desc": "If you find a bug in NoteGen, please feedback here." }, "discussions": { "title": "Discussions", "buttonName": "Discuss", "desc": "If you want to discuss with the author or other users, you can join the group discussion." } } }, "memories": { "title": "Memory Management", "desc": "AI long-term memory feature that lets AI remember your writing preferences, experiences, and note-taking habits.", "stats": { "total": "Total Memories", "preferences": "Preferences", "memories": "Memories" }, "form": { "title": "Add New Memory", "categoryDescription": "Memories are divided into two types:", "preferenceDescription": "Preferences: Settings like language, format, style - always loaded in conversations", "memoryDescription": "Memories: Facts, experiences, expertise - intelligently matched based on conversation context", "contentLabel": "Memory Content", "contentPlaceholder": "e.g., I prefer Chinese responses, I'm a React expert...", "categoryLabel": "Type", "preferenceLabel": "Preference", "memoryLabel": "Memory", "preferenceDesc": "Language, format, style, etc.", "memoryDesc": "Facts, experience, expertise, etc.", "save": "Save Memory", "saving": "Saving..." }, "listTitle": "My Memories", "addMemory": "Add Memory", "empty": "No memories yet, add your first memory!", "emptyHint": "You can add memories manually, or use phrases like \"please remember\" or \"remember this\" in conversations to let AI automatically create memories.", "preference": "Preference", "memory": "Memory", "replaced": "Replaced", "accessCount": "Accessed {count} times", "tabs": { "all": "All", "preference": "Preferences", "memory": "Memories" }, "success": "Success", "saved": "Memory saved", "updated": "Memory updated (similar memory replaced)", "deleted": "Memory deleted", "cleared": "All memories cleared", "found": "Found {count} memories", "error": "Error", "errorEmpty": "Please enter memory content", "errorSave": "Failed to save", "errorDelete": "Failed to delete", "errorList": "Failed to get memory list", "errorEmbedding": "Failed to generate embedding, please check embedding model configuration", "errorClear": "Failed to clear" }, "defaultModel": { "title": "Default Model", "desc": "Here, you can use different models for different scenes, to improve efficiency and reduce costs.", "tooltip": "Use main model", "noModel": "Do not use", "placeholder": "Please select or search for models", "main": "Main model", "options": { "primaryModel": { "title": "Main model", "desc": "As the main model for all scenarios, this model is used if other dialogue models do not select the default model." }, "markDesc": { "title": "Record Description", "desc": "Used to process records after OCR recognition, generating record descriptions." }, "placeholder": { "title": "AI Suggestion", "desc": "AI suggestion prompt for generating placeholder content in the record page AI conversation." }, "completion": { "title": "Fast Completion", "desc": "AI inline completion for Markdown editor, similar to GitHub Copilot, quickly generates continuation content." }, "commit": { "title": "Auto Generate Commit Message", "desc": "Used to automatically generate Git commit messages, intelligently generating descriptive commit messages based on file content changes." }, "embedding": { "title": "Embedding Model", "desc": "Used for text embedding and vectorization scenarios." }, "reranking": { "title": "Reranking Model", "desc": "Used for reordering and optimizing search results." }, "condense": { "title": "Condense Model", "desc": "Used to compress historical conversation content to save token usage" } }, "mainModel": "Main Model" }, "audio": { "title": "Audio Settings", "desc": "Here, you can configure audio settings, including text-to-speech (TTS) and speech-to-text (STT) functions.", "mode": { "title": "Mode", "auto": "Auto (Recommended)", "local": "Local only", "model": "Model only" }, "tts": { "title": "Text-to-Speech (TTS)", "desc": "Configure read aloud functionality to provide voice playback for chat content.", "modeDesc": "Prefer browser and system voices by default, and use a model only when needed for a better experience.", "model": { "title": "TTS Model", "desc": "Optional. Configure a model to enhance auto mode or to power model-only mode." }, "speed": { "title": "Speech Rate", "desc": "Adjust the playback speed of the voice, ranging from 0.5x to 2x speed, with 1x being the normal speed." } }, "stt": { "title": "Speech-to-Text (STT)", "desc": "Configure voice recognition to convert speech to text records.", "modeDesc": "Prefer native browser recognition by default, and fall back to a model when local support is unavailable.", "model": { "title": "STT Model", "desc": "Optional. Configure a model for auto fallback or for model-only mode." } } }, "readAloud": { "title": "Read Aloud", "desc": "Configure read aloud behavior. System voices are preferred by default, with model speech as an enhancement.", "options": { "mode": { "title": "Mode", "desc": "Auto mode prefers system voices and only tries a model when local speech is unavailable.", "auto": "Auto (Recommended)", "local": "Local only", "model": "Model only" }, "audioModel": { "title": "Read Aloud Model", "desc": "Optional. Configure a model to enhance auto mode or to power model-only mode." }, "speed": { "title": "Speed", "desc": "Adjust read aloud speed from 0.5x to 2x, with 1x as the default rate." } } }, "prompt": { "title": "Prompt", "promptTitle": "Prompt Title", "desc": "Here, you can add and manage prompts, helping AI better understand your needs.", "addPrompt": "Add Prompt", "selectPrompt": "Select Prompt", "configPrompt": "Configure Prompt", "noContent": "No content", "addPromptDesc": "Please enter the prompt name and content, helping AI better understand your needs.", "promptTitlePlaceholder": "Please enter the prompt name", "promptContentPlaceholder": "Please enter the prompt content", "promptContent": "Prompt Content", "optimizePrompt": "Optimize Prompt", "optimizing": "Optimizing...", "optimizeSuccess": "Prompt optimized successfully", "optimizeFailed": "Failed to optimize prompt, please try again later", "noContentToOptimize": "Please enter prompt content first" }, "sync": { "title": "Sync", "desc": "Here, you can configure the synchronization repository, which can help you synchronize records, markdown files, system configurations and other information.", "selectPlatform": "Select Sync Platform", "platformSettings": "Select Platform", "settings": "Sync Settings", "platformDesc": "Configure Token and repository information to enable sync", "moreSettings": "More Settings", "repoStatus": "Repository Status", "syncRepo": "Sync Repository", "syncRepoDesc": "Sync markdown files in writing", "imageRepo": "Image Repository", "imageRepoDesc": "Sync your images to repository, using jsdelivr for acceleration", "status": { "connected": "Connected", "disconnected": "Disconnected", "failed": "Connection Failed", "unconfigured": "Not Configured" }, "uploadRecords": "Upload Records & Config", "downloadConfig": "Download Records & Config", "cloudSync": "Records & Config Sync", "localBackupAll": "Local Backup (All)", "private": "Private", "public": "Public", "createdAt": "Created {time}", "updatedAt": "Last updated {time}", "newToken": "Create Access Token", "newTokenDesc": "When creating a new token, please make sure to check the repo permission, and after configuration, it will automatically create a file repository (private) and an image repository.", "giteeTokenDesc": "Gitee personal access token is used for data synchronization. It needs repository read and write permissions. After configuration, it will automatically create a file repository (private) and an image repository.", "imageRepoSetting": "Enable Image Hosting", "imageRepoSettingDesc": "You have already configured an image repository, you can choose to use the image repository or use local storage.", "jsdelivrSetting": "jsDelivr", "autoSyncDesc": "When enabled, the editor will automatically sync to GitHub 10 seconds after input stops", "giteeAutoSyncDesc": "When enabled, the editor will automatically sync to Gitee 10 seconds after input stops", "customSyncRepo": "Custom Sync Repository Name", "customSyncRepoDesc": "Leave empty to use default repository name", "customImageRepo": "Custom Image Repository Name", "customImageRepoDesc": "Leave empty to use default repository name", "backupMethod": "Backup Method", "backupMethodDesc": "After setting as the primary backup method, all sync-related functions in writing will use the current backup method (except for image hosting)", "createRepo": "Create Repository", "creating": "Creating", "checkRepo": "Check Repository", "checking": "Checking", "enterToken": "Please enter Access Token", "enterTokenHint": "Please enter Access Token first to check repository status", "defaultRepoName": "Default: {name}", "gitlabInstanceType": "GitLab Instance Type", "gitlabInstanceTypeDesc": "Select the type of GitLab instance to connect to", "gitlabInstanceTypePlaceholder": "Select GitLab Instance Type", "gitlabInstanceTypeOptions": { "selfHosted": "Self-hosted Instance", "selfHostedDesc": "Enter your self-hosted GitLab server address (e.g., https://gitlab.example.com)" }, "gitlabAccessTokenDesc": "Create a personal access token at {instanceDisplayName}, requires api permission", "giteaInstanceType": "Gitea Instance Type", "giteaInstanceTypeDesc": "Select the type of Gitea instance to connect to", "giteaInstanceTypePlaceholder": "Select Gitea Instance Type", "giteaInstanceTypeOptions": { "selfHosted": "Self-hosted Instance", "selfHostedDesc": "Enter your self-hosted Gitea server address (e.g., https://gitea.example.com)" }, "giteaAccessTokenDesc": "Create a personal access token at {instanceDisplayName}, requires full repository permission", "s3": { "title": "S3 Sync", "description": "Sync your notes using S3-compatible storage", "status": "Connection Status", "connected": "Connected", "connecting": "Connecting", "disconnected": "Disconnected", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "Please enter Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "Please enter Secret Access Key", "region": "Region", "bucket": "Bucket", "bucketPlaceholder": "Please enter bucket name", "endpoint": "Endpoint", "pathPrefix": "Path Prefix", "pathPrefixPlaceholder": "Please enter path prefix", "pathPrefixDesc": "Used to differentiate files between different users, similar to repository name", "customDomain": "Custom Domain", "testConnection": "Test Connection", "testing": "Testing", "saveConfig": "Save Config", "saving": "Saving" }, "webdav": { "title": "WebDAV Sync", "description": "Sync your notes using WebDAV protocol", "status": "Connection Status", "connected": "Connected", "connecting": "Connecting", "disconnected": "Disconnected", "url": "Server URL", "urlPlaceholder": "Please enter WebDAV server URL", "urlDesc": "Supports Synology, QNAP, Nextcloud and other WebDAV services", "username": "Username", "usernamePlaceholder": "Please enter username", "password": "Password", "passwordPlaceholder": "Please enter password", "pathPrefix": "Path Prefix", "pathPrefixPlaceholder": "Please enter path prefix", "pathPrefixDesc": "Used to differentiate files between different users", "testConnection": "Test Connection", "testing": "Testing", "saveConfig": "Save Config", "saving": "Saving" }, "autoSync": "Auto Sync", "autoSyncOptions": { "placeholder": "Select auto sync time", "disabled": "Disabled", "2s": "2 seconds", "3s": "3 seconds", "5s": "5 seconds", "10s": "10 seconds", "20s": "20 seconds", "30s": "30 seconds", "1m": "1 minute", "2m": "2 minutes" }, "autoPullOnOpen": "Auto pull when opening files", "autoPullOnOpenDesc": "When opening a file, automatically pull remote version if newer", "autoPullOnSwitch": "Auto pull when switching files", "autoPullOnSwitchDesc": "When switching to another file, automatically pull remote version if newer", "exclusions": { "title": "Sync Exclusion Configuration", "desc": "The following settings will not be synced across devices as they are device-specific", "workspacePath": "Workspace Path", "workspaceHistory": "Workspace History", "assetsPath": "Assets Path", "uiScale": "UI Scale", "contentTextScale": "Content Text Scale", "customCss": "Custom CSS", "reason": "These settings may differ across devices, excluding them from sync prevents path errors and other issues" }, "settingsSync": { "uploadSuccess": "Settings uploaded successfully", "uploadFailed": "Failed to upload settings", "downloadSuccess": "Settings downloaded successfully", "downloadFailed": "Failed to download settings", "autoSync": "Settings will be automatically synced during upload/download (excluding device-specific settings like workspace path)" }, "jsdelivrSettingDesc": "Use jsdelivr to accelerate image access." }, "imageHosting": { "title": "Image Hosting", "desc": "Here, you can configure image hosting services for storing and managing your images.", "type": "Select Platform", "typeDesc": "Select image hosting service provider", "customRepoName": "Custom Repository Name", "customRepoNameDesc": "Leave empty to use default repository name", "isPrimaryBackup": "Current {type} primary image hosting method", "setPrimaryBackup": "Set as Primary Image Hosting", "smms": { "token": { "desc": "Please create and input SM.MS Token.", "createToken": "Create Token" }, "disk": "Disk Usage", "error": "Failed to get, please check network or Token is correct." }, "picgo": { "desc": "PicGo server URL", "ok": "Service is running, please ensure PicGo image hosting is configured.", "error": "Service is not running, please ensure PicGo (v2.2.0+) is running, otherwise image upload will fail." }, "github": { "title": "GitHub Image Hosting", "description": "Use GitHub repository as image storage service", "repoStatus": "Repository Status", "repoExists": "Repository Exists", "repoNotExists": "Repository Not Found", "checking": "Checking", "creating": "Creating", "manualCreateTitle": "Manual Repository Creation Required", "manualCreateDesc": "Please follow these steps to create the image hosting repository:", "createSteps": { "step1": "Visit GitHub and log in to your account", "step2": "Click the \"+\" button in the top right corner, select \"New repository\"", "step3": "Set repository name to:", "step4": "Optionally set as private repository (recommended)", "step5": "Click \"Create repository\" to complete creation", "step6": "After creation, click the \"Recheck\" button below" }, "createNewRepo": "Create New Repository", "recheckRepo": "Recheck", "recheckingRepo": "Checking...", "createRepo": "Create Repository", "creatingRepo": "Creating..." }, "s3": { "title": "S3 Object Storage", "description": "Configure AWS S3 or S3-compatible object storage service as image hosting", "status": "Connection Status", "connected": "Connected", "connecting": "Connecting", "disconnected": "Disconnected", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "Enter Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "Enter Secret Access Key", "region": "Region", "bucket": "Bucket", "bucketPlaceholder": "Enter bucket name", "advancedSettings": "Advanced Settings", "endpoint": "Custom Endpoint", "endpointDesc": "Leave empty for AWS S3, or enter S3-compatible service endpoint", "customDomain": "Custom Domain", "customDomainDesc": "Optional, custom domain for accessing images", "pathPrefix": "Path Prefix", "pathPrefixDesc": "Optional, path prefix for image storage", "save": "Save Configuration", "test": "Test Connection", "setAsPrimary": "Set as Primary", "error": "Configuration Error", "requiredFields": "Please fill in required fields: Access Key ID, Secret Access Key, Region and Bucket", "saveSuccess": "Configuration Saved", "saveSuccessDesc": "S3 configuration has been saved", "saveError": "Failed to Save Configuration", "testSuccess": "Connection Test Successful", "testSuccessDesc": "S3 connection is working, ready to upload images", "testFailed": "Connection Test Failed", "testFailedDesc": "Please check configuration and network connection", "testFirstDesc": "Please test connection successfully before setting as primary", "setPrimarySuccess": "Set Successfully", "setPrimarySuccessDesc": "S3 has been set as primary image hosting" } }, "imageMethod": { "title": "Image Recognition", "desc": "Here, you can configure image recognition related settings, supporting OCR and VLM two ways.", "enable": { "title": "Enable Image Recognition", "desc": "When enabled, images will be automatically recognized during screenshot and image recording. When disabled, image recognition will be skipped." }, "setPrimary": "Set as default", "isPrimary": "{type} has been set as default", "ocr": { "title": "OCR", "languagePacks": "Language Pack", "checkModels": "Here you can search all models", "modelInstruction": "Comma separated, for example: eng,chi_sim" }, "vlm": { "title": "Visual Language Model", "desc": "Use visual language model to recognize image content." } }, "backupSync": { "title": "Backup Data", "desc": "Here, you can use other methods to backup your data, you can regularly backup to ensure data security.", "localBackup": { "tabTitle": "Local Backup", "export": { "title": "Export Backup", "desc": "Package application data into a .zip file and save to specified location.", "button": "Choose Location and Export", "simpleButton": "Export", "exporting": "Exporting..." }, "import": { "title": "Import Backup", "desc": "Restore application data from .zip file, will overwrite all current data.", "button": "Choose File and Import", "importing": "Importing...", "warning": "Import operation will overwrite all current data, please ensure important content is backed up!" }, "exportDialog": { "title": "Choose backup file save location" }, "importDialog": { "title": "Choose backup file to import" }, "exportSuccess": "Backup exported successfully!", "exportError": "Backup export failed", "importSuccess": "Backup imported successfully! Application will restart to apply changes.", "importError": "Backup import failed", "restartConfirm": "Import completed! Restart application now to apply changes?" } }, "template": { "title": "Template", "desc": "Here you can create and manage custom organization templates to help AI organize record content according to your needs.", "customTemplate": "Custom Template", "addTemplate": "Add Custom Template", "deleteConfirm": "Are you sure to delete this template?", "status": "Status", "name": "Name", "content": "Content", "scope": "Scope", "selectScope": "Select Scope", "addTemplateDesc": "Please enter the custom template name and content, helping AI better understand your needs.", "editTemplate": "Edit Custom Template", "noContent": "No content", "range": { "all": "All", "today": "Today", "week": "Past Week", "month": "Past Month", "threeMonth": "Past 3 Months", "year": "Past Year" } }, "shortcut": { "title": "Shortcuts", "screenshot": "Screenshot Record", "link": "Link Record", "textRecord": "Text Record", "windowPin": "Window Pin" }, "theme": { "title": "Theme Settings", "desc": "Customize application theme colors", "appTheme": "App Color Scheme", "previewTheme": "Preview Content Theme", "codeTheme": "Code Block Highlight Theme", "selectTheme": "Select Theme" }, "dev": { "title": "Developer", "desc": "Here you can configure developer options, including network proxy, data cleanup, and configuration file management.", "clearData": "Clear Data", "clearDataConfirm": "Are you sure to clear data?", "proxy": "Proxy, used to solve network problems, after configuration, it is recommended to restart the application.", "proxyPlaceholder": "Enter proxy address", "proxyTitle": "Network Proxy", "clearDataTitle": "Clear Data", "clearDataDesc": "Clear data information, including system configuration and database (including records).", "clearFileTitle": "Clear Files", "clearFileDesc": "Clear files, including images and articles.", "clearButton": "Clear", "configFileTitle": "Config File Management", "configFileDesc": "Import and export configuration files. Importing will overwrite current configuration and take effect after restart.", "importConfigTitle": "Import Config File", "exportConfigTitle": "Export Config File", "importConfigSuccessMobile": "Config downloaded successfully, please restart the app manually", "exportConfigSuccess": "Export successful", "importButton": "Import", "exportButton": "Export" }, "chat": { "title": "Chat Settings", "desc": "Configure chat-related settings here, including summary generation.", "primaryModel": { "title": "Primary Model", "model": { "title": "Primary Chat Model", "desc": "Select the main AI model for daily conversations" } }, "toolbar": { "title": "Toolbar Settings", "chatToolbar": { "title": "Chat Toolbar", "desc": "Customize the visibility and order of chat toolbar buttons", "button": "Configure", "modelSelect": { "desc": "Switch the AI model for conversation" }, "promptSelect": { "desc": "Select the preset prompt for the conversation" }, "chatLanguage": { "desc": "Set the language for the conversation" }, "chatLink": { "title": "Link Tag", "desc": "Link note content of the current tag to conversation context" }, "fileLink": { "desc": "Link files or folders to the conversation context" }, "mcpButton": { "desc": "Select and connect MCP servers to use external tools" }, "ragSwitch": { "title": "Knowledge Base", "desc": "Enable vector knowledge base retrieval" }, "clipboardMonitor": { "title": "Clipboard Monitor", "desc": "Automatically monitor clipboard content changes" }, "newChat": { "desc": "Start a new conversation" }, "clearContext": { "desc": "Clear conversation context, keep chat history" }, "clearChat": { "desc": "Delete all chat records" } } }, "condense": { "title": "Conversation Summary", "enable": { "title": "Enable Summary", "desc": "Automatically compress long conversations to save token usage" }, "model": { "title": "Summary Model", "desc": "Select the AI model for generating summaries", "placeholder": "Use primary model" }, "threshold": { "title": "Trigger Threshold", "desc": "Check compression when AI messages exceed this count" }, "minToken": { "title": "Min Token Count", "desc": "Only compress messages exceeding this token count" }, "keepLatest": { "title": "Keep Latest", "desc": "Keep the latest N AI messages uncompressed" }, "maxLength": { "title": "Max Summary Length", "desc": "Control the maximum word count of generated summaries" }, "prompt": { "title": "Custom Summary Prompt", "desc": "Customize the prompt template for generating summaries", "label": "Prompt Template", "placeholder": "Enter custom prompt...", "help": "Use {content} as a placeholder for original content", "save": "Save", "reset": "Reset to Default" } }, "conversationTitle": { "title": "Conversation Title", "model": { "title": "Title Generation Model", "desc": "Select the AI model for generating conversation titles" } }, "inspiration": { "title": "Inspiration Model", "model": { "title": "Quick Prompt Generator", "desc": "Generate quick prompt suggestions to help users start conversations" } } }, "ai": { "title": "Model Management", "desc": "Here, you can add and manage various custom model services. After configuration, you will unlock AI-related features, such as organization and conversation functions.", "modelTitle": "Custom Name", "modelConfigTitle": "Model Config", "modelConfigDesc": "Every configuration corresponds to an AI model, you can create new configurations through templates or custom.", "providerInfo": "Provider Information", "providerInfoDesc": "This configuration is created based on a provider template, with name and URL pre-configured.", "create": "Create", "createDesc": "Select an empty configuration or create a new configuration using the supplier template.", "createSection": { "title": "Custom Model Configuration", "descWithoutModels": "Add custom AI model configurations to use more powerful model services." }, "config": "Config", "custom": "Custom", "addCustomModel": "Custom", "deleteCustomModel": "Delete", "deleteCustomModelConfirm": "Are you sure to delete this custom model?", "copyConfig": "Copy", "builtin": "Built-in", "modelSupport": "Only supports AI models with OpenAI protocol", "apiKeyUrl": "Create API Key", "modelType": { "title": "Model Type", "desc": "Select the type of AI model based on its capability", "chat": "Chat", "image": "Image", "video": "Video", "tts": "Text-to-Speech", "stt": "Speech-to-Text", "embedding": "Embedding", "rerank": "Reranking" }, "modelList": { "error": { "title": "Failed to get model list", "description": "Please check if API Key or network is correct" } }, "selectModel": "Please select a model", "modelProviderDesc": "Custom models only support AI models with OpenAI protocol.", "modelTitleDesc": "Custom name, used to identify AI models, please do not repeat.", "modelBaseUrlDesc": "You only need to configure the version number, for example: https://api.openai.com/v1, the suffix will be automatically added.", "modelDesc": "Some models support getting model list, if not supported please manually configure.", "temperatureDesc": "Controls randomness of output. Lower values make generated content more deterministic.", "topPDesc": "A nucleus sampling method, where the model considers the results of tokens with top_p probability mass. So 0.1 means only consider the top 10% probability mass. Usually we suggest to change this or temperature but not both.", "customHeaders": "Custom Headers", "customHeadersDesc": "Add custom HTTP headers with key-value pairs.", "headerKey": "Key", "headerValue": "Value", "addHeader": "Add Header", "connectionSuccess": "AI connection test passed", "voice": "Voice Type", "voiceDesc": "Specify the voice type for audio models, such as 'alloy', 'echo', 'fable', etc.", "voicePlaceholder": "Enter voice type, e.g.: alloy", "defaultModels": { "title": "Default Free Models", "desc": "NoteGen provides free AI model services for users, enabling basic functionality without configuration.", "chatModel": { "name": "Qwen/Qwen3-8B", "type": "Chat Model", "desc": "Suitable for daily conversations and text generation" }, "embeddingModel": { "name": "BAAI/bge-m3", "type": "Embedding Model", "desc": "Used for text vectorization and semantic search" }, "visionModel": { "name": "OpenGVLab/InternVL2-8B", "type": "Vision Model", "desc": "Supports image understanding and visual Q&A" }, "completionModel": { "name": "Fast Completion", "type": "Completion Model", "desc": "AI inline completion for Markdown editor, similar to GitHub Copilot, quickly generates continuation content" }, "poweredBy": "Powered by SiliconFlow" }, "connectionFailed": "Connection Failed", "enableStream": "Stream Response", "enableStreamDesc": "Enable streaming response to display generated content in real-time, but some models may not support this feature.", "selectConfig": "Please select a configuration", "models": "Model List", "modelsDesc": "Manage all models under the current configuration here. Each model can have different types and parameters.", "addModel": "Add Model", "newModel": "New Model", "checkConnection": "Test Connection", "model": "Model" }, "ocr": { "title": "OCR", "languagePacks": "Language Packs", "checkModels": "Check all models here", "modelInstruction": "Separate with commas, e.g.: eng,chi_sim" }, "file": { "title": "File Settings", "desc": "Here, you can manage workspace settings and other file-related options.", "workspace": { "title": "Workspace Settings", "desc": "Set the application's workspace directory where files will be saved", "current": "Current Workspace Path", "defaultPath": "Default Workspace", "default": "Using default workspace path", "custom": "Using custom workspace path", "select": "Select Workspace Directory", "reset": "Reset to Default Path", "history": "History Paths", "selectFromHistory": "Select workspace from history", "clearHistory": "Clear History", "actions": "Actions", "searchPlaceholder": "Search workspace paths...", "noResults": "No results found" }, "info": { "title": "Workspace Information", "desc": "After changing the workspace, you need to restart the application for the changes to take full effect. Files in the new workspace will be displayed after restart." }, "toast": { "updated": "Workspace Updated", "updatedDesc": "Workspace set to: {path}", "reset": "Workspace Reset", "resetDesc": "Restored to default workspace", "error": "Workspace Selection Failed", "errorDesc": "Unable to select workspace directory, please try again", "resetError": "Workspace Reset Failed", "resetErrorDesc": "Unable to reset to default workspace, please try again" }, "assets": { "title": "Assets Path", "desc": "Set the path where resources (e.g. images, videos, files etc.) used in writing will be saved. Resources will be saved at the same level as the currently edited markdown file.", "select": "Set the path where resources used in writing will be saved" } }, "shortcuts": { "title": "Shortcuts", "desc": "Here, you can configure shortcuts to help you use NoteGen more efficiently.", "resetDefaults": "Reset", "clear": "Clear", "noShortcut": "No Shortcut", "shortcuts": { "openWindow": { "title": "Open/Hide Window", "desc": "Open/Hide the main window." }, "quickRecordText": { "title": "Quick Record Text", "desc": "Quickly open the main window and switch to text recording." } } } }, "record": { "trash": { "title": "Empty Trash", "confirm": "Are you sure to empty the trash?", "records": "{count} records can be restored", "empty": "Empty", "restoreAll": "Restore All", "close": "Close Trash" }, "queue": { "ocr": "OCR recognition", "ai": "AI content recognition", "upload": "Upload to image host", "jsdelivr": "Notify jsdelivr cache", "save": "Save", "recording": "Recording...", "recorded": "Recorded", "record": "Record", "detected": "Detected" }, "mark": { "empty": "No records yet", "loading": "Loading...", "createdAt": "Created At", "type": { "scan": "Scan", "image": "Image", "screenshot": "Screenshot", "text": "Text", "recording": "Recording", "file": "File", "link": "Link", "todo": "Todo", "pdf": "PDF", "upload": "Upload Record", "download": "Download Record", "uploadTo": "Sync from local to {provider}", "downloadFrom": "Sync from {provider} to local" }, "uploadSuccess": "Record upload success", "downloadSuccess": "Record download success", "desc": "Description", "content": "Content", "progress": { "cacheImage": "Caching image", "ocr": "OCR recognition", "aiAnalysis": "AI content analysis", "uploadImage": "Uploading to image host", "jsdelivrCache": "Notifying jsdelivr cache", "cacheFile": "Caching file", "cacheScreenshot": "Caching screenshot", "textAnalysis": "Text analysis", "save": "Saving", "saveImage": "Saving image", "newToken": "Create access token", "newTokenDesc": "New token must be configured with repo permission, configuration will automatically create file repository (private) and image repository." }, "imageGallery": { "expand": "Expand", "collapse": "Collapse" }, "text": { "title": "Record Text", "description": "Record a piece of text, which will be inserted into the appropriate position when organizing notes.", "characterCount": "{count} characters", "save": "Save", "autoReadClipboard": "Auto-read clipboard text" }, "link": { "title": "Record Link", "description": "Enter a webpage link, and the system will automatically crawl the page content and save it", "save": "Save", "autoReadClipboard": "Auto-read clipboard link" }, "todo": { "title": "Todo Record", "description": "Create todo items to manage your tasks", "titlePlaceholder": "Enter todo title...", "descriptionPlaceholder": "Enter detailed description (optional)", "priority": "Priority", "priorityLow": "Low", "priorityMedium": "Medium", "priorityHigh": "High", "dateRange": "Date Range", "dateRangePlaceholder": "Select date range", "dueDate": "Due Date", "dueDatePlaceholder": "Select date", "save": "Create Todo", "saveEdit": "Save", "edit": "Edit Todo", "editDescription": "Modify the details of the todo item", "cancel": "Cancel", "selectTag": "Select Tag", "completed": "Completed", "uncompleted": "Uncompleted" }, "clipboard": { "detectedImage": "Clipboard image detected", "detectedText": "Clipboard text detected" }, "tag": { "searchPlaceholder": "Create or search tags...", "noResults": "No matching tags found", "quickAdd": "Quick Create", "pinned": "Pinned", "others": "Others", "rename": "Rename", "delete": "Delete", "pin": "Pin", "unpin": "Unpin", "newTag": "New Tag", "newTagPlaceholder": "Enter tag name...", "add": "Add" }, "mark": { "empty": "No records", "emptyHint": "Use the toolbar at the top to create your first record!", "type": { "text": "Text" }, "chat": { "modeSelect": { "chat": "Chat", "agent": "Agent" }, "agent": { "running": "Agent Running", "thinking": "Thinking", "acting": "Acting", "observation": "Observation", "thought": "Thought", "action": "Action", "toolCalls": "Tool Calls", "confirmation": { "title": "Confirm Action", "description": "The agent wants to perform the following action. Please confirm to continue.", "tool": "Tool", "parameters": "Parameters", "cancel": "Cancel", "confirm": "Confirm", "confirmed": "Confirmed", "cancelled": "Cancelled" } }, "placeholder": { "default": "Ask questions or organize your notes into an article...", "noApiKey": "API Key not configured, AI chat feature is unavailable...", "on": "AI Suggestion On", "off": "AI Suggestion Off" }, "header": { "configApiKey": "Configure API KEY", "clearChat": "Clear Chat", "configPrompt": "Configure Prompt", "selectPrompt": "Select Prompt" }, "clipboard": { "image": { "detected": "Image detected in clipboard:", "recording": "Recording...", "recorded": "Recorded", "record": "Record" }, "text": { "detected": "Text detected in clipboard:", "recorded": "Recorded", "record": "Record" } }, "messageControl": { "words": "words", "summary": "Summary" }, "mcp": { "maxIterationsReached": "Maximum tool call iterations reached", "toolCall": "MCP Server", "params": "Parameters", "result": "Result", "copy": "Copy", "paramsCopied": "Parameters copied", "resultCopied": "Result copied", "calling": "Calling", "success": "Completed", "error": "Failed" }, "empty": { "title": "Start AI Conversation", "subtitle": "Use Chat or Agent mode to interact with AI", "currentModel": "Current Model", "currentPrompt": "Current Prompt", "currentMode": "Conversation Mode", "noModel": "No model set", "noPrompt": "No prompt set", "configureModel": "Configure Model", "recentConversations": "Recent Conversations", "deleteConversation": "Delete conversation", "conversationHistory": "History", "viewMore": "View more", "messages": "messages", "searchPlaceholder": "Search conversations...", "noMatchingConversations": "No matching conversations found", "noConversationHistory": "No conversation history", "quickPrompts": { "title": "Quick Start", "writeNote": "Help me write a note", "summarize": "Help me summarize this content", "brainstorm": "Help me brainstorm ideas", "explain": "Help me explain this concept" }, "modeHint": "Click the", "modeHintSuffix": "button on the left side of the input box to switch conversation mode" }, "content": { "organize": "Organize your records into an article:" }, "note": { "writing": "Write", "convert": "Convert Article", "description": "The current note is generated by AI and cannot be edited. Convert the current note to an article (generate a local file) for secondary creation in the writing page.", "filename": "Filename", "selectFolder": "Select folder", "rootDirectory": "Root directory", "deleteTag": "Delete current tag, records and notes (can be restored from trash)", "warning": "After conversion, you will be redirected to the writing page.", "convert_button": "Convert" }, "mark": { "recorded": "Recorded", "record": "Record" }, "send": "Send" }, "text": { "title": "Record Text", "description": "Record a piece of text, which will be inserted into the appropriate position when organizing notes.", "characterCount": "{count} characters", "save": "Save" }, "clipboard": { "detectedImage": "Clipboard image detected", "detectedText": "Clipboard text detected" }, "tag": { "searchPlaceholder": "Create or search tags...", "noResults": "No matching tags found", "quickAdd": "Quick Create", "pinned": "Pinned", "others": "Others", "rename": "Rename", "delete": "Delete", "pin": "Pin", "unpin": "Unpin" }, "progress": { "cacheImage": "Caching image", "ocr": "OCR recognition", "aiAnalysis": "AI content analysis", "uploadImage": "Uploading to image host", "jsdelivrCache": "Notifying jsdelivr cache", "cacheFile": "Caching file", "cacheScreenshot": "Caching screenshot", "textAnalysis": "Text analysis", "save": "Saving", "saveImage": "Saving image" } }, "toolbar": { "search": "Search", "filter": { "title": "Filter", "description": "Instantly narrow records by content, time, and type.", "search": "Search", "searchPlaceholder": "Search record text, description, or link", "type": "Type", "time": "Time", "tag": "Tag", "allTags": "All tags", "clear": "Clear filters", "selectAllTypes": "Select all types", "clearTypes": "Clear type selection", "timeOptions": { "all": "All time", "today": "Today", "last7Days": "Last 7 days", "last30Days": "Last 30 days" } }, "trash": "Trash", "restore": "Restore", "delete": "Delete", "deleteConfirm": "Are you sure to delete?", "moveTag": "Move Tag", "convertTo": "Convert to {type}", "copyLink": "Copy Link", "copied": "Copied to clipboard!", "regenerateDesc": "Regenerate Description", "viewFolder": "View Folder", "viewFile": "View Original File", "deleteForever": "Delete Forever", "sortByName": "Sort by Name", "sortByCreated": "Sort by Created", "sortByModified": "Sort by Modified", "sortAsc": "Sort Ascending", "sortDesc": "Sort Descending", "sort": "Sort", "processingVectors": "Processing Vector Data", "calculateVectors": "Calculate Document Vectors", "multiSelect": "Multi Select", "exitMultiSelect": "Exit Multi Select", "organizeNotes": "Organize Notes", "organizeSuccess": "Notes organized successfully: {title}", "organizeError": "Failed to organize notes", "currentTag": "Current Tag", "text": "Record Text", "recording": "Recording Record", "scan": "Scan Image", "image": "Upload Image", "link": "Record Link", "file": "Upload File", "todo": "Todo Record", "closeTrash": "Close Trash", "selectAll": "Select All", "deselectAll": "Deselect All", "selectedCount": "{count} items selected", "visibleCount": "{count} records", "moveSelectedTags": "Move selected {count} items", "deleteSelected": "Delete selected {count} items", "deleteSelectedForever": "Permanently delete selected {count} items", "view": { "list": "List view", "compact": "Compact view", "cards": "Card view" } }, "list": { "title": "Records", "emptyFiltered": "No matching records", "emptyFilteredHint": "Try adjusting the search or filters", "filteredLabel": "{count} filtered", "filtered": "Filtered", "filteredByTag": "tag", "filteredByType": "{count} types", "filteredSummary": "Showing {count} results · {filters}", "searchChip": "Search: {value}", "time": { "today": "Today", "last7Days": "Last 7 days", "last30Days": "Last 30 days" } }, "note": { "organizeAs": "Organize as", "template": "Template", "setting": "Settings", "confirm": "确认", "cancel": "取消", "removeThinking": "移除思考过程", "stop": "Stop" } }, "chat": { "condensing": "Condensing context...", "condensed": { "message": "Condensed {count} historical messages" }, "empty": { "features": [ { "chat": "Chat with AI bot" }, { "linked": "Linked with your records or notes" }, { "clipboard": "Recognize clipboard records or images" }, { "organize": "Organize your records into notes" } ], "title": "Start chatting with AI", "subtitle": "Interact with AI using Chat or Agent mode", "currentModel": "Current Model", "currentPrompt": "Current Prompt", "currentMode": "Conversation Mode", "noModel": "No model set", "noPrompt": "No prompt set", "configureModel": "Configure Model", "recentConversations": "Recent Conversations", "deleteConversation": "Delete Conversation", "conversationHistory": "History", "viewMore": "View More", "messages": "messages", "searchPlaceholder": "Search conversations...", "noMatchingConversations": "No matching conversations found", "noConversationHistory": "No conversation history yet", "quickPrompts": { "title": "快速开始", "writeNote": "帮我写一篇笔记", "summarize": "帮我总结这段内容", "brainstorm": "帮我头脑风暴一些想法", "explain": "帮我解释这个概念" } }, "newChat": "New Chat with New Tag", "removeChat": "Remove Chat with Current Tag", "confirmNew": "Create New Tag", "confirmNewDescription": "Are you sure you want to create a new tag to start a conversation?", "confirmRemove": "Delete Tag", "confirmRemoveDescription": "Please note that deleting this tag will also delete all records within it. Please confirm again.", "content": { "organize": "Organize your records into an article:" }, "quote": { "lineSingle": "Quoted from {fileName} line {line}", "lineRange": "Quoted from {fileName} lines {startLine}-{endLine}", "noLine": "Quoted from {fileName}" }, "note": { "organize": "Organize", "writing": "Write", "convert": "Convert Article", "description": "The current note is generated by AI and cannot be edited. Convert the current note to an article (generate a local file) for secondary creation in the writing page.", "filename": "Filename", "selectFolder": "Select folder", "rootDirectory": "Root directory", "deleteTag": "Delete current tag, records and notes (can be restored from trash)", "warning": "After conversion, you will be redirected to the writing page.", "convert_button": "Convert", "organizeAs": "Organize your records into an article:", "templateContent": "Template content", "recordRange": "Record range", "filterThinkingContent": "Remove thinking content from records", "startOrganize": "Start organizing", "manageTemplate": "Manage template", "cancel": "Cancel", "stop": "Stop" }, "mark": { "recorded": "Recorded", "record": "Record" }, "input": { "organize": "Organize", "chat": "Chat", "placeholder": { "default": "Type a message...", "noApiKey": "No API Key configured, can't use AI chat...", "on": "AI suggestions on", "off": "AI suggestions off", "noPrimaryModel": "No primary model configured, can't use AI chat..." }, "translate": { "tooltip": "Translate", "translating": "Translating...", "showOriginal": "Show Original", "alreadyTranslated": "Translated to" }, "clipboardMonitor": { "enable": "Clipboard monitoring (on)", "disable": "Clipboard monitoring (off)" }, "send": "Send", "stop": "Stop", "stopped": "Conversation stopped", "terminate": "Terminate", "tagLink": { "on": "Linked to tag", "off": "Not linked to tag" }, "modelSelect": { "tooltip": "Select AI model", "placeholder": "Search AI models", "noModel": "No model found" }, "promptSelect": { "tooltip": "Select prompt", "placeholder": "Search prompts" }, "newChat": "New Chat", "mcp": { "tooltip": "MCP server" }, "chatLanguage": { "tooltip": "Select chat language", "placeholder": "Search language" }, "rag": { "notSupported": "Vector model is not supported", "enabled": "Knowledge Base Search (Enabled)", "disabled": "Knowledge Base Search (Disabled)" }, "modeSelect": { "tooltip": "Select input mode", "chat": "Chat mode", "gen": "Organize mode", "translate": "Translate mode" }, "chatModeSelect": { "chatDescription": "Quick conversation, analysis-first", "agentDescription": "Smart assistant, can execute actions" }, "attachImage": "Attach images", "imageSelector": { "title": "Select Images", "local": "Local Files", "records": "From Records", "selectFiles": "Select Local Images", "noRecords": "No image records available", "cancel": "Cancel", "confirm": "Confirm" }, "agent": { "running": "Agent Running", "thinking": "Thinking", "analyzingRequest": "Agent is analyzing your request...", "acting": "Acting", "observation": "Observation", "thought": "Thought", "action": "Action", "toolCalls": "Tool Calls", "autoFinal": { "createNote": "Created note \"{name}\".", "createFile": "Created file \"{name}\"." }, "confirmation": { "title": "Confirm Action", "description": "The agent wants to perform the following action. Please confirm to continue.", "tool": "Tool", "parameters": "Parameters", "cancel": "Cancel", "confirm": "Confirm", "confirmed": "Confirmed", "cancelled": "Cancelled", "fallback": { "title": "Review action", "description": "Please confirm the target and content of this action." }, "params": { "filePath": "File path", "content": "File content", "sourcePath": "Source path", "targetPath": "Target path", "files": "Files", "newName": "New name", "scriptName": "Script name", "command": "Command" }, "tools": { "create_file": { "title": "Create file", "description": "A new file will be created in the workspace." }, "create_files_batch": { "title": "Create files", "description": "Multiple new files will be created in the workspace." }, "rename_file": { "title": "Rename file", "description": "The selected file will be renamed." }, "move_file": { "title": "Move file", "description": "The file will be moved to a new location." }, "copy_file": { "title": "Copy file", "description": "A copy of the file will be created at the target location." }, "replace_editor_content": { "title": "Replace editor content", "description": "The current editor content will be replaced." }, "insert_at_cursor": { "title": "Insert at cursor", "description": "Content will be inserted at the current cursor position." }, "delete_markdown_file": { "title": "Delete file", "description": "The selected file will be permanently deleted." }, "execute_skill_script": { "title": "Run script", "description": "A skill-provided script or command will be executed." } } } }, "fileLink": { "tooltip": "Link File", "selectFile": "Select File", "linkedFile": "Linked File", "searchPlaceholder": "Search files...", "noFiles": "No files found", "loading": "Loading..." } }, "header": { "configApiKey": "Configure API KEY", "clearChat": "Clear Chat", "selectPrompt": "Select Prompt", "noModel": "AI model not selected", "configPrompt": "Configure Prompt" }, "clipboard": { "image": { "detected": "Image detected in clipboard:", "recording": "Recording...", "recorded": "Recorded", "record": "Record" }, "text": { "detected": "Text detected in clipboard:", "recorded": "Recorded", "record": "Record" } }, "messageControl": { "words": "words", "summary": "Summary", "readAloud": "Read Aloud", "playing": "Playing", "loading": "Loading", "stop": "Stop Playing", "copy": "Copy", "copied": "Copied" }, "ragSources": { "label": "Found {count} notes in knowledge base", "openFile": "Open file" }, "preview": { "close": "Close", "copy": "Copy", "copied": "Copied!" }, "control": { "edit": "Edit", "save": "Save", "cancel": "Cancel", "delete": "Delete", "deleteConfirm": "Are you sure to delete this message?" } }, "tag": { "add": "Add Tag", "edit": "Edit Tag", "delete": "Delete Tag", "deleteConfirm": "Are you sure to delete this tag?", "placeholder": "Enter tag name" } }, "search": { "placeholder": "Search notes and articles...", "results": "{count} search results", "noResults": "No search results", "tryDifferentKeywords": "Try using different keywords", "mode": { "fuzzy": "Fuzzy", "exact": "Exact" }, "item": { "record": "Record", "article": "Article", "matches": "{count} matches", "scanType": "scan" } }, "image": { "root": "Image Repository", "noData": { "title": "Sync feature not enabled", "desc": "Please go to the system settings page to configure Github sync.", "goToSettings": "Go to Settings", "howToUse": "How to use sync feature?" } }, "navigation": { "chat": "Chat", "record": "Record", "quickRecord": "Quick Record", "write": "Write", "search": "Search", "githubImageHosting": "Github Image Hosting", "login": "Login", "loading": "Loading", "view": "View", "logout": "Logout", "setting": "Settings", "activity": "Activity", "files": "Notes", "outline": "Outline", "showLeftSidebar": "Show Left Sidebar", "hideLeftSidebar": "Hide Left Sidebar", "showCenterPanel": "Show Editor", "hideCenterPanel": "Hide Editor", "showRightSidebar": "Show Right Sidebar", "hideRightSidebar": "Hide Right Sidebar", "searchPlaceholder": "Search notes or records..." }, "activity": { "title": "Activity Calendar", "description": "Review your daily records, chats, and writing activity in one place. This first version is derived from existing records, user chats, and note modification times.", "drawer": { "title": "Activity", "description": "Quickly review today's status and your recent activity trend.", "today": "Today" }, "loading": "Loading activity data...", "empty": "No activity data yet", "refresh": "Refresh", "summary": { "totalCount": "Total Activity", "activeDays": "Active Days", "records": "Records", "chats": "Chats", "writing": "Writing" }, "labels": { "record": "Record", "writing": "Writing", "chat": "Chat" }, "heatmap": { "title": "Last 26 Weeks", "range": "{startDate} - {endDate}", "less": "Less", "more": "More", "dayCount": "activities", "emptyDay": "No activity" }, "detail": { "title": "Day Details", "empty": "Select a day to inspect its activity details." } }, "marks": { "types": { "screenshot": "Screenshot", "text": "Text", "image": "Image" } }, "tags": { "inspiration": "Inspiration" }, "sync": { "status": "Sync Repository Status", "imageRepo": "Image Repository", "articleRepo": "Article Repository" }, "ai": { "thinking": "Thinking", "error": { "title": "AI Error", "noAddress": "Please set AI address first" } }, "article": { "sync": { "syncingRemote": "Pulling remote file...", "syncComplete": "Sync Complete", "pullingRemote": "Fetching latest content from remote server..." }, "syncConfirm": { "title": "Remote File Update Detected", "description": "File {fileName} has remote updates", "commitInfo": "Latest Commit Info", "commitMessage": "Commit Message", "author": "Author", "changes": "Changes", "confirmMessage": "Are you sure you want to pull the remote version and overwrite the local file? This action cannot be undone.", "cancel": "Cancel", "confirmPull": "Confirm Pull" }, "emptyState": { "title": "Start Creating", "subtitle": "Select a file to start editing, or create a new note", "tip": "💡 Tip: You can also select files from the left sidebar", "actions": { "newNote": { "title": "Create Note", "desc": "Create a new Markdown note" }, "newRecord": { "title": "Create Record", "desc": "Open text recording feature" }, "globalSearch": { "title": "Global Search", "desc": "Quickly find your note content" }, "openWorkspace": { "title": "Open Workspace", "desc": "Select or switch workspace directory" } }, "onboarding": { "title": "Onboarding", "subtitle": "Walk through these three tasks to learn the core NoteGen flow.", "dismiss": "Skip onboarding", "reopen": "Show onboarding again", "start": "Start", "viewHint": "Show hint", "continue": "Continue", "completed": "Done", "allDone": "All getting-started tasks are complete. You've already tried the core NoteGen workflow.", "stepLabel": "Task ({current}/{total})", "stepCompletedLabel": "Completed Task ({current}/{total})", "afterOrganizeDialog": { "title": "Completed Task (2/3)", "description": "You've turned the record into a note. Do you want to continue and use the AI Agent to turn this note into a bilingual version?", "confirm": "Continue", "cancel": "Not now" }, "agentPrompt": { "label": "Sample Prompt", "use": "Use This Prompt", "intro": "Please directly revise the note I just organized into a bilingual Chinese-English version.", "requirement1": "", "requirement2": "", "requirement3": "", "requirement4": "", "outro": "" }, "steps": { "createRecord": { "title": "Create your first record", "desc": "Save a sample record and learn where quick capture lives." }, "organizeNote": { "title": "Organize it into a note", "desc": "Turn that record into a structured note." }, "aiPolish": { "title": "Use Agent for bilingual translation", "desc": "Use the AI Agent to turn the note you just organized into a bilingual version." } }, "completedStates": { "create-record": { "title": "Your first record is saved", "desc": "You now know where quick capture lives." }, "organize-note": { "title": "Your record is now a note", "desc": "Next, try using AI to revise the note." }, "ai-polish": { "title": "You used the Agent on the note", "desc": "You've completed the flow from capture to note organization to Agent-assisted processing." } }, "spotlight": { "create-record": { "title": "This is the quick record entry", "desc": "Click here to open text capture. We'll preload a sample record so you can save it right away." }, "organize-note": { "title": "This button organizes records into a note", "desc": "Use it to turn your captured record into a full Markdown note." }, "ai-polish": { "title": "Use the Agent on the note you just created here", "desc": "Insert the sample prompt into chat and send it. The Agent will generate a bilingual version based on the current note." } } } }, "unsupportedFile": { "title": "Cannot Preview This File", "fileName": "File Name", "filePath": "File Path", "fileSize": "File Size", "modifiedTime": "Modified Time", "createdTime": "Created Time", "pathCopied": "Path copied", "openExternal": "Open with External App", "openDirectory": "Open File Directory" }, "file": { "toolbar": { "accessRepo": "Access Repository", "loadingSync": "Loading sync info", "configSync": "Configure Sync", "newArticle": "New Article", "newFolder": "New Folder", "refresh": "Refresh", "toggleFolders": "Toggle Folders", "expandAll": "Expand All", "collapseAll": "Collapse All", "sortByName": "Sort by Name", "sortByCreated": "Sort by Created", "sortByModified": "Sort by Modified", "sortAsc": "Sort Ascending", "sortDesc": "Sort Descending", "sort": "Sort", "hideCloudFiles": "Hide Cloud Files", "showCloudFiles": "Show Cloud Files", "processingVectors": "Processing Vector Data", "calculateVectors": "Knowledge Base Calculation (Full)", "importMarkdown": "Import", "importing": "Importing...", "importSuccess": "Import Successful", "importSuccessDesc": "Successfully imported {count} files", "importError": "Import Failed" }, "sync": { "syncingRemote": "Pulling remote file...", "syncComplete": "Sync Complete", "pullingRemote": "Fetching latest content from remote server...", "pullComplete": "Pull Complete" }, "context": { "viewDirectory": "View Directory", "cut": "Cut", "copy": "Copy", "paste": "Paste", "rename": "Rename", "deleteSyncFile": "Delete Sync File", "deleteLocalFile": "Delete Local File", "delete": "Delete", "confirmDelete": "Are you sure you want to delete the folder \"{name}\"? This will delete the folder and all its contents.", "deleteSuccess": "Deleted successfully", "deleteFailed": "Delete failed", "newFile": "New File", "newFolder": "New Folder", "syncFolder": "Sync Folder", "syncFolderDesc": "Sync all Markdown files in the current folder", "syncFolderSuccess": "Sync folder success", "syncFolderError": "Sync folder error", "syncFolderProgress": "Syncing folder...", "deleteSyncFileSuccess": "Delete Sync File Success", "deleteSyncFileError": "Delete Sync File Error", "knowledgeBase": "Knowledge Base", "calculateVectors": "Calculate Vectors", "updateVectors": "Update Vectors", "deleteVectors": "Delete Vectors", "includeInKB": "Include in Knowledge Base", "includeInKBFile": "Include in Knowledge Base", "autoVectorCalc": "Auto Vector Calculation", "vectorCalculated": "Vector Updated", "vectorCalcCompleted": "Vector Calculation Completed", "vectorCalcFailed": "Vector Calculation Failed", "vectorDeleted": "Vector Deleted", "vectorDeleteFailed": "Delete Vector Failed", "batchCalcSuccess": "Successfully calculated vectors for {count} files", "batchCalcPartial": "Calculation completed: {success} succeeded, {failed} failed", "batchCalcFailed": "Batch vector calculation failed", "batchDeleteSuccess": "Successfully deleted vectors for {count} files", "batchDeletePartial": "Deletion completed: {success} succeeded, {failed} failed", "batchDeleteFailed": "Batch vector deletion failed", "noMarkdownFiles": "No Markdown files in folder", "includedInKB": "Included in Knowledge Base", "excludedFromKB": "Excluded from Knowledge Base", "autoCalcEnabled": "Auto vector calculation enabled", "autoCalcDisabled": "Auto vector calculation disabled", "settingFailed": "Setting failed", "confirmDeleteVectors": "Are you sure you want to delete vectors for {count} files?" }, "folderView": { "vectorDbNotEnabled": "Vector database not enabled", "calculateVectors": "Calculate Vectors", "indexed": "Indexed", "vectorCount": "Vector Count", "databaseSize": "Database Size", "lastCalculated": "Last Calculated", "never": "Never", "calculating": "Calculating...", "failed": "Failed", "recalculateVectors": "Recalculate Vectors", "skills": "Skills", "skillNotFound": "Skill Not Found", "skillNotFoundDesc": "Cannot find Skill with ID {id}", "loadingSkills": "Loading Skills...", "loadingSkill": "Loading Skill...", "globalSkills": "Global Skills", "workspaceSkills": "Workspace Skills", "instructions": "Instructions", "examples": "Examples", "scripts": "Scripts", "references": "References", "assets": "Assets" }, "error": { "fileExists": "File name already exists" }, "clipboard": { "copied": "Copied to clipboard", "cut": "Cut to clipboard", "pasted": "Pasted successfully", "pasteFailed": "Paste operation failed", "empty": "Clipboard is empty", "confirmOverwrite": "File already exists, do you want to overwrite it?", "mark": { "title": "Records", "tooltip": "Use Records", "description": "Convert records into content to insert into the article.", "noRecords": "No records", "ocrNoContent": "OCR did not recognize any content" }, "question": { "tooltip": "Q&A", "selectContent": "Please select content first", "promptTemplate": "Reference text: \n{content}\nBased on the question: \n{question}\n, directly provide the answer content." }, "continue": { "tooltip": "Continue", "promptTemplate": "Based on the preceding text: \n{content}\n continue writing and return content not exceeding 100 words.\nYou can reference the following text: \n{endContent}\n, but avoid duplicating its content." }, "polish": { "tooltip": "Polish", "selectContent": "Please select content first", "promptTemplate": "Polish this text: \n{content}\n, keep the language unchanged, fix typos and grammatical errors, directly return the polished result." }, "eraser": { "tooltip": "Simplify", "selectContent": "Please select content first", "promptTemplate": "Simplify this text: \n{content}\n, this text is too verbose, reduce the word count by at least half, keep the language unchanged, directly return the optimized result." }, "expansion": { "tooltip": "Expand", "selectContent": "Please select content first", "promptTemplate": "Expand this text: \n{content}\n, this text is too short, increase the word count by at least half, keep the language unchanged, directly return the expanded result." }, "translation": { "tooltip": "Translate", "description": "Translate the selected text", "selectContent": "Please select content first", "promptTemplate": "Translate this text: \n{content}\n, into {language}, directly return the translated result." }, "notSupported": "Operation not supported" }, "mobile": { "cancel": "Cancel", "create": "Create", "save": "Save", "emptyDir": "This folder is empty", "root": "Root", "openFiles": "Open files", "remote": "Remote file", "remoteFileNotPulled": "Cloud only · Tap to pull", "remoteFolderOnly": "Cloud-only folder", "file": "File", "folder": "Folder", "folderChildren": "{files} files · {folders} folders", "filePlaceholder": "example.md", "folderPlaceholder": "example-folder" }, "deleteConfirm": "Are you sure you want to delete this file?" }, "editor": { "copySuccess": "Copy Success", "copySuccessDescription": "Copied to clipboard", "search": { "placeholder": "Find in document", "replacePlaceholder": "Replace with", "caseSensitive": "Case sensitive", "replace": "Replace", "replaceAll": "Replace all", "findPrev": "Previous", "findNext": "Next" }, "floatbar": { "quote": { "tooltip": "Quote" }, "readAloud": { "start": "Read Aloud", "stop": "Stop Reading", "loading": "Loading..." } }, "toolbar": { "organize": { "tooltip": "Organize Notes" }, "mark": { "title": "Records", "tooltip": "Records", "description": "Convert records into content to insert into the article.", "noRecords": "No records", "ocrNoContent": "OCR did not recognize any content" }, "question": { "tooltip": "Q&A", "selectContent": "Please select content first", "promptTemplate": "Reference text: \n{content}\nBased on the question: \n{question}\n, directly provide the answer content." }, "continue": { "tooltip": "Continue", "promptTemplate": "Based on the preceding text: \n{content}\n continue writing and return content not exceeding 100 words.\nYou can reference the following text: \n{endContent}\n, but avoid duplicating its content." }, "polish": { "tooltip": "Polish", "selectContent": "Please select content first", "promptTemplate": "Polish this text: \n{content}\n, keep the language unchanged, fix typos and grammatical errors, directly return the polished result." }, "eraser": { "tooltip": "Simplify", "selectContent": "Please select content first", "promptTemplate": "Simplify this text: \n{content}\n, this text is too verbose, reduce the word count by at least half, keep the language unchanged, directly return the optimized result." }, "expansion": { "tooltip": "Expand", "selectContent": "Please select content first", "promptTemplate": "Expand this text: \n{content}\n, this text is too short, increase the word count by at least half, keep the language unchanged, directly return the expanded result." }, "translation": { "tooltip": "Translate", "description": "Translate the selected text", "selectContent": "Please select content first", "promptTemplate": "Translate this text: \n{content}\n, into {language}, directly return the translated result.", "fail": "Translation failed", "failNoSelection": "Please select text to translate", "translating": "Translating", "translatingTo": "Translating to {language}...", "success": "Translation complete", "successTo": "Translated to {language}", "customLanguage": "Custom language...", "customLanguagePlaceholder": "Enter target language, e.g., English, Japanese, etc.", "customLanguageEmpty": "Please enter target language", "customLanguageExample": "e.g., English, Japanese, French, etc." } }, "upload": { "error": "Upload failed", "needToken": "Upload images need to configure accessToken", "uploading": "Uploading image" }, "saveDialog": { "title": "Save File", "emptyContent": "Empty Content", "emptyContentDesc": "Please enter content before saving", "success": "Save Successful", "successDesc": "File saved successfully", "error": "Save Failed", "errorDesc": "Failed to save file, please try again" } }, "footer": { "wordCount": "Word Count", "pull": { "pull": "Pull", "checking": "Checking for updates...", "noUpdate": "No remote updates", "clickToPull": "Click to pull remote updates", "pullSuccess": "Pull Successful", "pullFailed": "Pull Failed", "ignored": "Ignored", "ignoreUpdate": "Ignore This Update" }, "sync": { "push": "Push", "pushed": "Pushed", "syncing": "Pushing", "syncFailed": "Push Failed", "checkNetworkOrToken": "Please check network connection or token", "quickSync": "Quick Sync" }, "history": { "loadingHistory": "Loading history", "historyRecords": "History Records", "noHistory": "No History", "loading": "Loading", "recordsCount": "records", "filterQuickSync": "Filter Quick Syncs", "committedAt": "committed at", "pull": "Pull", "quickSync": "Quick Sync" }, "vectorCalc": { "tooltip": { "default": "Vector Index Status", "none": "Click to start vector calculation", "indexed": "Indexed", "pending": "Pending update, click to calculate now", "calculating": "Calculating..." }, "status": { "calculating": "Calculating" } } } }, "mobile": { "chat": { "drawer": { "settings": { "title": "Chat Settings" }, "tools": { "title": "Tools", "newChat": "New Chat", "start": "Start" }, "attachments": { "title": "Attachments", "gallery": "Gallery", "camera": "Camera", "file": "File", "linkNote": "Link Note" } } } }, "mcp": { "selectServers": "MCP Servers", "searchServers": "Search servers...", "noServers": "MCP service not enabled", "noServersFound": "No matching servers found", "addServer": "Add server...", "goToSettings": "Go to Settings", "close": "Close", "navigate": "Select", "confirm": "Confirm", "tools": "tools", "connecting": "Connecting", "disconnected": "Disconnected" }, "recording": { "title": "Voice Recording", "description": "Click the microphone button to start recording, the system will automatically recognize and convert to text", "recording": "Recording", "paused": "Paused", "ready": "Ready", "processing": "Processing...", "cancel": "Cancel", "error": "Error", "success": "Success", "noModelConfigured": "Speech recognition model not configured, please configure in settings first", "speechUnavailable": "The current speech recognition mode is unavailable. Check local speech support or model configuration.", "fallbackToModel": "Local speech recognition is unavailable, so the app switched to model transcription automatically.", "startError": "Unable to start recording", "noAudioData": "No audio data recorded", "transcriptionSuccess": "Speech recognition completed", "transcriptionEmpty": "Recognition result is empty", "transcriptionError": "Speech recognition failed", "configureModel": "Configure model", "retryTranscription": "Retry transcription", "retrying": "Retrying...", "retrySuccess": "Transcription updated", "retryError": "Retry transcription failed", "noContentDetected": "No content detected", "doubleClickToSelectFile": "Double click to select audio file", "mode": { "builtin": "Browser Recognition", "builtinDesc": "Free, real-time recognition", "model": "AI Model Recognition", "modelDesc": "Requires STT model, more accurate" } }, "footer": { "wordCount": "Words", "sync": { "sync": "Sync", "synced": "Synced", "syncing": "Syncing", "syncFailed": "Sync Failed", "checkNetworkOrToken": "Please check network connection or token", "quickSync": "Quick Sync" }, "history": { "loadingHistory": "Loading history", "historyRecords": "History Records", "noHistory": "No History", "loading": "Loading", "recordsCount": "records", "filterQuickSync": "Filter Quick Syncs", "committedAt": "committed at", "pull": "Pull", "quickSync": "Quick Sync" }, "vectorCalc": { "tooltip": "Vector Calculation: Auto-calculate 30s after editing, or click to calculate now", "calculating": "Calculating", "pending": "Pending {progress}%", "synced": "Synced" } }, "quickRecord": { "description": "Click to select a recording tool and quickly create records" }, "editor": { "placeholder": "Type / to open menu, or start writing...", "outline": { "title": "Outline", "open": "Open Outline", "close": "Close Outline" }, "translation": { "fail": "Translation failed", "failNoSelection": "Please select text to translate", "translating": "Translating...", "translatingTo": "Translating to {language}...", "success": "Translation complete", "successTo": "Translated to {language}", "customLanguageEmpty": "Please enter target language", "customLanguageExample": "e.g., English, Japanese, French, etc." }, "quoteDisplay": { "fromFile": "Quoted from {fileName}", "line": "Quoted from {fileName} line {line}", "lines": "Quoted from {fileName} lines {start}-{end}" }, "bubbleMenu": { "ai": "AI", "polish": "Polish", "concise": "Concise", "expand": "Expand", "translate": "Translate", "translateSubtitle": "Translate to", "quoteToChat": "Quote to Chat", "link": "Link", "linkPlaceholder": "Enter link URL", "confirm": "Confirm", "cancel": "Cancel", "bold": "Bold", "italic": "Italic", "strike": "Strikethrough", "underline": "Underline", "inlineCode": "Inline Code", "highlight": "Highlight", "blockquote": "Quote", "bulletList": "Bullet List", "orderedList": "Numbered List", "taskList": "Task List", "codeBlock": "Code Block", "languages": { "English": "English", "Japanese": "Japanese", "Korean": "Korean", "French": "French", "German": "German", "Spanish": "Spanish", "Portuguese": "Portuguese", "Russian": "Russian", "Arabic": "Arabic" }, "customLanguagePlaceholder": "Custom language..." }, "aiSuggestion": { "accept": "Accept", "reject": "Reject", "generating": "Generating...", "abort": "Abort" }, "image": { "insert": "Insert Image", "uploading": "Uploading...", "uploadSuccess": "Image uploaded to image hosting", "saveSuccess": "Image saved locally", "uploadFailed": "Failed to insert image", "sizeSmall": "Small (25%)", "sizeMedium": "Medium (50%)", "sizeLarge": "Large (75%)", "sizeOriginal": "Original Size", "editAlt": "Edit Alt Text", "editSrc": "Edit URL", "altPlaceholder": "Enter alt text...", "srcPlaceholder": "Enter image URL...", "delete": "Delete Image", "confirm": "Confirm", "cancel": "Cancel" }, "mermaid": { "rendering": "Rendering...", "renderError": "Render error", "clickToEdit": "Click to edit source", "clickToAdd": "Click to add diagram", "placeholder": "Enter Mermaid diagram code...", "preview": "Preview", "done": "Done", "diagramTypes": { "flowchart": "Flowchart", "sequence": "Sequence", "classDiagram": "Class Diagram", "stateDiagram": "State Diagram", "er": "ER Diagram", "gantt": "Gantt", "pie": "Pie Chart", "journey": "Journey" }, "templates": { "flowchart": "graph TD\n A[Start] --> B[Process]\n B --> C[End]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Hello\n Bob-->>Alice: Reply", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title Project Plan\n dateFormat YYYY-MM-DD\n section Phase 1\n Task1 :a1, 2024-01-01, 30d\n section Phase 2\n Task2 :after a1, 20d", "pie": "pie title Resource Allocation\n \"CPU\" : 45\n \"Memory\" : 30\n \"Storage\" : 25", "journey": "journey\n title My Daily Work\n section Morning\n Commute : 7:00, 5\n Work : 9:00, 8" } }, "slashCommand": { "groups": { "ai": "AI", "heading": "Heading", "list": "List", "block": "Block", "align": "Align", "embed": "Embed", "math": "Math", "chart": "Chart" }, "items": { "continue": "Continue", "continueDesc": "AI continue writing content", "heading1": "Heading 1", "heading1Desc": "Large heading", "heading2": "Heading 2", "heading2Desc": "Medium heading", "heading3": "Heading 3", "heading3Desc": "Small heading", "bulletList": "Bullet List", "bulletListDesc": "Create a simple bullet list", "orderedList": "Ordered List", "orderedListDesc": "Create a numbered list", "taskList": "Task List", "taskListDesc": "Create a checklist with checkboxes", "image": "Image", "imageDesc": "Insert local or hosted image", "table": "Table", "tableDesc": "Insert a table", "blockquote": "Quote", "blockquoteDesc": "Capture quoted content", "codeBlock": "Code Block", "codeBlockDesc": "Capture code snippets", "divider": "Divider", "dividerDesc": "Create a horizontal divider", "inlineMath": "Inline Math", "inlineMathDesc": "Insert inline LaTeX formula", "blockMath": "Block Math", "blockMathDesc": "Insert block LaTeX formula", "flowchart": "Flowchart", "flowchartDesc": "Insert a flowchart", "sequence": "Sequence Diagram", "sequenceDesc": "Insert a sequence diagram", "gantt": "Gantt Chart", "ganttDesc": "Insert a Gantt chart", "classDiagram": "Class Diagram", "classDiagramDesc": "Insert a class diagram", "stateDiagram": "State Diagram", "stateDiagramDesc": "Insert a state diagram", "pie": "Pie Chart", "pieDesc": "Insert a pie chart", "erDiagram": "ER Diagram", "erDiagramDesc": "Insert an entity relationship diagram", "journey": "Journey Map", "journeyDesc": "Insert a user journey map" }, "imageUpload": { "success": "Upload successful", "saveSuccess": "Save successful", "savePath": "Saved to: {path}", "failed": "Failed to insert image" } } }, "tabContext": { "close": "Close", "closeOthers": "Close Others", "closeAll": "Close All", "closeLeft": "Close Left", "closeRight": "Close Right" } } ================================================ FILE: messages/ja.json ================================================ { "app": { "title": "ノート生成ツール", "description": "あなたのAI搭載ノートアシスタント" }, "common": { "save": "保存", "cancel": "キャンセル", "delete": "削除", "confirm": "確認", "edit": "編集", "create": "作成", "theme": "テーマ", "light": "ライトモード", "dark": "ダークモード", "system": "システム設定に従う", "pin": "ピン留め", "unpin": "ピン留めを解除", "settings": "設定", "back": "戻る", "sync": "同期", "language": "言語", "success": "成功", "error": "失敗", "defaultFileName": "無題のドキュメント", "restartToApply": "、設定を有効にするにはアプリケーションを再起動してください", "close": "閉じる", "open": "開く", "add": "追加", "remove": "削除", "search": "検索", "filter": "フィルター", "sort": "並べ替え", "export": "エクスポート", "import": "インポート", "refresh": "更新", "loading": "読み込み中...", "warning": "警告", "info": "情報", "unsaved": "未保存", "saving": "保存中...", "configureSync": "同期を構成" }, "settings": { "defaultModels": { "title": "デフォルトモデル" }, "others": "その他", "general": { "title": "一般設定", "desc": "ここでは、アプリケーションの基本設定を構成できます。インターフェースのテーマ、言語などのオプションが含まれます。", "interface": { "title": "インターフェース設定", "theme": { "title": "テーマ", "desc": "アプリケーションの外観テーマを選択", "options": { "light": "ライトモード", "dark": "ダークモード", "system": "システム設定に従う" } }, "language": { "title": "言語", "desc": "アプリケーションの表示言語を選択" }, "scale": { "title": "インターフェーススケール", "desc": "アプリケーションインターフェースの全体的なスケールを調整", "placeholder": "スケール比率を選択" }, "contentTextScale": { "title": "本文スケール", "desc": "エディターとチャットの Markdown コンテンツのテキストサイズを調整" }, "fileManagerTextSize": { "title": "ファイルマネージャーのテキストサイズ", "desc": "ファイルマネージャーのファイルとフォルダーリストのテキストサイズを調整" }, "recordTextSize": { "title": "記録のテキストサイズ", "desc": "記録リストの記録項目のテキストサイズを調整" }, "customCss": { "title": "カスタム CSS", "desc": "カスタム CSS スタイルを追加してアプリケーションのデフォルトスタイルを上書き", "button": "CSS を編集", "dialogTitle": "カスタム CSS", "dialogDesc": "以下にカスタム CSS コードを入力して、アプリケーションのデフォルトスタイルを上書きします。保存をクリックして変更を適用します。", "placeholder": "ここにカスタム CSS コードを入力", "save": "保存", "cancel": "キャンセル" }, "tray": { "enabled": { "title": "トレイを有効にする", "desc": "ウィンドウを閉じる時にトレイに最小化するかアプリを終了するか選択" } }, "customTheme": { "title": "自定义主题颜色", "desc": "自定义应用的主题颜色,包括背景色、前景色、边框色等", "button": "编辑颜色", "dialogTitle": "自定义主题颜色", "dialogDesc": "配置自定义主题颜色。颜色更改会实时保存并生效,同时覆盖亮色和暗色主题。", "close": "閉じる", "reset": "重置全部", "tabs": { "custom": "自定义", "presets": "预设方案", "importExport": "导入导出" }, "export": { "title": "导出配色方案", "button": "生成导出代码", "placeholder": "点击生成按钮将当前配色导出为代码" }, "import": { "title": "导入配色方案", "button": "导入配色", "placeholder": "粘贴配色方案的 JSON 代码" }, "colors": { "background": "背景色", "foreground": "前景色", "card": "卡片背景色", "cardForeground": "卡片前景色", "primary": "主色调", "primaryForeground": "主色调前景色", "secondary": "次要色调", "secondaryForeground": "次要色调前景色", "third": "第三色调", "thirdForeground": "第三色调前景色", "muted": "柔和色", "mutedForeground": "柔和色前景色", "accent": "强调色", "accentForeground": "强调色前景色", "border": "边框色", "shadow": "阴影色" }, "presets": { "apply": "应用", "reset": { "name": "恢复默认" }, "default": { "name": "默认白色" }, "ocean": { "name": "海洋蓝" }, "forest": { "name": "森林绿" }, "sunset": { "name": "日落红" }, "lavender": { "name": "薰衣草紫" }, "midnight": { "name": "午夜暗" }, "deepSea": { "name": "深海蓝" }, "darkForest": { "name": "暗夜绿" }, "darkViolet": { "name": "紫罗兰暗" }, "coralWarm": { "name": "珊瑚暖" }, "slateGray": { "name": "石板灰" }, "darkGold": { "name": "暗夜金" }, "beigeWarm": { "name": "米黄暖" }, "beigeDark": { "name": "米黄暗" } } } }, "tools": { "title": "ツール設定", "chatToolbar": { "title": "チャットツールバー", "desc": "チャットツールバーボタンの表示順序と可視性をカスタマイズ", "button": "設定", "dialogTitle": "チャットツールバーを構成", "dialogDesc": "ツールをドラッグして順序を調整し、スイッチを使用して表示または非表示を制御", "groups": { "pc": "PC", "mobile": "モバイル", "bottom": "下部ツールバー", "topLeft": "上部ツールバー - 左側", "topRight": "上部ツールバー - 右側" } }, "recordToolbar": { "title": "記録ツールバー", "desc": "記録ツールバーボタンの表示順序と可視性をカスタマイズ", "button": "設定", "dialogTitle": "記録ツールバーを構成", "dialogDesc": "ツールをドラッグして順序を調整し、スイッチを使用して表示または非表示を制御" }, "desc": "配置各种工具栏按钮的显示和排序" } }, "rag": { "title": "知識庫", "desc": "ここでは、知識庫に関する設定を構成できます。知識庫は、RAG技術に基づいて、埋め込みモデルを使用してテキストをベクトルに変換し、ベクトル検索を介して智能的な検索と智能的な回答を達成します。", "settingsTitle": "パラメータ設定", "settingsDesc": "パラメータを調整することで、知識庫の検索結果をより正確に制御できます。", "deleteVectorConfirm": "知識庫を空にしますか?", "deleteVectorSuccess": "知識庫を空にしました", "enable": "知識庫検索を有効にする", "enableDesc": "有効にすると、AI は回答問題時にあなたのノート内容を検索して、より正確な回答を提供します。", "chunkSize": "ブロックサイズ", "chunkSizeDesc": "テキストをブロックに分割する最大文字数。より大きなブロックはより多くの文脈を含む可能性がありますが、ベクトル計算の複雑さを増加させます。", "chunkOverlap": "重叠サイズ", "chunkOverlapDesc": "テキストブロック間の重叠文字数。より大きな重叠は上下文の連続性を維持できます。", "resultCount": "検索結果数", "resultCountDesc": "検索時に返される関連するドキュメント数。数が多いと提供される情報がより豊富かもしれませんが、ノイズも増加する可能性があります。", "similarityThreshold": "類似度閾値", "similarityThresholdDesc": "ドキュメントとクエリの最小類似度閾値。この閾値を超えるドキュメントのみが返されます。値の範囲は 0.0-1.0、高いほど厳格です。", "resetToDefaults": "デフォルト値に戻す", "deleteVector": "知識庫を空にする", "topPDesc": "Top P パラメータはモデルが生成するテキストの多様性を制御します。値が小さいほど出力は決定论的になり、値が大きいほど多様になります。" }, "mcp": { "title": "MCP", "desc": "Model Context Protocol により、AI は外部ツールを呼び出してリソースにアクセスでき、AI の能力を拡張します。", "servers": "サーバーリスト", "serversDesc": "MCP サーバー設定を管理します。各サーバーは異なるツールとリソースを提供できます。", "addServer": "サーバーを追加", "addFirstServer": "最初のサーバーを追加", "editServer": "サーバーを編集", "serverName": "サーバー名", "serverNamePlaceholder": "例:ファイルシステムサーバー", "serverEnabled": "サーバーを有効にする", "serverEnabledDesc": "有効にすると、このサーバーは自動的に接続してツールを提供します。", "serverType": "サーバータイプ", "stdio": "ローカルコマンド", "http": "HTTP サービス", "command": "コマンド", "args": "引数", "argsDesc": "コマンドライン引数、スペースで区切る", "env": "環境変数", "envDesc": "JSON 形式の環境変数設定", "url": "サービス URL", "headers": "リクエストヘッダー", "headersDesc": "JSON 形式の HTTP リクエストヘッダー", "testConnection": "接続テスト", "test": "テスト", "testSuccess": "接続テスト成功", "testFailed": "接続テスト失敗", "connected": "接続済み", "connecting": "接続中", "disconnected": "未接続", "error": "エラー", "tools": "ツール", "noServers": "MCP サービスが有効になっていません", "noServersFound": "一致するサーバーが見つかりません", "serverAdded": "サーバーを追加しました", "serverUpdated": "サーバーを更新しました", "serverDeleted": "サーバーを削除しました", "deleteServerTitle": "サーバーを削除", "deleteServerDesc": "このサーバーを削除してもよろしいですか?この操作は元に戻せません。", "nameRequired": "サーバー名を入力してください", "commandRequired": "コマンドを入力してください", "urlRequired": "サービス URL を入力してください", "toolBrowser": "ツールブラウザ", "searchTools": "ツールを検索...", "noToolsFound": "ツールが見つかりません", "parameters": "パラメータ", "testAll": "すべての接続をテスト", "testAllCompleted": "すべての接続テストが完了しました", "testAllFailed": "接続テストに失敗しました", "save": "保存", "cancel": "キャンセル", "delete": "削除", "importJson": "JSON をインポート", "jsonImportTitle": "JSON からサーバー設定をインポート", "jsonImportDesc": "MCP サーバーの mcpServers 設定形式を貼り付けます", "jsonInput": "JSON 設定", "jsonInputHelp": "mcpServers 形式をサポート、サーバー名が自動的に key として使用されます", "jsonRequired": "JSON 設定を入力してください", "jsonEmpty": "JSON 設定は空にできません", "jsonInvalidJson": "JSON 形式が無効です", "jsonInvalidFormat": "設定形式が無効です、name と type フィールドを含む必要があります", "jsonInvalidType": "サーバータイプは stdio または http である必要があります", "jsonMissingCommand": "stdio タイプのサーバーは command を指定する必要があります", "jsonMissingUrl": "http タイプのサーバーは url を指定する必要があります", "jsonImportSuccess": "{count} 個のサーバーを正常にインポートしました", "jsonImportSkipped": "{count} 個の既存サーバーをスキップしました", "jsonImportNoServers": "サーバーがインポートされませんでした", "import": "インポート", "mobileHttpOnlyTitle": "ローカルコマンド MCP はデスクトップ専用です", "mobileHttpOnlyDesc": "ローカルコマンド型 MCP サーバーはデスクトップでのみ利用できます。モバイルでは現在 HTTP MCP のみサポートします。", "runtimeEnvironment": "ランタイム環境", "runtimeEnvironmentDesc": "MCP サーバーをテストする前に、必要なローカルランタイムが利用可能か確認します。", "checkEnvironment": "環境を確認", "recheckEnvironment": "再チェック", "runtimeCheckFailed": "環境チェックに失敗しました", "detectedLauncher": "検出されたランチャー", "runtimeInstalled": "インストール済み", "runtimeMissing": "未検出", "runtimeVersion": "バージョン", "runtimeInstalledSummary": "{installed}/{total} がインストール済み", "showRuntimeDetails": "ランタイムの詳細を表示", "hideRuntimeDetails": "ランタイムの詳細を隠す", "runtimeNotChecked": "このランタイムはまだ確認していません。", "runtimeCurrentUserScope": "対応している場合、推奨コマンドは現在のユーザー環境にインストールします。", "runtimeManualOnly": "このプラットフォームでは自動インストールに対応していません。手動でインストールしてから再チェックしてください。", "installRuntime": "ランタイムをインストール", "runtimeInstallTitle": "ランタイムをインストール", "runtimeInstallDesc": "確認後、NoteGen は以下のインストールコマンドを実行します。", "runtimeInstallPreparing": "インストールを準備中", "runtimeInstallRunning": "インストール中", "runtimeInstallCompleted": "インストール完了", "runtimeInstallCancelled": "キャンセル済み", "runtimeInstallFailedState": "インストール失敗", "runtimeInstallLogs": "インストールログ", "runtimeInstallWaitingLogs": "インストール出力を待機中...", "runtimeInstallClose": "閉じる", "runtimeInstallCancel": "インストールを停止", "runtimeInstallCancelledByUser": "ユーザーがインストールのキャンセルを要求しました。", "runtimeInstallCancelFailed": "インストールの停止に失敗しました", "runtimeInstallSuccess": "ランタイムのインストールが完了しました", "runtimeInstallFailed": "ランタイムのインストールに失敗しました", "runtimeNoGuidedSupport": "このコマンドにはまだガイド付きランタイム補助がありません。" , "enableTitle": "启用 MCP 功能", "enableDesc": "启用后,AI 可以调用配置的 MCP 服务器提供的工具。" }, "editor": { "title": "エディター設定", "interfaceSettings": "インターフェース設定", "desc": "ここでは、エディターをカスタマイズして、より適した書き込み体験を提供できます。", "centeredContent": "コンテンツを中央に表示", "centeredContentDesc": "有効にすると、コンテンツを中央に表示し、両側に余白を設けます。", "outlineEnable": "アウトラインを有効にする", "outlineEnableDesc": "アウトラインを有効にすると、アウトラインが表示されます。", "outlinePosition": "アウトライン位置", "outlinePositionDesc": "アウトライン位置を設定します。", "outlinePositionOptions": { "left": "左側", "right": "右側" }, "showUndoRedo": "元に戻す/やり直しボタン", "showUndoRedoDesc": "エディターのタブバーに元に戻すボタンとやり直しボタンを表示します。", "completion": { "title": "自動補完", "model": { "title": "自動補完モデル", "desc": "エディターの AI インライン補完に使用するモデルを選択" } }, "commit": { "title": "自動コミットメッセージ", "model": { "title": "コミットモデル", "desc": "ファイルの変更に基づいて Git コミットメッセージを自動生成するためのモデル" } }, "mermaid": { "title": " диаграмма", "rendering": "レンダリング中...", "renderError": "レンダリングエラー", "clickToEdit": "クリックしてソースを編集", "clickToAdd": "クリックして диаграммаを追加", "placeholder": "Mermaid диаграммаコードを入力...", "preview": "プレビュー", "done": "完了", "diagramTypes": { "flowchart": "フローチャート", "sequence": "シーケンス", "classDiagram": "クラス図", "stateDiagram": "ステート図", "er": "ER図", "gantt": "ガントチャート", "pie": "円グラフ", "journey": "ジャーニー" }, "templates": { "flowchart": "graph TD\n A[開始] --> B[処理]\n B --> C[終了]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: こんにちは\n Bob-->>Alice: 返信", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title プロジェクト計画\n dateFormat YYYY-MM-DD\n section 第一フェーズ\n タスク1 :a1, 2024-01-01, 30d\n section 第二フェーズ\n タスク2 :after a1, 20d", "pie": "pie title リソース割り当て\n \"CPU\" : 45\n \"メモリ\" : 30\n \"ストレージ\" : 25", "journey": "journey\n title 私の日常工作\n section 午前\n 通勤 : 7:00, 5\n 仕事 : 9:00, 8" } } }, "record": { "title": "記録設定", "desc": "ここでは、記録関連の設定を構成できます。記録の説明やツールバーの設定などが含まれます。", "model": { "title": "モデル設定", "markDesc": { "title": "記録説明", "desc": "OCR で認識された記録を処理し、記録の説明を生成するためのモデル" } }, "toolbar": { "title": "ツールバー設定", "recordToolbar": { "title": "記録ツールバー", "desc": "記録ツールバーボタンの表示順序と可視性をカスタマイズ", "button": "設定", "text": { "desc": "记录文本内容" }, "recording": { "desc": "录音记录功能" }, "scan": { "desc": "扫描识别图片中的文字" }, "image": { "desc": "上传图片到笔记" }, "link": { "desc": "记录网页链接" }, "file": { "desc": "上传文件到笔记" }, "todo": { "desc": "创建待办事项" } } } }, "uploadStore": { "uploadConfirm": "同期リポジトリをプライベートに設定してください。", "downloadConfirm": "ダウンロード配置をローカル配置に上書きし、再起動して有効になります。", "uploadSuccess": "配置を成功しました", "downloadSuccess": "配置を成功しました", "upload": "Upload", "download": "Download" }, "prompt": { "title": "マスク", "promptTitle": "マスク名称", "desc": "ここでマスクを追加・管理し、AIがあなたのニーズをよりよく理解できるようにします。", "addPrompt": "マスクを追加", "selectPrompt": "マスクを選択", "configPrompt": "マスクを設定", "noContent": "内容がありません", "addPromptDesc": "マスク名と内容を入力し、AIがあなたのニーズをよりよく理解できるようにしてください。", "promptTitlePlaceholder": "マスク名を入力してください", "promptContentPlaceholder": "マスク内容を入力してください", "promptContent": "マスク内容", "optimizePrompt": "プロンプト最適化", "optimizing": "最適化中...", "optimizeSuccess": "プロンプトの最適化が成功しました", "optimizeFailed": "プロンプトの最適化に失敗しました。後でもう一度お試しください", "noContentToOptimize": "まずプロンプト内容を入力してください" }, "memories": { "title": "記憶管理", "desc": "AI長期記憶機能で、AIがあなたの執筆設定、知識ベース、メモ習慣を記憶します。", "stats": { "total": "総記憶数", "preferences": "設定", "knowledge": "知識", "memories": "记忆" }, "form": { "title": "新しい記憶を追加", "contentLabel": "記憶の内容", "contentPlaceholder": "例:中国語で回答してほしい、Reactエキスパートです...", "categoryLabel": "タイプ", "preferenceDesc": "設定(言語、形式、スタイルなど)", "knowledgeDesc": "知識(事実、経験、専門分野など)", "save": "記憶を保存", "saving": "保存中...", "categoryDescription": "记忆分为两种类型:", "preferenceDescription": "偏好:语言、格式、风格等设置,每次对话都会自动加载", "memoryDescription": "记忆:事实、经验、专长等信息,根据对话内容智能匹配", "preferenceLabel": "偏好", "memoryLabel": "记忆", "memoryDesc": "事实、经验、专长等" }, "listTitle": "マイ記憶", "addMemory": "記憶を追加", "empty": "まだ記憶がありません。最初の記憶を追加しましょう!", "emptyHint": "手動で記憶を追加するか、会話で「覚えて」「これを覚えて」などのフレーズを使うとAIが自動的に記憶を作成します。", "preference": "設定", "knowledge": "知識", "replaced": "置換済み", "accessCount": "{count} 回アクセス", "tabs": { "all": "すべて", "preference": "設定", "knowledge": "知識", "memory": "记忆" }, "success": "成功", "saved": "記憶を保存しました", "updated": "記憶を更新しました(類似の記憶を置換)", "deleted": "記憶を削除しました", "cleared": "すべての記憶をクリアしました", "found": "{count} 件の記憶が見つかりました", "error": "エラー", "errorEmpty": "記憶の内容を入力してください", "errorSave": "保存に失敗しました", "errorDelete": "削除に失敗しました", "errorList": "記憶リストの取得に失敗しました", "errorEmbedding": "埋め込みの生成に失敗しました。埋め込みモデルの設定を確認してください", "errorClear": "クリアに失敗しました", "memory": "记忆" }, "defaultModel": { "title": "デフォルトモデル", "desc": "ここでは、異なるシーンに応じて異なるモデルを使用し、効率を高めコストを削減できます。", "tooltip": "メインモデルを使用", "noModel": "使用しない", "placeholder": "モデルを選択または検索してください", "main": "メインモデル", "options": { "primaryModel": { "title": "メインモデル", "desc": "すべてのシーンのメインモデルとして、他の会話モデルがデフォルトモデルを選択していない場合、このモデルを使用します。" }, "markDesc": { "title": "記録の説明", "desc": "OCR認識後の記録を処理し、記録の説明を生成します。" }, "placeholder": { "title": "AI提案", "desc": "記録ページのAI会話プレースホルダーコンテンツ生成用のAI提案プロンプト。" }, "completion": { "title": "高速補完", "desc": "Markdownエディタ用のAIインライン補完、GitHub Copilotに類似、素早く続きの内容を生成します。" }, "commit": { "title": "コミットメッセージを自動生成", "desc": "Gitコミットメッセージを自動生成するために使用され、ファイルの内容変更に基づいて記述的なコミットメッセージをインテリジェントに生成します。" }, "embedding": { "title": "埋め込みモデル", "desc": "テキスト埋め込みとベクトル化のシナリオに使用されます。" }, "reranking": { "title": "再ランキングモデル", "desc": "検索結果の並べ替えと最適化に使用されます。" }, "condense": { "title": "摘要模型", "desc": "用于压缩历史对话内容,节省 token 使用量" } }, "mainModel": "メインモデル" }, "readAloud": { "title": "音声読み上げ", "desc": "ここでは、音声読み上げ関連の設定を構成し、チャットコンテンツに音声再生機能を提供できます。", "noModel": "モデルを使用しない", "options": { "audioModel": { "title": "音声モデル", "desc": "テキストから音声への変換にAIモデルを選択し、様々な音声タイプとパラメータ設定をサポートします。" }, "speed": { "title": "読み上げ速度", "desc": "音声の再生速度を調整します。0.25倍から4倍の範囲で設定でき、1倍が通常の速度です。" } } }, "about": { "title": "このアプリについて", "desc": "記録と執筆に特化したメモ取りアシスタント。", "version": "NoteGen v{version}", "checkReleases": "過去のバージョンを確認", "language": "言語", "checkUpdate": "アップデートを確認", "checkError": "アップデートの確認に失敗しました", "updateAvailable": "新しいバージョンが利用可能です", "updateDownloading": "更新中 {downloaded} / {contentLength}", "updateInstalled": "アプリを再起動", "noUpdate": "現在は最新バージョンです", "ignoreVersion": "このバージョンを無視", "ignoreVersionSuccess": "このバージョンの更新を無視しました", "items": { "home": { "title": "公式サイト", "buttonName": "表示", "desc": "公式サイトを表示して、NoteGenの詳細を確認できます。" }, "guide": { "title": "ガイド", "buttonName": "表示", "desc": "配置ガイドを表示して、モデル、同期などの情報の設定方法を学ぶことができます。" }, "github": { "title": "GitHub", "buttonName": "表示", "desc": "NoteGenが役立った場合は、鼓励するには、GitHubにスターを付けてください!" }, "releases": { "title": "更新日志", "buttonName": "表示", "desc": "更新日志を表示して、NoteGenの更新内容を確認できます。" }, "issues": { "title": "問題報告", "buttonName": "報告", "desc": "NoteGenにバグを見つけた場合は、ここに報告してください。" }, "discussions": { "title": "ディスカッション", "buttonName": "参加", "desc": "作者や他のユーザーとディスカッションを参加できます。" } } }, "sync": { "title": "同期", "desc": "ここでは、同期リポジトリを設定することができます。ログ、markdownファイル、システム設定などの情報を同期するのに役立ちます。", "selectPlatform": "同期プラットフォームを選択", "platformSettings": "プラットフォームを選択", "settings": "同期設定", "platformDesc": "Tokenとリポジトリ情報を設定して同期を有効にします", "moreSettings": "その他の設定", "repoStatus": "リポジトリの状態", "syncRepo": "同期リポジトリ", "syncRepoDesc": "執筆中のMarkdownファイルを同期", "imageRepo": "画像ホスティング倉庫", "imageRepoDesc": "あなたの画像を画像ホスティングリポジトリに同期します。", "status": { "connected": "接続済み", "disconnected": "未接続", "failed": "接続失敗", "unconfigured": "未設定" }, "uploadRecords": "レコードと設定をアップロード", "downloadConfig": "レコードと設定をダウンロード", "cloudSync": "レコードと設定の同期", "localBackupAll": "ローカルバックアップ(全て)", "private": "非公開", "public": "公開", "createdAt": "{time} に作成", "updatedAt": "最終更新: {time}", "newToken": "作成 access token", "newTokenDesc": "新しいトークンを作成する際は必ずrepo権限を選択してください。設定後、自動的にプライベートリポジトリと画像ホスティングリポジトリが作成されます。", "giteeTokenDesc": "Giteeの個人アクセストークンはデータ同期に使用されます。リポジトリの読み書き権限が必要です。設定後、自動的にファイルリポジトリ(プライベート)と画像リポジトリが作成されます。", "imageRepoSetting": "画像ホスティングを有効化", "imageRepoSettingDesc": "画像ホスティングリポジトリが設定されています。有効にすると画像はそちらに保存され、無効の場合はローカル保存となります。", "jsdelivrSetting": "jsDelivr", "jsdelivrSettingDesc": "jsdelivrを利用して画像アクセスを高速化します。", "autoSync": "自動同期", "autoSyncDesc": "有効にすると、エディターは入力停止から10秒後にGitHubに自動同期します", "giteeAutoSyncDesc": "有効にすると、エディターは入力停止から10秒後にGiteeに自動同期します", "customSyncRepo": "カスタム同期リポジトリ名", "customSyncRepoDesc": "空白の場合はデフォルトのリポジトリ名を使用", "customImageRepo": "カスタム画像リポジトリ名", "customImageRepoDesc": "空白の場合はデフォルトのリポジトリ名を使用", "backupMethod": "バックアップ方法", "backupMethodDesc": "主要バックアップ方法として設定すると、文章作成中のすべての同期関連機能が現在のバックアップ方法を使用します(画像ホスティング機能を除く)", "createRepo": "リポジトリを作成", "creating": "作成中", "checkRepo": "リポジトリを確認", "checking": "確認中", "enterToken": "Access Tokenを入力してください", "enterTokenHint": "リポジトリ的状态を確認するには、先にAccess Tokenを入力してください", "gitlabInstanceType": "GitLab インスタンスタイプ", "gitlabInstanceTypeDesc": "接続する GitLab インスタンスタイプを選択してください", "gitlabInstanceTypePlaceholder": "GitLab インスタンスタイプを選択してください", "gitlabInstanceTypeOptions": { "selfHosted": "自建インスタンス", "selfHostedDesc": "自建 GitLab インスタンスの URL を入力してください(例:https://gitlab.example.com)" }, "gitlabAccessTokenDesc": "{instanceDisplayName}でパーソナルアクセストークンを作成するには、api権限が必要です", "autoSyncOptions": { "placeholder": "自動同期時間", "disabled": "無効", "2s": "2 秒", "3s": "3 秒", "5s": "5 秒", "10s": "10 秒", "20s": "20 秒", "30s": "30 秒", "1m": "1 分", "2m": "2 分" }, "autoPullOnOpen": "ファイルを開く時に自動プル", "autoPullOnOpenDesc": "ファイルを開く時、リモートに新しいバージョンがある場合は自動的にプルしてローカルを上書き", "autoPullOnSwitch": "ファイルを切り替える時に自動プル", "autoPullOnSwitchDesc": "他のファイルに切り替える時、リモートに新しいバージョンがある場合は自動的にプルしてローカルを上書き", "exclusions": { "title": "同期除外設定", "desc": "以下の設定はデバイス固有のものであるため、デバイス間で同期されません", "workspacePath": "ワークスペースパス", "workspaceHistory": "ワークスペース履歴", "assetsPath": "リソースパス", "uiScale": "UIスケール", "contentTextScale": "コンテンツテキストスケール", "customCss": "カスタムCSS", "reason": "これらの設定はデバイスによって異なる場合があるため、同期から除外することでパスエラーなどの問題を回避できます" }, "settingsSync": { "uploadSuccess": "設定のアップロードに成功しました", "uploadFailed": "設定のアップロードに失敗しました", "downloadSuccess": "設定のダウンロードに成功しました", "downloadFailed": "設定のダウンロードに失敗しました", "autoSync": "アップロード/ダウンロード時に設定が自動的に同期されます(ワークスペースパスなどのデバイス固有の設定を除く)" }, "defaultRepoName": "默认: {name}", "giteaInstanceType": "Gitea 实例类型", "giteaInstanceTypeDesc": "选择要连接的 Gitea 实例类型", "giteaInstanceTypePlaceholder": "选择 Gitea 实例类型", "giteaInstanceTypeOptions": { "selfHosted": "自建实例", "selfHostedDesc": "输入您的自建 Gitea 服务器地址(如:https://gitea.example.com)" }, "giteaAccessTokenDesc": "在 {instanceDisplayName} 创建个人访问令牌,需要完整的 repository 权限", "s3": { "title": "S3 同期", "description": "S3互換ストレージを使用してノートを同期します", "status": "接続状態", "connected": "接続済み", "connecting": "接続中", "disconnected": "未接続", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "Access Key IDを入力してください", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "Secret Access Keyを入力してください", "region": "リージョン", "bucket": "バケット", "bucketPlaceholder": "バケット名を入力してください", "endpoint": "エンドポイント", "pathPrefix": "パスプレフィックス", "pathPrefixPlaceholder": "パスプレフィックスを入力してください", "pathPrefixDesc": "異なるユーザーのファイルを区別するために使用、リポジトリ名に類似", "customDomain": "カスタムドメイン", "testConnection": "接続テスト", "testing": "テスト中", "saveConfig": "設定を保存", "saving": "保存中" }, "webdav": { "title": "WebDAV 同期", "description": "WebDAVプロトコルを使用してノートを同期します", "status": "接続状態", "connected": "接続済み", "connecting": "接続中", "disconnected": "未接続", "url": "サーバーURL", "urlPlaceholder": "WebDAV サーバーURLを入力してください", "urlDesc": "Synology、QNAP、Nextcloud などのWebDAVサービスをサポート", "username": "ユーザー名", "usernamePlaceholder": "ユーザー名を入力してください", "password": "パスワード", "passwordPlaceholder": "パスワードを入力してください", "pathPrefix": "パスプレフィックス", "pathPrefixPlaceholder": "パスプレフィックスを入力してください", "pathPrefixDesc": "異なるユーザーのファイルを区別するために使用", "testConnection": "接続テスト", "testing": "テスト中", "saveConfig": "設定を保存", "saving": "保存中" } }, "imageHosting": { "title": "画像ホスティング", "desc": "ここでは、画像の保存と管理のための画像ホスティングサービスを設定できます。", "type": "プラットフォームを選択", "typeDesc": "画像ホスティングサービスを選択", "customRepoName": "カスタムリポジトリ名", "customRepoNameDesc": "空白の場合はデフォルトのリポジトリ名を使用", "isPrimaryBackup": "現在の {type} 主要バックアップ方法", "setPrimaryBackup": "主要バックアップ方法として設定", "smms": { "token": { "desc": "SM.MS Token を入力してください。", "createToken": "Token を作成" }, "disk": "磁盘使用", "error": "取得失敗、ネットワークや Token の正しさを確認してください。" }, "picgo": { "desc": "PicGo サーバー URL", "ok": "サービスが起動しています。PicGo の設定を確認してください。", "error": "サービスが起動していません。PicGo(v2.2.0+)を起動してください。" }, "github": { "title": "GitHub画像ホスティング", "description": "GitHubリポジトリを画像ストレージサービスとして使用", "repoStatus": "リポジトリステータス", "repoExists": "リポジトリが存在します", "repoNotExists": "リポジトリが見つかりません", "checking": "確認中", "creating": "作成中", "manualCreateTitle": "手動でリポジトリ作成が必要", "manualCreateDesc": "以下の手順で画像ホスティングリポジトリを作成してください:", "createSteps": { "step1": "GitHubにアクセスしてアカウントにログイン", "step2": "右上の「+」ボタンをクリックし、「New repository」を選択", "step3": "リポジトリ名を設定:", "step4": "プライベートリポジトリに設定することも可能(推奨)", "step5": "「Create repository」をクリックして作成完了", "step6": "作成後、下の「再確認」ボタンをクリック" }, "createNewRepo": "新しいリポジトリを作成", "recheckRepo": "再確認", "recheckingRepo": "確認中...", "createRepo": "リポジトリを作成", "creatingRepo": "作成中..." }, "s3": { "title": "S3オブジェクトストレージ", "description": "AWS S3またはS3互換オブジェクトストレージサービスを画像ホスティングとして設定", "status": "接続状態", "connected": "接続済み", "connecting": "接続中", "disconnected": "未接続", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "Access Key ID を入力", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "Secret Access Key を入力", "region": "リージョン", "bucket": "バケット", "bucketPlaceholder": "バケット名を入力", "advancedSettings": "詳細設定", "endpoint": "カスタムエンドポイント", "endpointDesc": "AWS S3 の場合は空白、S3 互換サービスのエンドポイントを入力", "customDomain": "カスタムドメイン", "customDomainDesc": "オプション、画像アクセス用のカスタムドメイン", "pathPrefix": "パスプレフィックス", "pathPrefixDesc": "オプション、画像保存のパスプレフィックス", "save": "設定を保存", "test": "接続テスト", "setAsPrimary": "メインに設定", "error": "設定エラー", "requiredFields": "必須フィールドを入力してください:Access Key ID、Secret Access Key、リージョン、バケット", "saveSuccess": "設定保存成功", "saveSuccessDesc": "S3 設定が保存されました", "saveError": "設定保存失敗", "testSuccess": "接続テスト成功", "testSuccessDesc": "S3 接続正常、画像アップロード可能", "testFailed": "接続テスト失敗", "testFailedDesc": "設定情報とネットワーク接続を確認してください", "testFirstDesc": "メイン画像ホスティングに設定する前に接続テストを成功させてください", "setPrimarySuccess": "設定成功", "setPrimarySuccessDesc": "S3 がメイン画像ホスティングに設定されました" } }, "imageMethod": { "title": "画像認識", "desc": "ここでは、画像認識に関する設定を配置できます。OCR と VLM の二つの方法をサポートします。", "enable": { "title": "画像認識を有効にする", "desc": "有効にすると、スクリーンショット記録と画像記録時に自動的に画像認識が行われます。無効にすると、画像認識がスキップされます。" }, "setPrimary": "設定をデフォルト", "isPrimary": "{type} がデフォルト設定", "ocr": { "title": "OCR", "languagePacks": "言語パック", "checkModels": "ここでは、すべてのモデルを検索できます。", "modelInstruction": "逗号分隔、例如:eng,chi_sim" }, "vlm": { "title": "視覚的言語モデル", "desc": "視覚的言語モデルを使用して画像内容を認識します。" } }, "backupSync": { "title": "備用方案", "desc": "ここでは、他の方法でデータをバックアップすることができます。定期的にバックアップを取ることで、データの安全を確保できます。", "localBackup": { "tabTitle": "ローカルバックアップ", "export": { "title": "バックアップのエクスポート", "desc": "アプリケーションデータを .zip ファイルにパッケージし、指定した場所に保存します。", "button": "場所を選択してエクスポート", "simpleButton": "エクスポート", "exporting": "エクスポート中..." }, "import": { "title": "バックアップのインポート", "desc": ".zip ファイルからアプリケーションデータを復元し、現在のすべてのデータを上書きします。", "button": "ファイルを選択してインポート", "importing": "インポート中...", "warning": "インポート操作により現在のすべてのデータが上書きされます。重要なコンテンツがバックアップされていることを確認してください!" }, "exportDialog": { "title": "バックアップファイルの保存場所を選択" }, "importDialog": { "title": "インポートするバックアップファイルを選択" }, "exportSuccess": "バックアップのエクスポートが成功しました!", "exportError": "バックアップのエクスポートに失敗しました", "importSuccess": "バックアップのインポートが成功しました!変更を適用するためにアプリケーションが再起動されます。", "importError": "バックアップのインポートに失敗しました", "restartConfirm": "インポートが完了しました!変更を適用するために今すぐアプリケーションを再起動しますか?" } }, "template": { "title": "整理テンプレート", "desc": "ここでは、カスタム整理テンプレートを作成・管理し、AIがあなたのニーズに応じて記録内容を整理するのを支援できます。", "customTemplate": "カスタムテンプレート", "addTemplate": "テンプレートを追加", "deleteConfirm": "このテンプレートを削除してもよろしいですか?", "status": "状態", "name": "名称", "content": "内容", "scope": "範囲", "selectScope": "範囲を選択", "addTemplateDesc": "カスタムテンプレート名称と内容を入力し、AIがあなたのニーズをよりよく理解できるようにしてください。", "editTemplate": "編集カスタムテンプレート", "noContent": "内容がありません", "range": { "all": "すべて", "today": "今日", "week": "過去1週間", "month": "過去1ヶ月", "threeMonth": "過去3ヶ月", "year": "過去1年" } }, "shortcut": { "title": "ショートカットキー", "screenshot": "スクリーンショット記録", "link": "链接記録", "textRecord": "テキスト記録", "windowPin": "ウィンドウをピン留め" }, "theme": { "title": "外観", "appTheme": "アプリテーマ", "previewTheme": "プレビュー用テーマ", "codeTheme": "コードブロックのハイライトテーマ", "selectTheme": "テーマを選択" }, "chat": { "title": "会話設定", "desc": "ここでは、要約生成など会話関連の設定を構成できます。", "primaryModel": { "title": "メインモデル", "model": { "title": "メインチャットモデル", "desc": "日常会話に使用するメインの AI モデルを選択" } }, "toolbar": { "title": "ツールバー設定", "chatToolbar": { "title": "チャットツールバー", "desc": "チャットツールバーボタンの表示順序と可視性をカスタマイズ", "button": "設定", "modelSelect": { "desc": "会話に使用する AI モデルを切り替え" }, "promptSelect": { "desc": "会話で使用するプリセットプロンプトを選択" }, "chatLanguage": { "desc": "会話の言語を設定" }, "chatLink": { "title": "タグをリンク", "desc": "現在のタグのノート内容を会話コンテキストにリンク" }, "fileLink": { "desc": "ファイルまたはフォルダーを会話コンテキストにリンク" }, "mcpButton": { "desc": "MCP サーバーを選択して接続し、外部ツールを使用" }, "ragSwitch": { "title": "ナレッジベース", "desc": "ベクトルナレッジベース検索を有効にする" }, "clipboardMonitor": { "title": "クリップボード監視", "desc": "クリップボードの内容の変更を自動監視" }, "newChat": { "desc": "新しい会話を開始" }, "clearContext": { "desc": "会話コンテキストをクリアし、チャット履歴を保持" }, "clearChat": { "desc": "すべてのチャット記録を削除" } } }, "condense": { "title": "会話の要約", "enable": { "title": "要約を有効にする", "desc": "長い会話を自動的に圧縮してトークン使用量を節約" }, "model": { "title": "要約モデル", "desc": "要約生成に使用する AI モデルを選択", "placeholder": "メインモデルを使用" }, "threshold": { "title": "トリガーしきい値", "desc": "AI メッセージがこの数を超えたときに圧縮をチェック" }, "minToken": { "title": "最小トークン数", "desc": "このトークン数を超えるメッセージのみを圧縮" }, "keepLatest": { "title": "最新を保持", "desc": "最新の N 件の AI メッセージを圧縮しない" }, "maxLength": { "title": "要約の最大長", "desc": "生成される要約の最大文字数を制御" }, "prompt": { "title": "カスタム要約プロンプト", "desc": "要約生成に使用するプロンプトテンプレートをカスタマイズ", "label": "プロンプトテンプレート", "placeholder": "カスタムプロンプトを入力...", "help": "元のコンテンツのプレースホルダーとして {content} を使用", "save": "保存", "reset": "デフォルトにリセット" } }, "inspiration": { "title": "インスピレーションモデル", "model": { "title": "クイックプロンプト生成", "desc": "会話を開始するためのクイックプロンプト候補を生成します" } }, "conversationTitle": { "title": "会话标题", "model": { "title": "标题生成模型", "desc": "选择用于生成会话标题的 AI 模型" } } }, "dev": { "title": "開発者", "desc": "ここでは、ネットワークプロキシ、データクリーンアップ、設定ファイル管理などの開発者オプションを設定できます。", "clearData": "データをクリア", "clearDataConfirm": "本当にデータをクリアしますか?", "proxy": "ネットワーク問題解決用のプロキシ。設定後はアプリの再起動を推奨します。", "proxyPlaceholder": "プロキシアドレスを入力してください", "proxyTitle": "ネットワークプロキシ", "clearDataTitle": "データをクリア", "clearDataDesc": "システム設定情報とデータベース(記録を含む)をクリアします。", "clearFileTitle": "ファイルをクリア", "clearFileDesc": "画像や記事などのファイルをクリアします。", "clearButton": "クリア", "configFileTitle": "設定ファイル管理", "configFileDesc": "設定ファイルのインポートとエクスポート。インポートすると現在の設定が上書きされ、再起動後に有効になります。", "importConfigTitle": "設定ファイルをインポート", "exportConfigTitle": "設定ファイルをエクスポート", "importConfigSuccessMobile": "設定のダウンロードに成功しました。手動でアプリを再起動してください", "exportConfigSuccess": "エクスポート成功", "importButton": "インポート", "exportButton": "エクスポート" }, "ai": { "title": "モデル管理", "desc": "ここでさまざまなカスタムモデルサービスを追加・管理できます。設定後、整理や会話などAI機能が有効になります。", "modelTitle": "カスタム名", "modelConfigTitle": "モデル配置", "modelConfigDesc": "それぞれの構成はAIモデルに対応しており、テンプレートやカスタムで新しい構成を作成することができます。", "providerInfo": "プロバイダー情報", "providerInfoDesc": "この設定はプロバイダーテンプレートに基づいて作成され、名前とURLが事前設定されています。", "create": "作成", "createDesc": "空の設定を選択するか、供給元のテンプレートを使用して新しい設定を作成します。", "createSection": { "title": "カスタムモデル設定", "descWithoutModels": "カスタムAIモデル設定を追加して、より強力なモデルサービスを使用しましょう。" }, "config": "配置单", "custom": "自定義", "addCustomModel": "自定義", "deleteCustomModel": "削除", "deleteCustomModelConfirm": "この自定義モデル設定を削除してもよろしいですか?", "copyConfig": "コピー", "builtin": "内蔵", "modelSupport": "OpenAIプロトコル対応のAIモデルのみサポート", "apiKeyUrl": "Create API Key", "modelType": { "title": "モデルタイプ", "desc": "能力に基づいてAIモデルのタイプを選択します", "chat": "チャット", "image": "画像生成", "video": "動画", "audio": "音声", "embedding": "埋め込み", "rerank": "再ランキング", "tts": "文本转语音", "stt": "语音转文本" }, "modelList": { "error": { "title": "モデルリストの取得に失敗しました", "description": "API Key またはネットワークを確認してください" } }, "selectModel": "モデルを選択してください", "modelProviderDesc": "自定義モデルOpenAIプロトコル対応のAIモデルのみサポート。", "modelTitleDesc": "カスタム名、用于标识 AI 模型,请勿重复。", "modelBaseUrlDesc": "バージョン番号まで設定すればOKです(例:https://api.openai.com/v1)。サフィックスは自動で追加されます。", "modelDesc": "一部モデルはリスト取得に対応しています。未対応の場合は手動で設定してください。", "temperatureDesc": "サンプリング温度は0から2の間で設定します。高い値(例:0.8)は出力をよりランダムに、低い値(例:0.2)はより決定的にします。通常、この値かtop_pのみを調整してください。", "topPDesc": "top_p(核サンプリング)は温度の代替手法です。top_p=0.1なら上位10%確率のトークンのみ考慮します。通常、この値かtemperatureのみを調整してください。", "customHeaders": "カスタムヘッダー", "customHeadersDesc": "キーと値のペアでカスタムHTTPヘッダーを追加します。", "connectionSuccess": "AI接続テストが成功しました", "headerKey": "キー", "headerValue": "値", "addHeader": "ヘッダーを追加", "voice": "音声タイプ", "voiceDesc": "音声モデルで使用する音声タイプを指定します(例:'alloy'、'echo'、'fable'など)。", "voicePlaceholder": "音声タイプを入力してください(例:alloy)", "defaultModels": { "title": "デフォルト無料モデル", "desc": "NoteGenはユーザーに無料のAIモデルサービスを提供し、設定なしで基本機能を使用できます。", "chatModel": { "name": "Qwen/Qwen3-8B", "type": "チャットモデル", "desc": "日常会話やテキスト生成に適用" }, "embeddingModel": { "name": "BAAI/bge-m3", "type": "埋め込みモデル", "desc": "テキストベクトル化や意味検索に使用" }, "visionModel": { "name": "OpenGVLab/InternVL2-8B", "type": "ビジョンモデル", "desc": "画像理解とビジュアルQ&Aをサポート" }, "completionModel": { "name": "高速補完", "type": "補完モデル", "desc": "Markdownエディタ用のAIインライン補完、GitHub Copilotに類似、素早く続きの内容を生成" }, "poweredBy": "SiliconFlowによる技術サポート" }, "connectionFailed": "接続に失敗しました", "enableStream": "ストリーミングレスポンス", "enableStreamDesc": "ストリーミングレスポンスを有効にすると、生成中のコンテンツをリアルタイムで表示できますが、一部のモデルではこの機能がサポートされていない場合があります。", "selectConfig": "設定を選択してください", "models": "モデルリスト", "modelsDesc": "現在の設定のすべてのモデルをここで管理します。各モデルは異なるタイプとパラメータを持つことができます。", "addModel": "モデルを追加", "newModel": "新しいモデル", "checkConnection": "接続をテスト", "model": "モデル" }, "ocr": { "title": "OCR", "languagePacks": "言語パック", "checkModels": "在此查询全部模型", "modelInstruction": "以逗号分隔,例如:eng,chi_sim" }, "file": { "title": "ファイル管理", "desc": "ここで同期リポジトリを設定し、執筆中のファイルをリポジトリと同期できます。画像ホスティングもサポートしています。", "workspace": { "title": "ワークスペース設定", "desc": "アプリケーションのワークスペースディレクトリを設定します。ファイルはこのディレクトリに保存されます。", "current": "現在のワークスペースパス", "defaultPath": "デフォルトワークスペース", "default": "現在デフォルトのワークスペースパスを使用しています。", "custom": "現在カスタムワークスペースパスを使用しています。", "select": "ワークスペースディレクトリを選択", "reset": "デフォルトパスにリセット", "history": "履歴パス", "selectFromHistory": "履歴からワークスペースを選択", "clearHistory": "履歴をクリア", "actions": "アクション", "searchPlaceholder": "ワークスペースパスを検索...", "noResults": "結果が見つかりません" }, "info": { "title": "ワークスペースの説明", "desc": "ワークスペースを変更した後、完全に反映させるにはアプリケーションを再起動する必要があります。新しいワークスペース内のファイルは再起動後に表示されます。" }, "toast": { "updated": "ワークスペースが更新されました", "updatedDesc": "ワークスペースが次のパスに設定されました: {path}", "reset": "ワークスペースがリセットされました", "resetDesc": "デフォルトのワークスペースに戻りました", "error": "ワークスペースの選択に失敗しました", "errorDesc": "ワークスペースディレクトリを選択できません。再試行してください。", "resetError": "ワークスペースのリセットに失敗しました", "resetErrorDesc": "デフォルトのワークスペースにリセットできません。再試行してください。" }, "assets": { "title": "アセット", "desc": "執筆中のリソース(例:画像、ビデオ、ファイル等)の保存パスを設定します。現在編集中の markdown ファイルと同じレベルに保存されます。", "select": "執筆中のリソースの保存パスを設定してください" } }, "shortcuts": { "title": "ショートカット", "desc": "ここで、NoteGen をより効率的に使用するためのショートカットを設定できます。", "resetDefaults": "リセットします", "clear": "クリア", "noShortcut": "未設定", "shortcuts": { "openWindow": { "title": "ウィンドウを開く/隠す", "desc": "主ウィンドウを開く/隠す。" }, "quickRecordText": { "title": "テキストを素早く記録します", "desc": "主ウィンドウを開き、テキスト記録を表示します。" } } }, "skills": { "title": "Skills", "desc": "Skills 是可重用的 AI 能力包,让 AI 助手能够根据任务自动应用特定的行为模式。", "enable": "启用 Skills 功能", "enableDesc": "启用后,AI 可以使用已配置的 Skills", "autoMatch": "自动匹配 Skills", "autoMatchDesc": "根据用户输入自动选择合适的 Skills", "project": "工作区 Skills", "global": "全局 Skills", "globalPath": "全局 Skills 存储位置", "openInFileManager": "在文件管理器中打开", "createSkill": "创建 Skill", "editSkill": "编辑 Skill", "deleteSkill": "删除 Skill", "exportSkill": "导出 Skill", "importSkill": "导入 Skill", "selectSkillZip": "选择 Skill zip 文件", "importSuccess": "导入成功", "importError": "导入失败", "imported": "已导入", "importing": "导入中...", "skillName": "Skill 名称", "skillDescription": "描述", "skillVersion": "版本", "skillAuthor": "作者", "allowedTools": "允许使用的工具", "userInvocable": "在斜杠菜单显示", "instructions": "指令内容", "instructionsPlaceholder": "输入给 AI 的详细指令...", "importHelp": "支持导入 zip 格式的 Skill,zip 文件需包含 SKILL.md 文件。", "metadata": "元数据", "content": "指令内容", "noSkills": "还没有 Skills", "noSkillsDesc": "创建或导入 Skills 以开始使用", "noSkillsGlobal": "还没有全局 Skills", "noSkillsGlobalDesc": "创建或导入 Skills 以在所有项目中使用", "emptyWorkspace": "工作区中没有 Skills", "emptyWorkspaceDesc": "在 skills 文件夹中创建 SKILL.md 文件来添加 Skill", "basicSettings": "基础设置", "installedGlobalSkills": "已安装的全局 Skills", "nameRequired": "请输入 Skill 名称", "descriptionRequired": "请输入描述", "namePlaceholder": "note-organizer", "versionPlaceholder": "1.0.0", "descriptionPlaceholder": "自动整理和优化笔记结构...", "authorPlaceholder": "Your Name", "descriptionHelp": "用于 AI 匹配,描述此 Skill 的功能和适用场景", "allowedToolsHelp": "这些工具使用时不需要用户确认", "userInvocableHelp": "用户可以通过 /skill-name 手动触发", "instructionsHelp": "给 AI 的详细指令,支持 Markdown 格式", "deleteSkillTitle": "删除 Skill", "deleteSkillDesc": "确定要删除这个 Skill 吗?此操作无法撤销。", "skillDeleted": "Skill 删除成功" }, "audio": { "title": "语音设置", "desc": "在这里,你可以配置语音相关设置,包括文本转语音(朗读)和语音转文本(录音识别)功能。", "mode": { "title": "モード", "auto": "自動(推奨)", "local": "ローカルのみ", "model": "モデルのみ" }, "tts": { "title": "文本转语音(TTS)", "desc": "配置朗读功能,为聊天内容提供语音播放。", "modeDesc": "既定ではブラウザとシステム音声を優先し、必要な場合のみモデルを使って体験を強化します。", "model": { "title": "朗读模型", "desc": "任意です。自動モードの強化やモデル専用モードで利用できます。" }, "speed": { "title": "语速", "desc": "调整语音播放的速度,范围从0.5倍到2倍速度,默认为1倍正常速度。" } }, "stt": { "title": "语音转文本(STT)", "desc": "配置录音识别功能,将语音转换为文字记录。", "modeDesc": "既定ではブラウザ標準認識を優先し、ローカル利用不可時のみモデルへフォールバックします。", "model": { "title": "识别模型", "desc": "任意です。自動フォールバック用、またはモデル専用モードで使用できます。" } } }, "readAloud": { "title": "読み上げ", "desc": "読み上げ方法を設定します。既定ではシステム音声を優先し、モデル音声は強化用として利用します。", "options": { "mode": { "title": "モード", "desc": "自動モードではシステム音声を優先し、ローカル音声が使えない場合のみモデルを試します。", "auto": "自動(推奨)", "local": "ローカルのみ", "model": "モデルのみ" }, "audioModel": { "title": "読み上げモデル", "desc": "任意です。自動モードの強化やモデル専用モードで利用できます。" }, "speed": { "title": "速度", "desc": "読み上げ速度を0.5倍から2倍まで調整できます。既定値は1倍です。" } } } }, "record": { "trash": { "title": "ゴミ箱を空にする", "confirm": "本当にデータをクリアしますか?", "records": "{count}件の記録が復元可能です", "empty": "空にする", "close": "ゴミ箱を閉じる" }, "queue": { "ocr": "OCR 認識", "ai": "AI 認識", "upload": "画像ホストへアップロード", "jsdelivr": "jsdelivrキャッシュ通知", "save": "保存", "recording": "記録中...", "recorded": "記録済み", "record": "記録", "detected": "検出済み" }, "mark": { "empty": "記録はまだありません", "loading": "読み込み中...", "type": { "scan": "スキャン", "image": "イラスト", "screenshot": "スクリーンショット", "text": "テキスト", "file": "ファイル", "link": "リンク", "todo": "Todo", "pdf": "PDF", "upload": "アップロード", "download": "ダウンロード", "uploadTo": "ローカルから {provider} へ同期", "downloadFrom": "{provider} からローカルへ同期", "recording": "录音" }, "uploadSuccess": "記録アップロード成功", "downloadSuccess": "記録ダウンロード成功", "desc": "説明", "content": "内容", "createdAt": "作成日時", "progress": { "cacheImage": "画像をキャッシュ", "ocr": "OCR 認識", "aiAnalysis": "AI 認識", "uploadImage": "画像ホストへアップロード", "jsdelivrCache": "jsdelivr キャッシュ通知", "cacheFile": "ファイルをキャッシュ", "cacheScreenshot": "スクリーンショットをキャッシュ", "textAnalysis": "テキスト分析", "save": "保存", "saveImage": "画像を保存" }, "imageGallery": { "expand": "展開", "collapse": "折りたたむ" }, "text": { "title": "テキスト記録", "description": "テキストを記録します。ノート整理時に適切な位置に挿入されます。", "characterCount": "{count} 文字", "save": "記録", "autoReadClipboard": "クリップボードのテキストを自動読み取り" }, "link": { "title": "リンク記録", "description": "ウェブページのリンクを入力すると、システムは自動的にページの内容を取得して保存します", "save": "保存", "autoReadClipboard": "クリップボードのリンクを自動読み取り" }, "todo": { "title": "Todo記録", "description": "Todoアイテムを作成してタスクを管理", "titlePlaceholder": "Todoのタイトルを入力...", "descriptionPlaceholder": "詳細説明を入力(オプション)", "priority": "優先度", "priorityLow": "低", "priorityMedium": "中", "priorityHigh": "高", "dateRange": "日付範囲", "dateRangePlaceholder": "日付範囲を選択", "dueDate": "期限", "dueDatePlaceholder": "日付を選択", "save": "Todo作成", "saveEdit": "保存", "edit": "Todo編集", "editDescription": "Todoアイテムの詳細を変更", "cancel": "キャンセル", "selectTag": "タグを選択", "completed": "完了", "uncompleted": "未完了" }, "clipboard": { "detectedImage": "クリップボードの画像を検出しました", "detectedText": "クリップボードのテキストを検出しました" }, "tag": { "searchPlaceholder": "タグを作成または検索...", "noResults": "関連タグが見つかりません", "quickAdd": "クイック作成", "pinned": "ピン留め", "others": "その他", "rename": "リネーム", "delete": "削除", "pin": "ピン留め", "unpin": "キャンセルピン留め", "newTag": "新しいタグ", "newTagPlaceholder": "タグ名を入力...", "add": "追加" }, "mark": { "empty": "記録がありません", "emptyHint": "上部のツールバーを使用して最初の記録を作成しましょう!", "type": { "text": "テキスト" }, "chat": { "modeSelect": { "chat": "チャット", "agent": "エージェント" }, "agent": { "running": "エージェント実行中", "thinking": "思考中", "acting": "実行中", "observation": "観察結果", "toolCalls": "ツール呼び出し", "thought": "思考", "action": "行動", "confirmation": { "title": "操作の確認", "description": "エージェントが以下の操作を実行しようとしています。続行するには確認してください。", "tool": "ツール", "parameters": "パラメータ", "cancel": "キャンセル", "confirm": "確認", "confirmed": "確認済み", "cancelled": "キャンセル済み" } }, "placeholder": { "default": "質問したり記録を文章に整理したりできます...", "noApiKey": "API Keyが設定されていないため、AI対話機能を使用できません...", "on": "AI提案オン", "off": "AI提案オフ" }, "header": { "configApiKey": "API KEYを設定", "clearChat": "対話をクリア", "configPrompt": "マスクを設定", "selectPrompt": "マスクを選択" }, "clipboard": { "image": { "detected": "クリップボードに画像があります:", "recording": "記録中", "recorded": "記録済み", "record": "記録" }, "text": { "detected": "クリップボードにテキストがあります:", "recorded": "記録済み", "record": "記録" } }, "messageControl": { "words": "文字", "summary": "要約" }, "mcp": { "maxIterationsReached": "最大ツール呼び出し回数に達しました", "toolCall": "MCP サーバー", "params": "パラメータ", "result": "結果", "copy": "コピー", "paramsCopied": "パラメータをコピーしました", "resultCopied": "結果をコピーしました", "calling": "呼び出し中", "success": "完了", "error": "失敗" }, "empty": { "title": "AI会話を開始", "subtitle": "ChatまたはAgentモードでAIと対話", "currentModel": "現在のモデル", "currentPrompt": "現在のPrompt", "currentMode": "会話モード", "noModel": "モデルが設定されていません", "noPrompt": "Promptが設定されていません", "configureModel": "モデルを設定", "recentConversations": "最近の会話", "deleteConversation": "会話を削除", "conversationHistory": "会話履歴", "viewMore": "もっと見る", "messages": "件のメッセージ", "searchPlaceholder": "会話を検索...", "noMatchingConversations": "一致する会話が見つかりませんでした", "noConversationHistory": "会話履歴はありません", "quickPrompts": { "title": "クイックスタート", "writeNote": "ノートを書くのを手伝って", "summarize": "この内容を要約して", "brainstorm": "アイデアを出し合って", "explain": "この概念を説明して" }, "modeHint": "入力ボックスの左側の", "modeHintSuffix": "ボタンをクリックして会話モードを切り替え" }, "content": { "organize": "あなたの記録を文章に整理:" }, "note": { "writing": "執筆", "convert": "文章に変換", "description": "現在のノートはAIによって生成されており、編集できません。現在のノートを記事に変換(ローカルファイルの生成)して、執筆ページで二次創作を行うことができます。", "filename": "ファイル名", "selectFolder": "フォルダを選択", "rootDirectory": "ルートディレクトリ", "deleteTag": "現在のタグ、記録、ノートを削除(ゴミ箱から復元可能)", "warning": "変換後、執筆ページに移動します。", "convert_button": "変換" }, "mark": { "recorded": "已記録", "record": "記録" }, "send": "送信" }, "text": { "title": "記録テキスト", "description": "テキストを記録します。ノート整理時に適切な位置に挿入されます。", "characterCount": "{count} 文字", "save": "記録" }, "clipboard": { "detectedImage": "クリップボードの画像を検出しました", "detectedText": "クリップボードのテキストを検出しました" }, "tag": { "searchPlaceholder": "タグを作成または検索...", "noResults": "関連タグが見つかりません", "quickAdd": "クイック作成", "pinned": "ピン留め", "others": "その他", "rename": "リネーム", "delete": "削除", "pin": "ピン留め", "unpin": "キャンセルピン留め" }, "progress": { "cacheImage": "画像をキャッシュ", "ocr": "OCR 認識", "aiAnalysis": "AI 内容認識", "uploadImage": "画像ホストへアップロード", "jsdelivrCache": "jsdelivr キャッシュ通知", "cacheFile": "ファイルをキャッシュ", "cacheScreenshot": "スクリーンショットをキャッシュ", "textAnalysis": "テキスト分析", "save": "保存", "saveImage": "画像を保存" } }, "toolbar": { "search": "検索", "trash": "ゴミ箱", "restore": "復元", "delete": "削除", "deleteConfirm": "本当に削除しますか?", "moveTag": "タグに移動", "convertTo": "{type}に変換", "copyLink": "リンクをコピー", "copied": "クリップボードにコピーしました!", "regenerateDesc": "説明を再生成", "viewFolder": "フォルダで表示", "viewFile": "元ファイルを表示", "deleteForever": "完全に削除", "multiSelect": "複数選択", "exitMultiSelect": "複数選択を終了", "selectAll": "すべて選択", "deselectAll": "すべて選択解除", "selectedCount": "{count}項目を選択中", "moveSelectedTags": "選択した{count}項目を移動", "deleteSelected": "選択した{count}項目を削除", "deleteSelectedForever": "選択した{count}項目を完全削除", "organizeNotes": "ノート整理", "organizeSuccess": "ノート整理成功:{title}", "organizeError": "ノート整理失敗", "currentTag": "現在のタグ", "text": "テキスト記録", "recording": "音声記録", "scan": "画像スキャン", "image": "画像アップロード", "link": "リンク記録", "file": "ファイルアップロード", "todo": "Todo記録", "closeTrash": "ゴミ箱を閉じる" }, "list": { "title": "記録" }, "note": { "organizeAs": "整理先", "template": "テンプレート", "setting": "設定", "confirm": "确认", "cancel": "取消", "removeThinking": "移除思考过程", "stop": "停止" } }, "chat": { "empty": { "features": [ { "chat": "AIボットと対話する" }, { "linked": "あなたの記録に関連付けられています" }, { "clipboard": "クリップボードの記録を識別" }, { "organize": "あなたの記録をノートに整理します" } ], "title": "AIとの会話を開始", "subtitle": "チャットまたはエージェントモードでAIと対話", "currentModel": "現在のモデル", "currentPrompt": "現在のプロンプト", "currentMode": "会話モード", "noModel": "モデルが設定されていません", "noPrompt": "プロンプトが設定されていません", "configureModel": "モデルを設定", "recentConversations": "最近の会話", "deleteConversation": "会話を削除", "conversationHistory": "会話履歴", "viewMore": "もっと見る", "messages": "件のメッセージ", "searchPlaceholder": "会話を検索...", "noMatchingConversations": "一致する会話が見つかりませんでした", "noConversationHistory": "まだ会話履歴がありません", "quickPrompts": { "title": "快速开始", "writeNote": "帮我写一篇笔记", "summarize": "帮我总结这段内容", "brainstorm": "帮我头脑风暴一些想法", "explain": "帮我解释这个概念" } }, "newChat": "新しいタグで対話を開始", "removeChat": "現在のタグの対話を削除", "confirmNew": "新しいタグを作成", "confirmNewDescription": "新しいタグを作成して対話を始めますか?", "confirmRemove": "タグを削除", "confirmRemoveDescription": "このタグを削除すると、内部の記録も削除されます。もう一度確認してください。", "input": { "organize": "整理", "chat": "チャット", "placeholder": { "default": "メッセージを入力...", "noApiKey": "API Keyが設定されていないため、AIチャットを使用できません...", "on": "AIサジェスト有効", "off": "AIサジェスト無効", "noPrimaryModel": "メインモデルが設定されていないため、AIチャットを使用できません..." }, "translate": { "tooltip": "翻訳", "translating": "翻訳中...", "showOriginal": "原文表示", "alreadyTranslated": "翻訳済み" }, "clipboardMonitor": { "enable": "クリップボード監視(有効)", "disable": "クリップボード監視(無効)" }, "mcp": { "tooltip": "MCP サーバー" }, "send": "送信", "stop": "停止", "terminate": "終了", "tagLink": { "on": "タグとリンク済み", "off": "タグとリンクなし" }, "modelSelect": { "tooltip": "AIモデルを選択", "placeholder": "AIモデルを検索", "noModel": "モデルが見つかりません" }, "promptSelect": { "tooltip": "プロンプトを選択", "placeholder": "プロンプトを検索" }, "clearChat": "会話をクリア", "clearContext": { "tooltip": "コンテキストをクリア" }, "chatLanguage": { "tooltip": "会話言語を選択", "placeholder": "言語を検索" }, "rag": { "notSupported": "ベクトルモデルが利用できません", "enabled": "知識ベース検索有効", "disabled": "知識ベース検索無効" }, "modeSelect": { "tooltip": "入力モードを選択", "chat": "チャットモード", "gen": "整理モード", "translate": "翻訳モード" }, "chatModeSelect": { "chatDescription": "クイック会話、分析優先", "agentDescription": "スマートアシスタント、アクション実行可能" }, "attachImage": "画像を添付", "agent": { "running": "エージェント実行中", "thinking": "思考中", "analyzingRequest": "Agent がリクエストを分析しています...", "acting": "実行中", "observation": "観察結果", "toolCalls": "ツール呼び出し", "autoFinal": { "createNote": "ノート「{name}」を作成しました。", "createFile": "ファイル「{name}」を作成しました。" }, "thought": "思考", "action": "行動", "confirmation": { "title": "操作の確認", "description": "エージェントが以下の操作を実行しようとしています。続行するには確認してください。", "tool": "ツール", "parameters": "パラメータ", "cancel": "キャンセル", "confirm": "確認", "confirmed": "確認済み", "cancelled": "キャンセル済み" } }, "imageSelector": { "title": "画像を選択", "local": "ローカルファイル", "records": "記録から選択", "selectFiles": "ローカル画像を選択", "noRecords": "利用可能な画像記録がありません", "cancel": "キャンセル", "confirm": "確認" }, "fileLink": { "tooltip": "ファイルをリンク", "selectFile": "ファイルを選択", "linkedFile": "リンクされたファイル", "searchPlaceholder": "ファイルを検索...", "noFiles": "ファイルが見つかりません", "loading": "読み込み中..." }, "stopped": "对话已终止", "newChat": "开始新对话" }, "header": { "configApiKey": "API KEY の設定", "clearChat": "チャットをクリア", "configPrompt": "マスクの設定", "selectPrompt": "マスクを選択", "noModel": "AI モデルが選択されていません" }, "clipboard": { "image": { "detected": "クリップボードに画像が存在します:", "recording": "記録中", "recorded": "記録済み", "record": "記録" }, "text": { "detected": "クリップボードにテキストが存在します:", "recorded": "記録済み", "record": "記録" } }, "messageControl": { "words": "字", "summary": "要約", "readAloud": "音声読み上げ", "playing": "再生中", "loading": "準備中", "stop": "停止", "copy": "コピー", "copied": "コピーしました" }, "ragSources": { "label": "ナレッジベースで {count} 件のメモを検索", "openFile": "ファイルを開く" }, "preview": { "close": "閉じる", "copy": "コピー", "copied": "コピーしました!" }, "control": { "edit": "編集", "save": "保存", "cancel": "キャンセル", "delete": "削除", "deleteConfirm": "本当に削除しますか?" }, "content": { "organize": "あなたの記録を記事に整理:" }, "quote": { "lineSingle": "{fileName} の {line} 行目から引用", "lineRange": "{fileName} の {startLine}-{endLine} 行目から引用", "noLine": "{fileName} から引用" }, "note": { "organize": "整理", "writing": "執筆", "convert": "記事に変換", "description": "現在のノートはAIによって生成されており、編集できません。現在のノートを記事に変換(ローカルファイルを生成)して、執筆ページで二次創作を行うことができます。", "filename": "ファイル名", "selectFolder": "フォルダを選択", "rootDirectory": "ルートディレクトリ", "deleteTag": "現在のタグ、記録、ノートを削除(ゴミ箱から復元可能)", "warning": "変換後、執筆ページに移動します。", "convert_button": "変換", "organizeAs": "記録を整理します...", "templateContent": "テンプレート内容", "recordRange": "記録範囲を選択", "filterThinkingContent": "思考の記録を削除します", "startOrganize": "開始整理", "manageTemplate": "管理テンプレート", "cancel": "キャンセル", "stop": "停止" }, "mark": { "recorded": "記録済み", "record": "記録" }, "condensing": "正在压缩上下文...", "condensed": { "message": "已压缩 {count} 条历史消息" } }, "tag": { "add": "添加标签", "edit": "編集タグ", "delete": "削除タグ", "deleteConfirm": "本当に削除しますか?", "placeholder": "入力するタグ名" } }, "image": { "root": "画像ホスティング倉庫", "noData": { "title": "同期機能が有効になっていません", "desc": "システム設定ページに移動して、Github同期を設定してください。", "goToSettings": "設定へ移動", "howToUse": "同期機能の使い方は?" } }, "navigation": { "chat": "チャット", "record": "記録", "quickRecord": "クイック記録", "write": "執筆", "search": "検索", "githubImageHosting": "Github 画像ホスティング", "login": "ログイン", "loading": "読み込み中", "view": "表示", "logout": "ログアウト", "setting": "設定", "activity": "アクティビティ", "files": "ノート", "outline": "アウトライン", "hideLeftSidebar": "左サイドバーを非表示", "showLeftSidebar": "左サイドバーを表示", "hideRightSidebar": "右サイドバーを非表示", "showRightSidebar": "右サイドバーを表示", "searchPlaceholder": "ノートまたは記録を検索...", "showCenterPanel": "显示编辑器", "hideCenterPanel": "隐藏编辑器" }, "activity": { "title": "アクティビティカレンダー", "description": "記録、対話、執筆の活動を日ごとに確認できます。初版では既存の記録、ユーザー対話、ノート更新時刻をもとに集計します。", "drawer": { "title": "アクティビティ", "description": "今日の状態と最近の活動傾向をすばやく確認できます。", "today": "今日" }, "loading": "アクティビティデータを読み込み中...", "empty": "まだアクティビティデータがありません", "refresh": "更新", "summary": { "totalCount": "総アクティビティ", "activeDays": "活動日数", "records": "記録回数", "chats": "対話回数", "writing": "執筆活動" }, "labels": { "record": "記録", "writing": "執筆", "chat": "対話" }, "heatmap": { "title": "直近 26 週間", "range": "{startDate} - {endDate}", "less": "少", "more": "多", "dayCount": "件の活動", "emptyDay": "活動なし" }, "detail": { "title": "当日の詳細", "empty": "日付を選択すると当日の活動詳細が表示されます。" } }, "chat": { "placeholder": { "default": "メッセージを入力...", "noApiKey": "無 API KEY 設定、AI 話題できません...", "on": "AIサジェスト有効", "off": "AIサジェスト無効", "noPrimaryModel": "無主模型設定、AI 話題できません..." }, "translate": { "tooltip": "翻訳", "translating": "翻訳中...", "showOriginal": "原文表示", "alreadyTranslated": "翻訳済み" }, "clipboardMonitor": { "enable": "クリップボード監視(有効)", "disable": "クリップボード監視(無効)" }, "mcp": { "tooltip": "MCP サーバー" }, "send": "送信", "stop": "停止", "terminate": "終了", "tagLink": { "on": "タグとリンク済み", "off": "タグとリンクなし" }, "modelSelect": { "tooltip": "AIモデルを選択", "placeholder": "AIモデルを検索", "noModel": "モデルが見つかりません" }, "promptSelect": { "tooltip": "プロンプトを選択", "placeholder": "プロンプトを検索" }, "clearChat": "会話をクリア", "clearContext": { "tooltip": "コンテキストをクリア" }, "chatLanguage": { "tooltip": "会話言語を選択", "placeholder": "言語を検索" }, "rag": { "notSupported": "ベクトルモデルが利用できません", "enabled": "知識ベース検索有効", "disabled": "知識ベース検索無効" }, "modeSelect": { "tooltip": "入力モードを選択", "chat": "チャットモード", "gen": "整理モード", "translate": "翻訳モード" }, "fileLink": { "tooltip": "ファイルをリンク", "selectFile": "ファイルを選択", "linkedFile": "リンクされたファイル", "searchPlaceholder": "ファイルを検索...", "noFiles": "ファイルが見つかりません", "loading": "読み込み中..." } }, "header": { "configApiKey": "API KEY の設定", "clearChat": "チャットをクリア", "configPrompt": "マスクの設定", "selectPrompt": "マスクを選択", "noModel": "AI モデルが選択されていません" }, "clipboard": { "image": { "detected": "クリップボードに画像が存在します:", "recording": "記録中", "recorded": "記録済み", "record": "記録" }, "text": { "detected": "クリップボードにテキストが存在します:", "recorded": "記録済み", "record": "記録" } }, "messageControl": { "words": "字", "readAloud": "音声読み上げ", "playing": "再生中", "loading": "準備中", "stop": "停止", "copy": "コピー", "copied": "コピーしました" }, "ragSources": { "label": "参照ファイル" }, "preview": { "close": "关闭", "copy": "复制", "copied": "已复制!" }, "control": { "edit": "編集", "save": "保存", "cancel": "キャンセル", "delete": "削除", "deleteConfirm": "本当に削除しますか?" }, "content": { "organize": "将你的記録整理为文章:" }, "note": { "organize": "整理", "writing": "執筆", "convert": "文章に変換", "description": "現在のノートはAIによって生成され、編集できません。ノートを文章(ローカルファイル)に変換して、執筆ページで二次創作できます。", "filename": "ファイル名", "selectFolder": "ファイル夹を選択", "rootDirectory": "ルートディレクトリ", "deleteTag": "削除タグ、記録とノート(ゴミ箱で復元可能)", "warning": "変換後、執筆ページに移動します。", "convert_button": "変換", "organizeAs": "記録を整理します...", "templateContent": "テンプレート内容", "recordRange": "記録範囲を選択", "filterThinkingContent": "思考の記録を削除します", "startOrganize": "開始整理", "manageTemplate": "管理テンプレート", "cancel": "キャンセル" }, "search": { "placeholder": "ノートと記事を検索...", "results": "{count} 件の検索結果", "noResults": "検索結果がありません", "tryDifferentKeywords": "別のキーワードで検索してみてください", "item": { "record": "記録", "article": "記事", "matches": "{count}件の一致", "scanType": "スキャン" } }, "marks": { "types": { "screenshot": "スクリーンショット", "text": "テキスト", "image": "イラスト" } }, "tags": { "inspiration": "インスピレーション" }, "sync": { "status": "同期リポジトリの状態", "imageRepo": "画像ホスティング倉庫", "articleRepo": "記事倉庫" }, "ai": { "thinking": "考えることです", "error": { "title": "AIエラー", "noAddress": "まずAIアドレスを設定してください" } }, "article": { "sync": { "syncingRemote": "リモートファイルをプル中...", "syncComplete": "同期完了", "pullingRemote": "リモートサーバーから最新コンテンツを取得中..." }, "syncConfirm": { "title": "リモートファイルの更新を検出", "description": "ファイル {fileName} にリモート更新があります", "commitInfo": "最新コミット情報", "commitMessage": "コミットメッセージ", "author": "作者", "changes": "変更", "confirmMessage": "リモートバージョンをプルしてローカルファイルを上書きしてもよろしいですか?この操作は元に戻せません。", "cancel": "キャンセル", "confirmPull": "プルを確認" }, "emptyState": { "title": "作成を開始", "subtitle": "ファイルを選択して編集を開始するか、新しいノートを作成してください", "tip": "💡 ヒント:左側のファイルマネージャーからファイルを選択することもできます", "actions": { "newNote": { "title": "ノートを作成", "desc": "新しいMarkdownノートを作成" }, "newRecord": { "title": "記録を作成", "desc": "テキスト記録機能を開く" }, "globalSearch": { "title": "グローバル検索", "desc": "ノートの内容を素早く検索" }, "openWorkspace": { "title": "ワークスペースを開く", "desc": "ワークスペースディレクトリを選択または切り替え" } }, "onboarding": { "title": "初回ガイド", "subtitle": "この 3 つのタスクで NoteGen の基本フローを体験できます。", "dismiss": "オンボーディングをスキップ", "reopen": "初回ガイドを再表示", "start": "開始", "viewHint": "ヒントを見る", "continue": "次へ進む", "completed": "完了", "allDone": "スタートガイドのタスクはすべて完了しました。NoteGen の基本フローは体験済みです。", "stepLabel": "タスク ({current}/{total})", "stepCompletedLabel": "完了したタスク ({current}/{total})", "afterOrganizeDialog": { "title": "タスク完了 (2/3)", "description": "記録をノートに整理できました。次は AI Agent を使って、このノートをバイリンガル版に翻訳してみますか?", "confirm": "次へ進む", "cancel": "今はしない" }, "agentPrompt": { "label": "サンプルプロンプト", "use": "このプロンプトを使う", "intro": "先ほど整理したこのノートを、中国語と英語のバイリンガル版に直接修正してください。", "requirement1": "", "requirement2": "", "requirement3": "", "requirement4": "", "outro": "" }, "steps": { "createRecord": { "title": "最初の記録を作成", "desc": "サンプル記録を保存して、記録入口を覚えます。" }, "organizeNote": { "title": "ノートに整理", "desc": "記録を正式なノートに整理します。" }, "aiPolish": { "title": "Agent でバイリンガル翻訳", "desc": "AI Agent を使って、整理したノートをバイリンガル版に変換します。" } }, "completedStates": { "create-record": { "title": "最初の記録を作成しました", "desc": "クイック記録の入口がどこにあるか分かりました。" }, "organize-note": { "title": "記録をノートに整理しました", "desc": "次は AI でノートを編集してみましょう。" }, "ai-polish": { "title": "Agent でノートを処理しました", "desc": "記録から整理、さらに Agent による処理まで、NoteGen の基本フローを体験できました。" } }, "spotlight": { "create-record": { "title": "ここからすぐに記録できます", "desc": "この入口をクリックするとテキスト記録が開き、サンプル内容も自動で入ります。" }, "organize-note": { "title": "ここで記録をノートに整理します", "desc": "このボタンで、保存した記録を Markdown ノートにまとめられます。" }, "ai-polish": { "title": "ここで今作成したノートを Agent に渡せます", "desc": "サンプルプロンプトをチャットに入れて送信すると、Agent が現在のノートを元にバイリンガル版を生成します。" } } } }, "unsupportedFile": { "title": "このファイルをプレビューできません", "fileName": "ファイル名", "filePath": "ファイルパス", "fileSize": "ファイルサイズ", "modifiedTime": "更新日時", "createdTime": "作成日時", "pathCopied": "パスをコピーしました", "openExternal": "外部アプリで開く", "openDirectory": "ファイルのディレクトリを開く" }, "file": { "toolbar": { "accessRepo": "リポジトリにアクセス", "loadingSync": "同期情報を読み込み中", "configSync": "同期を設定", "newArticle": "新規記事", "newFolder": "新規フォルダ", "refresh": "更新", "toggleFolders": "フォルダを展開/折りたたみ", "expandAll": "すべて展開", "collapseAll": "すべて折りたたみ", "sortByName": "名前順で並べ替え", "sortByCreated": "作成日時で並べ替え", "sortByModified": "更新日時で並べ替え", "sortAsc": "昇順", "sortDesc": "降順", "sort": "並べ替え", "hideCloudFiles": "クラウドファイルを非表示", "showCloudFiles": "クラウドファイルを表示", "processingVectors": "ベクトルデータ処理中", "calculateVectors": "知識庫計算(全量)", "importMarkdown": "インポート", "importing": "インポート中...", "importSuccess": "インポート成功", "importSuccessDesc": "{count} 個のファイルをインポートしました", "importError": "インポート失敗" }, "sync": { "syncingRemote": "リモートファイルをプル中...", "syncComplete": "同期完了", "pullingRemote": "リモートサーバーから最新コンテンツを取得中...", "pullComplete": "プル完了" }, "context": { "viewDirectory": "ディレクトリを表示", "cut": "切り取り", "copy": "コピー", "paste": "貼り付け", "rename": "名前を変更", "deleteSyncFile": "同期ファイルを削除", "deleteLocalFile": "ローカルファイルを削除", "delete": "削除", "confirmDelete": "フォルダ \"{name}\" を削除してもよろしいですか?この操作により、フォルダとその内容がすべて削除されます。", "deleteSuccess": "削除しました", "deleteFailed": "削除に失敗しました", "newFile": "新規ファイル", "newFolder": "新規フォルダ", "syncFolder": "同期", "syncFolderDesc": "現在のフォルダ内のすべての Markdown ファイルを同期", "syncFolderSuccess": "フォルダの同期に成功しました", "syncFolderError": "フォルダの同期に失敗しました", "syncFolderProgress": "フォルダを同期中...", "deleteSyncFileSuccess": "削除しました", "deleteSyncFileError": "削除に失敗しました", "knowledgeBase": "ナレッジベース", "calculateVectors": "ベクトル計算", "updateVectors": "ベクトル更新", "deleteVectors": "ベクトル削除", "includeInKB": "ナレッジベースに含める", "includeInKBFile": "ナレッジベースに含める", "autoVectorCalc": "自動ベクトル計算", "vectorCalculated": "ベクトルを更新しました", "vectorCalcCompleted": "ベクトル計算が完了しました", "vectorCalcFailed": "ベクトル計算に失敗しました", "vectorDeleted": "ベクトルを削除しました", "vectorDeleteFailed": "ベクトルの削除に失敗しました", "batchCalcSuccess": "{count} 個のファイルのベクトル計算が成功しました", "batchCalcPartial": "計算完了:{success} 件成功、{failed} 件失敗", "batchCalcFailed": "一括ベクトル計算が失敗しました", "batchDeleteSuccess": "{count} 個のファイルのベクトル削除が成功しました", "batchDeletePartial": "削除完了:{success} 件成功、{failed} 件失敗", "batchDeleteFailed": "一括ベクトル削除が失敗しました", "noMarkdownFiles": "フォルダに Markdown ファイルがありません", "includedInKB": "ナレッジベースに含めました", "excludedFromKB": "ナレッジベースから除外しました", "autoCalcEnabled": "自動ベクトル計算を有効にしました", "autoCalcDisabled": "自動ベクトル計算を無効にしました", "settingFailed": "設定に失敗しました", "confirmDeleteVectors": "{count} 個のファイルのベクトルを削除してもよろしいですか?" }, "folderView": { "vectorDbNotEnabled": "ベクターデッサースが有効ではありません", "calculateVectors": "ベクトルを計算", "indexed": "インデックス済み", "vectorCount": "ベクター数", "databaseSize": "データベースサイズ", "lastCalculated": "最終計算", "never": "なし", "calculating": "計算中...", "failed": "失敗", "recalculateVectors": "ベクターを再計算", "skills": "Skills", "skillNotFound": "Skill が見つかりません", "skillNotFoundDesc": "ID {id} の Skill が見つかりません", "loadingSkills": "Skills を読み込み中...", "loadingSkill": "Skill を読み込み中...", "globalSkills": "グローバル Skills", "workspaceSkills": "ワークスペース Skills", "instructions": "命令", "examples": "例", "scripts": "スクリプト", "references": "参考資料", "assets": "アセット" }, "error": { "fileExists": "ファイル名が既に存在します" }, "clipboard": { "copied": "クリップボードにコピーしました", "cut": "クリップボードに切り取りました", "pasted": "貼り付けました", "pasteFailed": "貼り付け操作に失敗しました", "empty": "クリップボードが空です", "confirmOverwrite": "ファイルが既に存在します。覆盖吗?", "notSupported": "この操作はサポートされていません" }, "deleteConfirm": "このファイルを削除してもよろしいですか?" }, "editor": { "copySuccess": "コピー成功", "copySuccessDescription": "クリップボードにコピーしました", "search": { "placeholder": "ドキュメント内を検索", "replacePlaceholder": "置換後の文字列", "caseSensitive": "大文字小文字を区別", "replace": "置換", "replaceAll": "すべて置換", "findPrev": "前へ", "findNext": "次へ" }, "upload": { "error": "画像のアップロードに失敗しました", "needToken": "画像のアップロードには accessToken の設定が必要です", "uploading": "画像をアップロードしています" }, "floatbar": { "quote": { "tooltip": "引用" }, "readAloud": { "start": "読み上げ", "stop": "停止", "loading": "読み込み中..." } }, "toolbar": { "organize": { "tooltip": "ノート整理" }, "mark": { "title": "記録を使用", "tooltip": "記録を使用", "description": "記録をコンテンツとして記事に挿入する。", "noRecords": "記録なし", "ocrNoContent": "OCRはコンテンツを認識しませんでした" }, "question": { "tooltip": "質問応答", "selectContent": "先に内容を選択してください", "promptTemplate": "参考文:\n{content}\n質問内容:\n{question}\nに基づいて、直接回答を返してください。" }, "continue": { "tooltip": "文章続き", "promptTemplate": "前文:\n{content}\n内容に基づいて、100文字以内で続きを書いてください。\n後文:\n{endContent}\nを参考にしても良いですが、重複は避けてください。" }, "polish": { "tooltip": "最適化", "selectContent": "先に内容を選択してください", "promptTemplate": "この文章を校正してください:\n{content}\n。言語はそのままに、誤字脱字や不自然な表現を修正し、校正後の結果を直接返してください。" }, "eraser": { "tooltip": "簡潔化", "selectContent": "先に内容を選択してください", "promptTemplate": "この文章を要約してください:\n{content}\n。文章があまりに冗長なので、文字数を半分以上に減らしてください。言語は変更しないで、要約した結果を直接返してください。" }, "expansion": { "tooltip": "拡張", "selectContent": "先に内容を選択してください", "promptTemplate": "この文章を拡張してください:\n{content}\n。文章があまりに短いので、文字数を半分以上に増やしてください。言語は変更しないで、拡張した結果を直接返してください。" }, "translation": { "tooltip": "翻訳", "description": "選択したテキストを翻訳します", "selectContent": "まず内容を選択してください", "promptTemplate": "このテキスト:\n{content}\nを{language}に翻訳してください。翻訳結果のみを返してください。", "fail": "翻訳に失敗しました", "failNoSelection": "翻訳するテキストを選択してください", "translating": "翻訳中", "translatingTo": "{language}に翻訳中...", "success": "翻訳完了", "successTo": "{language}に翻訳されました", "customLanguage": "カスタム言語...", "customLanguagePlaceholder": "目標言語を入力、例:英語、日本語など", "customLanguageEmpty": "目標言語を入力してください", "customLanguageExample": "例:英語、日本語、フランス語など" } }, "saveDialog": { "title": "保存文件", "emptyContent": "内容为空", "emptyContentDesc": "请先输入内容后再保存", "success": "保存成功", "successDesc": "文件已保存", "error": "保存失败", "errorDesc": "文件保存失败,请重试" } }, "footer": { "wordCount": "文字数", "pull": { "pull": "プル", "checking": "更新を確認中...", "noUpdate": "リモート更新なし", "clickToPull": "クリックしてリモート更新をプル", "pullSuccess": "プル成功", "pullFailed": "プル失敗", "ignored": "無視しました", "ignoreUpdate": "この更新を無視" }, "sync": { "push": "プッシュ", "pushed": "プッシュ済み", "syncing": "プッシュ中", "syncFailed": "プッシュに失敗しました", "checkNetworkOrToken": "ネットワーク接続またはトークンを確認してください", "quickSync": "クイック同期" }, "history": { "loadingHistory": "履歴を読み込み中", "historyRecords": "履歴記録", "noHistory": "履歴がありません", "loading": "読み込み中", "recordsCount": "件の記録", "filterQuickSync": "クイック同期を絞り込み", "committedAt": "コミット日時", "pull": "プル", "quickSync": "クイック同期" }, "vectorCalc": { "tooltip": { "default": "ベクトルインデックス状態", "none": "クリックしてベクトル計算を開始", "indexed": "インデックス済み", "pending": "更新待ち、クリックして今すぐ計算", "calculating": "計算中..." }, "status": { "calculating": "計算中" } } } }, "mobile": { "chat": { "drawer": { "settings": { "title": "チャット設定" }, "tools": { "title": "ツール", "clearContext": "コンテキストをクリア", "clearContextDesc": "会話のコンテキストをクリアし、チャット履歴を保持", "clearChat": "チャットをクリア", "clearChatDesc": "すべてのチャット記録を削除", "clear": "クリア", "newChat": "开始新对话", "start": "开始" }, "attachments": { "title": "添付ファイル", "gallery": "ギャラリー", "camera": "カメラ", "file": "ファイル", "linkNote": "ノートをリンク" } } } }, "mcp": { "selectServers": "MCP Servers", "searchServers": "サーバーを検索...", "noServers": "MCPサービスが有効になっていません", "noServersFound": "一致するサーバーが見つかりません", "addServer": "サーバーを追加...", "goToSettings": "設定へ移動", "close": "閉じる", "navigate": "選択", "confirm": "確認", "tools": "個のツール", "connecting": "接続中", "disconnected": "未接続" }, "recording": { "title": "音声録音", "description": "マイクボタンをクリックして録音を開始すると、システムが自動的に認識してテキストに変換します", "recording": "録音中", "paused": "一時停止", "ready": "準備完了", "processing": "処理中...", "cancel": "キャンセル", "error": "エラー", "success": "成功", "noModelConfigured": "音声認識モデルが設定されていません。設定で構成してください", "speechUnavailable": "現在の認識モードは利用できません。ローカル音声対応またはモデル設定を確認してください。", "fallbackToModel": "ローカル音声認識が利用できないため、自動的にモデル文字起こしへ切り替えました。", "startError": "録音を開始できません", "noAudioData": "音声データが録音されていません", "transcriptionSuccess": "音声認識完了", "transcriptionEmpty": "認識結果が空です", "transcriptionError": "音声認識に失敗しました", "configureModel": "モデルを設定", "retryTranscription": "再認識", "retrying": "再認識中...", "retrySuccess": "再認識が完了しました", "retryError": "再認識に失敗しました", "noContentDetected": "コンテンツが検出されませんでした", "doubleClickToSelectFile": "ダブルクリックで音声ファイルを選択", "mode": { "builtin": "ブラウザ認識", "builtinDesc": "無料、リアルタイム認識", "model": "AIモデル認識", "modelDesc": "STTモデルが必要、より正確" } }, "quickRecord": { "description": "記録ツールを選択して、素早く記録を作成" }, "editor": { "placeholder": "「/」を入力してメニューを開くか、直接書き始める...", "outline": { "title": "アウトライン", "open": "アウトラインを開く", "close": "アウトラインを閉じる" }, "translation": { "fail": "翻訳に失敗しました", "failNoSelection": "翻訳するテキストを選択してください", "translating": "翻訳中...", "translatingTo": "{language}に翻訳中...", "success": "翻訳完了", "successTo": "{language}に翻訳されました", "customLanguageEmpty": "目標言語を入力してください", "customLanguageExample": "例:英語、日本語、フランス語など" }, "quoteDisplay": { "fromFile": "{fileName}から引用", "line": "{fileName}の{line}行目から引用", "lines": "{fileName}の{start}-{end}行目から引用" }, "bubbleMenu": { "ai": "AI", "polish": "添削", "concise": "簡潔に", "expand": "拡張", "translate": "翻訳", "translateSubtitle": "翻訳先", "quoteToChat": "チャットに引用", "link": "リンク", "linkPlaceholder": "リンクURLを入力", "confirm": "確認", "cancel": "キャンセル", "bold": "太字", "italic": "斜体", "strike": "取り消し線", "underline": "下線", "inlineCode": "インラインコード", "highlight": "ハイライト", "blockquote": "引用", "bulletList": "箇条書き", "orderedList": "番号付きリスト", "taskList": "タスクリスト", "codeBlock": "コードブロック", "languages": { "English": "英語", "Japanese": "日本語", "Korean": "韓国語", "French": "フランス語", "German": "ドイツ語", "Spanish": "スペイン語", "Portuguese": "ポルトガル語", "Russian": "ロシア語", "Arabic": "アラビア語" }, "customLanguagePlaceholder": "カスタム言語..." }, "aiSuggestion": { "accept": "受け入れ", "reject": "拒否", "generating": "生成中...", "abort": "中止" }, "image": { "insert": "画像を挿入", "uploading": "アップロード中...", "uploadSuccess": "画像は画像ホスティングにアップロードされました", "saveSuccess": "画像はローカルに保存されました", "uploadFailed": "画像の挿入に失敗しました", "sizeSmall": "小 (25%)", "sizeMedium": "中 (50%)", "sizeLarge": "大 (75%)", "sizeOriginal": "元のサイズ", "editAlt": "代替テキストを編集", "editSrc": "URLを編集", "altPlaceholder": "代替テキストを入力...", "srcPlaceholder": "画像URLを入力...", "delete": "画像を削除", "confirm": "確認", "cancel": "キャンセル" }, "mermaid": { "rendering": "レンダリング中...", "renderError": "レンダリングエラー", "clickToEdit": "クリックしてソースを編集", "clickToAdd": "クリックして диаграммаを追加", "placeholder": "Mermaid диаграммаコードを入力...", "preview": "プレビュー", "done": "完了", "diagramTypes": { "flowchart": "フローチャート", "sequence": "シーケンス", "classDiagram": "クラス図", "stateDiagram": "ステート図", "er": "ER図", "gantt": "ガントチャート", "pie": "円グラフ", "journey": "ジャーニー" }, "templates": { "flowchart": "graph TD\n A[開始] --> B[処理]\n B --> C[終了]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: こんにちは\n Bob-->>Alice: 返信", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title プロジェクト計画\n dateFormat YYYY-MM-DD\n section 第一フェーズ\n タスク1 :a1, 2024-01-01, 30d\n section 第二フェーズ\n タスク2 :after a1, 20d", "pie": "pie title リソース割り当て\n \"CPU\" : 45\n \"メモリ\" : 30\n \"ストレージ\" : 25", "journey": "journey\n title 私の日常\n section 午前\n 通勤 : 7:00, 5\n 仕事 : 9:00, 8" } }, "slashCommand": { "groups": { "ai": "AI", "heading": "見出し", "list": "リスト", "block": "ブロック", "align": "整列", "embed": "埋め込み", "math": "数式", "chart": "図" }, "items": { "continue": "続ける", "continueDesc": "AIが内容を続きます", "heading1": "見出し1", "heading1Desc": "大見出し", "heading2": "見出し2", "heading2Desc": "中見出し", "heading3": "見出し3", "heading3Desc": "小見出し", "bulletList": "箇条書き", "bulletListDesc": "シンプルな箇条書きリストを作成", "orderedList": "番号付きリスト", "orderedListDesc": "番号付きのリストを作成", "taskList": "タスクリスト", "taskListDesc": "チェックボックス付きタスクリストを作成", "image": "画像", "imageDesc": "ローカル画像または画像ホスティングを挿入", "table": "表", "tableDesc": "表を挿入", "blockquote": "引用", "blockquoteDesc": "引用内容をキャプチャ", "codeBlock": "コードブロック", "codeBlockDesc": "コードスニペットをキャプチャ", "divider": "区切り線", "dividerDesc": "要素の間に区切り線を作成", "inlineMath": "インライン数式", "inlineMathDesc": "インラインLaTeX数式を挿入", "blockMath": "ブロック数式", "blockMathDesc": "ブロックLaTeX数式を挿入", "flowchart": "フローチャート", "flowchartDesc": "フローチャートを挿入", "sequence": "シーケンス図", "sequenceDesc": "シーケンス図を挿入", "gantt": "ガントチャート", "ganttDesc": "ガントチャートを挿入", "classDiagram": "クラス図", "classDiagramDesc": "クラス図を挿入", "stateDiagram": "状態図", "stateDiagramDesc": "状態図を挿入", "pie": "円グラフ", "pieDesc": "円グラフを挿入", "erDiagram": "ER図", "erDiagramDesc": "エンティティ関係図を挿入", "journey": "ジャーニーマップ", "journeyDesc": "ユーザージャーニーマップを挿入" }, "imageUpload": { "success": "アップロード成功", "saveSuccess": "保存成功", "savePath": "保存先: {path}", "failed": "画像の挿入に失敗しました" } } }, "tabContext": { "close": "閉じる", "closeOthers": "その他を閉じる", "closeAll": "すべて閉じる", "closeLeft": "左を閉じる", "closeRight": "右を閉じる" } } ================================================ FILE: messages/pt-BR.json ================================================ { "app": { "title": "Gerador de Notas", "description": "Seu assistente de anotações com IA" }, "common": { "save": "Salvar", "cancel": "Cancelar", "delete": "Excluir", "edit": "Editar", "create": "Criar", "theme": "Tema", "light": "Claro", "dark": "Escuro", "system": "Sistema", "pin": "Fixar", "unpin": "Desafixar", "settings": "Configurações", "back": "Voltar", "sync": "Sincronizar", "language": "Idioma", "confirm": "Confirmar", "selectPrompt": "Selecionar Prompt", "prompt": "Instrução", "success": "Sucesso", "error": "Falha", "defaultFileName": "Sem Título", "restartToApply": ", por favor reinicie o aplicativo para que a configuração entre em vigor", "close": "Fechar", "open": "Abrir", "add": "Adicionar", "remove": "Remover", "search": "Pesquisar", "filter": "Filtrar", "sort": "Ordenar", "export": "Exportar", "import": "Importar", "refresh": "Atualizar", "loading": "Carregando", "warning": "Aviso", "info": "Informação", "unsaved": "Não salvo", "saving": "Salvando", "configureSync": "Configurar Sincronização" }, "settings": { "defaultModels": { "title": "Modelos Padrão" }, "others": "Avançado", "general": { "title": "Configurações Gerais", "desc": "Aqui, você pode configurar as definições básicas do aplicativo, incluindo tema da interface, idioma e outras opções.", "interface": { "title": "Configurações da Interface", "theme": { "title": "Tema", "desc": "Escolha o tema de aparência do aplicativo", "options": { "light": "Claro", "dark": "Escuro", "system": "Sistema" } }, "language": { "title": "Idioma", "desc": "Escolha o idioma de exibição do aplicativo" }, "scale": { "title": "Escala da Interface", "desc": "Ajuste a escala geral da interface do aplicativo", "placeholder": "Selecione a proporção da escala" }, "contentTextScale": { "title": "Escala do Conteúdo", "desc": "Ajuste o tamanho do texto no editor e no conteúdo Markdown do chat" }, "fileManagerTextSize": { "title": "Tamanho do Texto do Gerenciador de Arquivos", "desc": "Ajuste o tamanho do texto das listas de arquivos e pastas no gerenciador de arquivos" }, "recordTextSize": { "title": "Tamanho do Texto dos Registros", "desc": "Ajuste o tamanho do texto dos itens de registro na lista de registros" }, "customCss": { "title": "CSS Personalizado", "desc": "Adicione estilos CSS personalizados para substituir os estilos padrão do aplicativo", "button": "Editar CSS", "dialogTitle": "CSS Personalizado", "dialogDesc": "Insira o código CSS personalizado abaixo para substituir os estilos padrão do aplicativo. Clique em salvar para aplicar as alterações.", "placeholder": "Insira o código CSS personalizado aqui", "save": "Salvar", "cancel": "Cancelar" }, "tray": { "enabled": { "title": "Habilitar Bandeja", "desc": "Escolher minimizar para bandeja ou fechar aplicativo ao fechar janela" } }, "customTheme": { "title": "Cores do tema personalizado", "desc": "Personalize as cores do tema do aplicativo, incluindo cor de fundo, cor do texto, cor da borda e outras.", "button": "Editar cores", "dialogTitle": "Cores do tema personalizado", "dialogDesc": "Configure cores personalizadas do tema. As alterações são salvas e aplicadas em tempo real, substituindo os temas claro e escuro.", "close": "Fechar", "reset": "Redefinir tudo", "tabs": { "custom": "Personalizar", "presets": "Predefinições", "importExport": "Importar/Exportar" }, "export": { "title": "Exportar configuração", "button": "Exportar", "placeholder": "Cole aqui a configuração exportada" }, "import": { "title": "Importar configuração", "button": "Importar", "placeholder": "Cole aqui a configuração para importar", "error": "Falha ao importar: formato inválido", "success": "Importado com sucesso" }, "presets": { "title": "Predefinições", "desc": "Escolha uma paleta de cores pronta", "apply": "Aplicar", "reset": { "name": "Restaurar padrão" }, "default": { "name": "Branco padrão" }, "ocean": { "name": "Azul oceano" }, "forest": { "name": "Verde floresta" }, "sunset": { "name": "Vermelho pôr do sol" }, "lavender": { "name": "Roxo lavanda" }, "midnight": { "name": "Meia-noite escuro" }, "deepSea": { "name": "Azul mar profundo" }, "darkForest": { "name": "Verde floresta escuro" }, "darkViolet": { "name": "Violeta escuro" }, "coralWarm": { "name": "Coral quente" }, "slateGray": { "name": "Cinza ardósia" }, "darkGold": { "name": "Dourado escuro" }, "beigeWarm": { "name": "Bege quente" }, "beigeDark": { "name": "Bege escuro" } }, "colors": { "background": "Cor de fundo", "foreground": "Cor do texto", "card": "Cor de fundo do cartão", "cardForeground": "Cor do texto do cartão", "primary": "Cor principal", "primaryForeground": "Cor do texto (principal)", "secondary": "Cor secundária", "secondaryForeground": "Cor do texto (secundária)", "third": "Cor terciária", "thirdForeground": "Cor do texto (terciária)", "muted": "Cor suave", "mutedForeground": "Cor do texto (suave)", "accent": "Cor de destaque", "accentForeground": "Cor do texto (destaque)", "border": "Cor da borda", "shadow": "Cor da sombra" } } }, "tools": { "title": "Configurações de Ferramentas", "chatToolbar": { "title": "Barra de Ferramentas do Chat", "desc": "Personalize a ordem de exibição e a visibilidade dos botões da barra de ferramentas do chat para uma experiência de chat personalizada", "button": "Configurar", "dialogTitle": "Configurar Barra de Ferramentas do Chat", "dialogDesc": "Arraste as ferramentas para ajustar a ordem, use as chaves para mostrar ou ocultar", "groups": { "pc": "PC", "mobile": "Móvel", "bottom": "Barra de Ferramentas Inferior", "topLeft": "Barra de Ferramentas Superior - Esquerda", "topRight": "Barra de Ferramentas Superior - Direita" } }, "recordToolbar": { "title": "Barra de Ferramentas de Registro", "desc": "Personalize a ordem de exibição e a visibilidade dos botões da barra de ferramentas de registro", "button": "Configurar", "dialogTitle": "Configurar Barra de Ferramentas de Registro", "dialogDesc": "Arraste as ferramentas para ajustar a ordem, use as chaves para mostrar ou ocultar" }, "desc": "配置各种工具栏按钮的显示和排序" } }, "rag": { "title": "Base de Conhecimento", "desc": "Aqui, você pode configurar as definições da base de conhecimento, baseada na tecnologia RAG, que converte texto em vetores usando modelos de embedding e, em seguida, realiza buscas inteligentes e respostas através da busca vetorial.", "settingsTitle": "Configuração de Parâmetros", "settingsDesc": "Ajustando os parâmetros, você pode controlar com mais precisão o efeito de recuperação da base de conhecimento.", "deleteVectorConfirm": "Tem certeza de que deseja limpar a base de conhecimento?", "deleteVectorSuccess": "Base de conhecimento limpa com sucesso", "enable": "Habilitar busca na base de conhecimento", "enableDesc": "Habilitar esta opção fará com que a IA pesquise suas notas ao responder perguntas, fornecendo respostas mais precisas.", "chunkSize": "Tamanho do Chunk", "chunkSizeDesc": "O número máximo de caracteres para a divisão do texto. Chunks maiores podem conter mais contexto, mas aumentarão a complexidade do cálculo vetorial.", "chunkOverlap": "Sobreposição de Chunks", "chunkOverlapDesc": "O número de caracteres sobrepostos entre os chunks de texto. Sobreposições maiores podem manter a continuidade do contexto.", "resultCount": "Contagem de Resultados", "resultCountDesc": "O número de documentos relacionados retornados na busca. Mais documentos fornecem mais informação, mas também podem introduzir ruído.", "similarityThreshold": "Limiar de Similaridade", "similarityThresholdDesc": "O limiar mínimo de similaridade entre documentos e consultas. Apenas documentos que excederem este limiar serão retornados. O valor varia de 0.0 a 1.0; quanto maior o limiar, mais rigoroso o requisito.", "resetToDefaults": "Redefinir para Padrões", "deleteVector": "Limpar Base de Conhecimento", "topPDesc": "O parâmetro Top P controla a diversidade do texto gerado pelo modelo: quanto menor o valor, mais determinístico; quanto maior, mais variado." }, "mcp": { "title": "MCP", "desc": "O Protocolo de Contexto de Modelo (MCP) permite que a IA chame ferramentas externas e acesse recursos, expandindo as capacidades da IA.", "servers": "Lista de Servidores", "serversDesc": "Gerencie as configurações do servidor MCP. Cada servidor pode fornecer diferentes ferramentas e recursos.", "addServer": "Adicionar Servidor", "addFirstServer": "Adicionar Primeiro Servidor", "editServer": "Editar Servidor", "serverName": "Nome do Servidor", "serverNamePlaceholder": "Ex: Servidor de Sistema de Arquivos", "serverEnabled": "Habilitar Servidor", "serverEnabledDesc": "Quando habilitado, este servidor se conectará automaticamente e fornecerá ferramentas.", "serverType": "Tipo de Servidor", "stdio": "Comando Local", "http": "Serviço HTTP", "command": "Comando", "args": "Argumentos", "argsDesc": "Argumentos de linha de comando, separados por espaços", "env": "Variáveis de Ambiente", "envDesc": "Configuração de variáveis de ambiente em formato JSON", "url": "URL do Serviço", "headers": "Cabeçalhos da Requisição", "headersDesc": "Cabeçalhos da requisição HTTP em formato JSON", "testConnection": "Testar Conexão", "test": "Testar", "testSuccess": "Teste de conexão bem-sucedido", "testFailed": "Falha no teste de conexão", "connected": "Conectado", "connecting": "Conectando", "disconnected": "Desconectado", "error": "Erro", "tools": "Ferramentas", "noServers": "Serviço MCP não habilitado", "noServersFound": "Nenhum servidor correspondente encontrado", "serverAdded": "Servidor adicionado com sucesso", "serverUpdated": "Servidor atualizado com sucesso", "serverDeleted": "Servidor excluído com sucesso", "deleteServerTitle": "Excluir Servidor", "deleteServerDesc": "Tem certeza de que deseja excluir este servidor? Esta ação não pode ser desfeita.", "nameRequired": "Por favor, insira o nome do servidor", "commandRequired": "Por favor, insira o comando", "urlRequired": "Por favor, insira a URL do serviço", "toolBrowser": "Navegador de Ferramentas", "searchTools": "Buscar ferramentas...", "noToolsFound": "Nenhuma ferramenta encontrada", "parameters": "Parâmetros", "testAll": "Testar Todas as Conexões", "testAllCompleted": "Todos os testes de conexão concluídos", "testAllFailed": "Falha no teste de conexão", "save": "Salvar", "cancel": "Cancelar", "delete": "Excluir", "importJson": "Importar JSON", "jsonImportTitle": "Importar Configuração do Servidor de JSON", "jsonImportDesc": "Cole o formato de configuração mcpServers dos servidores MCP", "jsonInput": "Configuração JSON", "jsonInputHelp": "Suporta formato mcpServers, usa automaticamente o nome do servidor como chave", "jsonRequired": "Por favor, insira a configuração JSON", "jsonEmpty": "A configuração JSON não pode estar vazia", "jsonInvalidJson": "Formato JSON inválido", "jsonInvalidFormat": "Formato de configuração inválido, deve conter campos name e type", "jsonInvalidType": "O tipo de servidor deve ser stdio ou http", "jsonMissingCommand": "Servidor tipo stdio deve especificar command", "jsonMissingUrl": "Servidor tipo http deve especificar url", "jsonImportSuccess": "Importado com sucesso {count} servidor(es)", "jsonImportSkipped": "Ignorado {count} servidor(es) existente(s)", "jsonImportNoServers": "Nenhum servidor foi importado", "import": "Importar", "mobileHttpOnlyTitle": "MCP por comando local é exclusivo do desktop", "mobileHttpOnlyDesc": "Servidores MCP com comando local só são suportados no desktop. No mobile, o suporte atual é apenas para MCP HTTP.", "runtimeEnvironment": "Ambiente de runtime", "runtimeEnvironmentDesc": "Verifique se o runtime local necessário está disponível antes de testar o servidor MCP.", "checkEnvironment": "Verificar ambiente", "recheckEnvironment": "Verificar novamente", "runtimeCheckFailed": "Falha ao verificar o ambiente", "detectedLauncher": "Launcher detectado", "runtimeInstalled": "Instalado", "runtimeMissing": "Ausente", "runtimeVersion": "Versão", "runtimeInstalledSummary": "{installed}/{total} instalados", "showRuntimeDetails": "Mostrar detalhes do runtime", "hideRuntimeDetails": "Ocultar detalhes do runtime", "runtimeNotChecked": "Este runtime ainda não foi verificado.", "runtimeCurrentUserScope": "Quando houver suporte, o comando recomendado instala no ambiente do usuário atual.", "runtimeManualOnly": "A instalação automática não está disponível para este runtime na plataforma atual. Instale manualmente e verifique novamente.", "installRuntime": "Instalar runtime", "runtimeInstallTitle": "Instalar runtime", "runtimeInstallDesc": "Após sua confirmação, o NoteGen executará o seguinte comando de instalação.", "runtimeInstallPreparing": "Preparando instalação", "runtimeInstallRunning": "Instalando", "runtimeInstallCompleted": "Instalação concluída", "runtimeInstallCancelled": "Cancelado", "runtimeInstallFailedState": "Falha na instalação", "runtimeInstallLogs": "Logs de instalação", "runtimeInstallWaitingLogs": "Aguardando saída da instalação...", "runtimeInstallClose": "Fechar", "runtimeInstallCancel": "Parar instalação", "runtimeInstallCancelledByUser": "Cancelamento solicitado pelo usuário.", "runtimeInstallCancelFailed": "Falha ao parar a instalação", "runtimeInstallSuccess": "Instalação do runtime concluída", "runtimeInstallFailed": "Falha na instalação do runtime", "runtimeNoGuidedSupport": "Ainda não há assistência guiada para este comando.", "enableTitle": "Ativar MCP", "enableDesc": "Quando ativado, a IA pode chamar as ferramentas fornecidas pelos servidores MCP configurados." }, "editor": { "title": "Configurações do Editor", "interfaceSettings": "Configurações de Interface", "desc": "Aqui, você pode personalizar o editor, criando uma experiência de escrita adaptada às suas necessidades.", "centeredContent": "Conteúdo Centralizado", "centeredContentDesc": "Quando ativado, o conteúdo do editor será centralizado com margens em ambos os lados.", "outlineEnable": "Sumário habilitado por padrão", "outlineEnableDesc": "Habilitar esta opção tornará o sumário visível por padrão.", "outlinePosition": "Posição do Sumário", "outlinePositionDesc": "Defina a posição do sumário.", "outlinePositionOptions": { "left": "Esquerda", "right": "Direita" }, "showUndoRedo": "Botões Desfazer/Refazer", "showUndoRedoDesc": "Mostrar botões de desfazer e refazer na barra de guias do editor.", "completion": { "title": "Auto Completar", "model": { "title": "Modelo de Completamento Rápido", "desc": "Selecione o modelo para preenchimento automático no editor" } }, "commit": { "title": "Mensagem de Commit Automática", "model": { "title": "Modelo de Commit", "desc": "Para gerar automaticamente mensagens de commit do Git com base nas alterações do arquivo" } }, "mermaid": { "title": "Diagrama", "rendering": "Renderizando...", "renderError": "Erro de renderização", "clickToEdit": "Clique para editar código", "clickToAdd": "Clique para adicionar diagrama", "placeholder": "Digite o código do diagrama Mermaid...", "preview": "Visualizar", "done": "Concluído", "diagramTypes": { "flowchart": "Fluxograma", "sequence": "Sequência", "classDiagram": "Diagrama de Classes", "stateDiagram": "Diagrama de Estados", "er": "Diagrama ER", "gantt": "Gantt", "pie": "Gráfico de Pizza", "journey": "Jornada" }, "templates": { "flowchart": "graph TD\n A[Início] --> B[Processo]\n B --> C[Fim]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Olá\n Bob-->>Alice: Resposta", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title Plano de Projeto\n dateFormat YYYY-MM-DD\n section Fase 1\n Tarefa1 :a1, 2024-01-01, 30d\n section Fase 2\n Tarefa2 :after a1, 20d", "pie": "pie title Alocação de Recursos\n \"CPU\" : 45\n \"Memória\" : 30\n \"Armazenamento\" : 25", "journey": "journey\n title Meu Trabalho Diário\n section Manhã\n Deslocamento : 7:00, 5\n Trabalho : 9:00, 8" } } }, "record": { "title": "Configurações de Registro", "desc": "Configure as configurações relacionadas a registros aqui, incluindo descrição de registro e configuração da barra de ferramentas.", "model": { "title": "Configurações do Modelo", "markDesc": { "title": "Descrição do Registro", "desc": "Para processar registros reconhecidos por OCR e gerar descrições de registros" } }, "toolbar": { "title": "Configurações da Barra de Ferramentas", "recordToolbar": { "title": "Barra de Ferramentas de Registro", "desc": "Personalize a visibilidade e a ordem dos botões da barra de ferramentas de registro", "button": "Configurar", "text": { "desc": "记录文本内容" }, "recording": { "desc": "录音记录功能" }, "scan": { "desc": "扫描识别图片中的文字" }, "image": { "desc": "上传图片到笔记" }, "link": { "desc": "记录网页链接" }, "file": { "desc": "上传文件到笔记" }, "todo": { "desc": "创建待办事项" } } } }, "uploadStore": { "uploadConfirm": "Configuração de Carregamento: Por favor, certifique-se de que o repositório de sincronização é privado, caso contrário, seus dados serão expostos!", "downloadConfirm": "Baixar a configuração irá sobrescrever a configuração local e exigirá um reinício para ter efeito!", "uploadSuccess": "Upload bem-sucedido", "downloadSuccess": "Download bem-sucedido", "upload": "Carregar", "download": "Baixar" }, "about": { "title": "Sobre", "desc": "Um assistente de anotações focado em registro e escrita.", "version": "NoteGen v{version}", "checkReleases": "Verificar Histórico de Lançamentos", "language": "Idioma", "checkUpdate": "Verificar Atualizações", "checkError": "Falha ao verificar atualizações", "updateAvailable": "Atualizar para nova versão", "updateDownloading": "Atualizando {downloaded} / {contentLength}", "updateInstalled": "Reiniciar aplicativo", "noUpdate": "A versão atual é a mais recente", "ignoreVersion": "Ignorar esta versão", "ignoreVersionSuccess": "Esta atualização de versão foi ignorada", "items": { "home": { "title": "Início", "buttonName": "Abrir", "desc": "Visite o site para saber mais sobre o NoteGen." }, "guide": { "title": "Guia", "buttonName": "Abrir", "desc": "Veja o guia de configuração, aprenda como configurar modelos, sincronização e outras informações." }, "github": { "title": "GitHub", "buttonName": "Ver", "desc": "Se o NoteGen te ajuda, por favor, dê uma estrela para incentivar!" }, "releases": { "title": "Log de Atualizações", "buttonName": "Ver", "desc": "Veja o log de atualizações, saiba mais sobre as novidades do NoteGen." }, "issues": { "title": "Feedback de Problemas", "buttonName": "Comentários", "desc": "Se você encontrar um bug no NoteGen, por favor, reporte aqui." }, "discussions": { "title": "Discussões", "buttonName": "Discutir", "desc": "Se você quiser discutir com o autor ou outros usuários, pode se juntar ao grupo de discussão." } } }, "memories": { "title": "Gerenciamento de Memória", "desc": "Recurso de memória de longo prazo da IA que permite que a IA lembre de suas preferências de escrita, base de conhecimento e hábitos de anotações.", "stats": { "total": "Total de Memórias", "preferences": "Preferências", "knowledge": "Conhecimento", "memories": "记忆" }, "form": { "title": "Adicionar Nova Memória", "contentLabel": "Conteúdo da Memória", "contentPlaceholder": "ex: Prefiro respostas em chinês, sou um especialista em React...", "categoryLabel": "Tipo", "preferenceDesc": "Preferência (idioma, formato, estilo, etc.)", "knowledgeDesc": "Conhecimento (fatos, experiência, especialização, etc.)", "save": "Salvar Memória", "saving": "Salvando...", "categoryDescription": "记忆分为两种类型:", "preferenceDescription": "偏好:语言、格式、风格等设置,每次对话都会自动加载", "memoryDescription": "记忆:事实、经验、专长等信息,根据对话内容智能匹配", "preferenceLabel": "偏好", "memoryLabel": "记忆", "memoryDesc": "事实、经验、专长等" }, "listTitle": "Minhas Memórias", "addMemory": "Adicionar Memória", "empty": "Nenhuma memória ainda, adicione sua primeira memória!", "emptyHint": "Você pode adicionar memórias manualmente ou usar frases como \"por favor, lembre-se\" ou \"lembre-se disso\" nas conversas para que a IA crie memórias automaticamente.", "preference": "Preferência", "knowledge": "Conhecimento", "replaced": "Substituído", "accessCount": "Acessado {count} vezes", "tabs": { "all": "Todas", "preference": "Preferências", "knowledge": "Conhecimento", "memory": "记忆" }, "success": "Sucesso", "saved": "Memória salva", "updated": "Memória atualizada (memória similar substituída)", "deleted": "Memória excluída", "cleared": "Todas as memórias limpas", "found": "Encontrado {count} memórias", "error": "Erro", "errorEmpty": "Por favor, insira o conteúdo da memória", "errorSave": "Falha ao salvar", "errorDelete": "Falha ao excluir", "errorList": "Falha ao obter lista de memórias", "errorEmbedding": "Falha ao gerar embedding, verifique a configuração do modelo de embedding", "errorClear": "Falha ao limpar", "memory": "记忆" }, "defaultModel": { "title": "Modelo Padrão", "desc": "Aqui, você pode usar diferentes modelos para diferentes cenários, para melhorar a eficiência e reduzir custos.", "tooltip": "Usar modelo principal", "noModel": "Não usar", "placeholder": "Por favor, selecione ou procure por modelos", "main": "Modelo principal", "options": { "primaryModel": { "title": "Modelo principal", "desc": "Como o modelo principal para todos os cenários, este modelo é usado se outros modelos de diálogo não selecionarem o modelo padrão." }, "markDesc": { "title": "Descrição do Registro", "desc": "Usado para processar registros após reconhecimento OCR, gerando descrições de registro." }, "placeholder": { "title": "Sugestão da IA", "desc": "Prompts de sugestão da IA são usados para geração de conteúdo no placeholder da conversa de IA da página de registro." }, "completion": { "title": "Conclusão Rápida", "desc": "Conclusão inline de IA para editor Markdown, semelhante ao GitHub Copilot, gera rapidamente conteúdo de continuação" }, "commit": { "title": "Gerar Mensagem de Commit Automaticamente", "desc": "Usado para gerar automaticamente mensagens de commit Git, gerando inteligentemente mensagens de commit descritivas com base nas alterações do conteúdo do arquivo." }, "translate": { "title": "Tradução", "desc": "Usado para cenários de tradução de conteúdo." }, "embedding": { "title": "Modelo de Embedding", "desc": "Usado para cenários de embedding e vetorização de texto." }, "reranking": { "title": "Modelo de Reordenação", "desc": "Usado para reordenar e otimizar resultados de busca." }, "condense": { "title": "摘要模型", "desc": "用于压缩历史对话内容,节省 token 使用量" } }, "mainModel": "Modelo principal" }, "audio": { "title": "Configurações de Áudio", "desc": "Aqui, você pode configurar as definições de áudio, incluindo as funções de conversão de texto em fala (TTS) e fala em texto (STT).", "mode": { "title": "Modo", "auto": "Automático (Recomendado)", "local": "Somente local", "model": "Somente modelo" }, "tts": { "title": "Texto para Fala (TTS)", "desc": "Configure a funcionalidade de leitura em voz alta para fornecer reprodução de voz para o conteúdo do chat.", "modeDesc": "Prefere as vozes do navegador e do sistema por padrão e usa um modelo apenas quando necessário para melhorar a experiência.", "model": { "title": "Modelo TTS", "desc": "Opcional. Configure um modelo para aprimorar o modo automático ou usar o modo somente modelo." }, "speed": { "title": "Velocidade da Fala", "desc": "Ajuste a velocidade de reprodução da voz, variando de 0.5x a 2x, sendo 1x a velocidade normal." } }, "stt": { "title": "Fala para Texto (STT)", "desc": "Configure o reconhecimento de voz para converter fala em registros de texto.", "modeDesc": "Prefere o reconhecimento nativo do navegador por padrão e usa um modelo como fallback quando o suporte local não estiver disponível.", "model": { "title": "Modelo STT", "desc": "Opcional. Configure um modelo para fallback automático ou para o modo somente modelo." } } }, "readAloud": { "title": "Ler em Voz Alta", "desc": "Configure o comportamento da leitura em voz alta. As vozes do sistema são preferidas por padrão, e a voz de modelo funciona como aprimoramento.", "options": { "mode": { "title": "Modo", "desc": "O modo automático prefere as vozes do sistema e só tenta um modelo quando a fala local não está disponível.", "auto": "Automático (Recomendado)", "local": "Somente local", "model": "Somente modelo" }, "audioModel": { "title": "Modelo de Leitura", "desc": "Opcional. Configure um modelo para aprimorar o modo automático ou usar o modo somente modelo." }, "speed": { "title": "Velocidade", "desc": "Ajuste a velocidade da leitura entre 0.5x e 2x, com 1x como padrão." } } }, "prompt": { "title": "Prompt", "promptTitle": "Título do Prompt", "desc": "Aqui, você pode adicionar e gerenciar prompts, ajudando a IA a entender melhor suas necessidades.", "addPrompt": "Adicionar Prompt", "selectPrompt": "Selecionar Prompt", "configPrompt": "Configurar Prompt", "noContent": "Nenhum conteúdo", "addPromptDesc": "Por favor, insira o nome e o conteúdo do prompt, ajudando a IA a entender melhor suas necessidades.", "promptTitlePlaceholder": "Por favor, insira o nome do prompt", "promptContentPlaceholder": "Por favor, insira o conteúdo do prompt", "promptContent": "Conteúdo do Prompt", "optimizePrompt": "Otimizar Prompt", "optimizing": "Otimizando...", "optimizeSuccess": "Prompt otimizado com sucesso", "optimizeFailed": "Falha ao otimizar o prompt, por favor, tente novamente mais tarde", "noContentToOptimize": "Por favor, insira o conteúdo do prompt primeiro" }, "sync": { "title": "Sincronização", "desc": "Aqui, você pode configurar o repositório de sincronização, que pode ajudá-lo a sincronizar registros, arquivos markdown, configurações do sistema e outras informações.", "selectPlatform": "Selecionar Plataforma de Sincronização", "platformSettings": "Selecionar Plataforma", "settings": "Configurações de Sincronização", "platformDesc": "Configure o Token e informações do repositório para habilitar a sincronização", "moreSettings": "Mais Configurações", "repoStatus": "Status do Repositório", "syncRepo": "Repositório de Sincronização", "syncRepoDesc": "Sincronizar arquivos markdown na escrita", "imageRepo": "Repositório de Imagens", "imageRepoDesc": "Sincronize suas imagens para o repositório, usando jsdelivr para aceleração", "status": { "connected": "Conectado", "disconnected": "Desconectado", "failed": "Conexão Falhou", "unconfigured": "Não Configurado" }, "uploadRecords": "Enviar Registros e Config", "downloadConfig": "Baixar Registros e Config", "cloudSync": "Sinc Registros e Config", "localBackupAll": "Backup Local (Tudo)", "private": "Privado", "public": "Público", "createdAt": "Criado {time}", "updatedAt": "Última atualização {time}", "newToken": "Criar Token de Acesso", "newTokenDesc": "Ao criar um novo token, por favor, certifique-se de marcar a permissão 'repo', e após a configuração, ele criará automaticamente um repositório de arquivos (privado) e um repositório de imagens.", "giteeTokenDesc": "O token de acesso pessoal do Gitee é usado para sincronização de dados. Ele precisa de permissões de leitura e escrita do repositório. Após a configuração, ele criará automaticamente um repositório de arquivos (privado) e um repositório de imagens.", "imageRepoSetting": "Ativar Hospedagem de Imagens", "imageRepoSettingDesc": "Você já configurou um repositório de imagens, pode escolher usar o repositório de imagens ou usar o armazenamento local.", "jsdelivrSetting": "jsDelivr", "autoSyncDesc": "Quando habilitado, o editor sincronizará automaticamente com o GitHub 10 segundos após a interrupção da entrada", "giteeAutoSyncDesc": "Quando habilitado, o editor sincronizará automaticamente com o Gitee 10 segundos após a interrupção da entrada", "customSyncRepo": "Nome Personalizado do Repositório de Sincronização", "customSyncRepoDesc": "Deixe em branco para usar o nome do repositório padrão", "customImageRepo": "Nome Personalizado do Repositório de Imagens", "customImageRepoDesc": "Deixe em branco para usar o nome do repositório padrão", "backupMethod": "Método de Backup", "backupMethodDesc": "Após definir como o método de backup principal, todas as funções relacionadas à sincronização na escrita usarão o método de backup atual (exceto para hospedagem de imagens)", "createRepo": "Criar Repositório", "creating": "Criando", "checkRepo": "Verificar Repositório", "checking": "Verificando", "enterToken": "Por favor, insira o Access Token", "enterTokenHint": "Por favor, insira o Access Token primeiro para verificar o status do repositório", "defaultRepoName": "Padrão: {name}", "gitlabInstanceType": "Tipo de Instância GitLab", "gitlabInstanceTypeDesc": "Selecione o tipo de instância GitLab para conectar", "gitlabInstanceTypePlaceholder": "Selecione o Tipo de Instância GitLab", "gitlabInstanceTypeOptions": { "selfHosted": "Instância Auto-hospedada", "selfHostedDesc": "Insira o endereço do seu servidor GitLab auto-hospedado (ex: https://gitlab.example.com)" }, "gitlabAccessTokenDesc": "Crie um token de acesso pessoal em {instanceDisplayName}, requer permissão 'api'", "giteaInstanceType": "Tipo de Instância Gitea", "giteaInstanceTypeDesc": "Selecione o tipo de instância Gitea para conectar", "giteaInstanceTypePlaceholder": "Selecione o Tipo de Instância Gitea", "giteaInstanceTypeOptions": { "selfHosted": "Instância Auto-hospedada", "selfHostedDesc": "Insira o endereço do seu servidor Gitea auto-hospedado (ex: https://gitea.example.com)" }, "giteaAccessTokenDesc": "Crie um token de acesso pessoal em {instanceDisplayName}, requer permissão total de repositório", "s3": { "title": "Sincronização S3", "description": "Sincronize suas notas usando armazenamento compatível com S3", "status": "Status da Conexão", "connected": "Conectado", "connecting": "Conectando", "disconnected": "Desconectado", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "Por favor, insira o Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "Por favor, insira o Secret Access Key", "region": "Região", "bucket": "Bucket", "bucketPlaceholder": "Por favor, insira o nome do bucket", "endpoint": "Endpoint", "pathPrefix": "Prefixo do Caminho", "pathPrefixPlaceholder": "Por favor, insira o prefixo do caminho", "pathPrefixDesc": "Usado para diferenciar arquivos entre diferentes usuários, similar ao nome do repositório", "customDomain": "Domínio Personalizado", "testConnection": "Testar Conexão", "testing": "Testando", "saveConfig": "Salvar Configuração", "saving": "Salvando" }, "webdav": { "title": "Sincronização WebDAV", "description": "Sincronize suas notas usando o protocolo WebDAV", "status": "Status da Conexão", "connected": "Conectado", "connecting": "Conectando", "disconnected": "Desconectado", "url": "URL do Servidor", "urlPlaceholder": "Por favor, insira a URL do servidor WebDAV", "urlDesc": "Suporta Synology, QNAP, Nextcloud e outros serviços WebDAV", "username": "Nome de Usuário", "usernamePlaceholder": "Por favor, insira o nome de usuário", "password": "Senha", "passwordPlaceholder": "Por favor, insira a senha", "pathPrefix": "Prefixo do Caminho", "pathPrefixPlaceholder": "Por favor, insira o prefixo do caminho", "pathPrefixDesc": "Usado para diferenciar arquivos entre diferentes usuários", "testConnection": "Testar Conexão", "testing": "Testando", "saveConfig": "Salvar Configuração", "saving": "Salvando" }, "autoSync": "Sincronização Automática", "autoSyncOptions": { "placeholder": "Selecione o tempo de sincronização automática", "disabled": "Desabilitado", "2s": "2 segundos", "3s": "3 segundos", "5s": "5 segundos", "10s": "10 segundos", "20s": "20 segundos", "30s": "30 segundos", "1m": "1 minuto", "2m": "2 minutos" }, "autoPullOnOpen": "Puxar automaticamente ao abrir arquivos", "autoPullOnOpenDesc": "Ao abrir um arquivo, puxa automaticamente a versão remota se for mais recente", "autoPullOnSwitch": "Puxar automaticamente ao trocar de arquivo", "autoPullOnSwitchDesc": "Ao trocar para outro arquivo, puxa automaticamente a versão remota se for mais recente", "exclusions": { "title": "Configuração de Exclusão de Sincronização", "desc": "As seguintes configurações não serão sincronizadas entre dispositivos, pois são específicas do dispositivo", "workspacePath": "Caminho do Workspace", "workspaceHistory": "Histórico do Workspace", "assetsPath": "Caminho dos Recursos", "uiScale": "Escala da UI", "contentTextScale": "Escala do Texto do Conteúdo", "customCss": "CSS Personalizado", "reason": "Essas configurações podem diferir entre dispositivos, excluí-las da sincronização evita erros de caminho e outros problemas" }, "settingsSync": { "uploadSuccess": "Configurações enviadas com sucesso", "uploadFailed": "Falha ao enviar configurações", "downloadSuccess": "Configurações baixadas com sucesso", "downloadFailed": "Falha ao baixar configurações", "autoSync": "As configurações serão sincronizadas automaticamente durante o upload/download (excluindo configurações específicas do dispositivo como o caminho do workspace)" }, "jsdelivrSettingDesc": "Use jsDelivr para acelerar o acesso às imagens." }, "imageHosting": { "title": "Hospedagem de Imagens", "desc": "Aqui, você pode configurar serviços de hospedagem de imagens para armazenar e gerenciar suas imagens.", "type": "Selecionar Plataforma", "typeDesc": "Selecione o provedor de serviços de hospedagem de imagens", "customRepoName": "Nome Personalizado do Repositório", "customRepoNameDesc": "Deixe em branco para usar o nome do repositório padrão", "isPrimaryBackup": "Método principal atual de hospedagem de imagens: {type}", "setPrimaryBackup": "Definir como Hospedagem de Imagem Principal", "smms": { "token": { "desc": "Por favor, crie e insira o Token SM.MS.", "createToken": "Criar Token" }, "disk": "Uso do Disco", "error": "Falha ao obter, por favor, verifique a rede ou se o Token está correto." }, "picgo": { "desc": "URL do servidor PicGo", "ok": "O serviço está em execução, por favor, garanta que a hospedagem de imagens do PicGo esteja configurada.", "error": "O serviço não está em execução, por favor, garanta que o PicGo (v2.2.0+) esteja em execução, caso contrário, o upload de imagens falhará." }, "github": { "title": "Hospedagem de Imagens do GitHub", "description": "Use o repositório do GitHub como serviço de armazenamento de imagens", "repoStatus": "Status do Repositório", "repoExists": "Repositório Existe", "repoNotExists": "Repositório Não Encontrado", "checking": "Verificando", "creating": "Criando", "manualCreateTitle": "Criação Manual de Repositório Necessária", "manualCreateDesc": "Por favor, siga estes passos para criar o repositório de hospedagem de imagens:", "createSteps": { "step1": "Acesse o GitHub e faça login na sua conta", "step2": "Clique no botão \"+\" no canto superior direito, selecione \"Novo repositório\"", "step3": "Defina o nome do repositório como:", "step4": "Opcionalmente, defina como repositório privado (recomendado)", "step5": "Clique em \"Criar repositório\" para concluir a criação", "step6": "Após a criação, clique no botão \"Verificar Novamente\" abaixo" }, "createNewRepo": "Criar Novo Repositório", "recheckRepo": "Verificar Novamente", "recheckingRepo": "Verificando...", "createRepo": "Criar Repositório", "creatingRepo": "Criando..." }, "s3": { "title": "Armazenamento de Objetos S3", "description": "Configure o AWS S3 ou serviço de armazenamento de objetos compatível com S3 como hospedagem de imagens", "status": "Status da Conexão", "connected": "Conectado", "connecting": "Conectando", "disconnected": "Desconectado", "accessKeyId": "ID da Chave de Acesso", "accessKeyIdPlaceholder": "Insira o ID da Chave de Acesso", "secretAccessKey": "Chave de Acesso Secreta", "secretAccessKeyPlaceholder": "Insira a Chave de Acesso Secreta", "region": "Região", "bucket": "Bucket", "bucketPlaceholder": "Insira o nome do bucket", "advancedSettings": "Configurações Avançadas", "endpoint": "Endpoint Personalizado", "endpointDesc": "Deixe em branco para AWS S3, ou insira o endpoint do serviço compatível com S3", "customDomain": "Domínio Personalizado", "customDomainDesc": "Opcional, domínio personalizado para acessar imagens", "pathPrefix": "Prefixo do Caminho", "pathPrefixDesc": "Opcional, prefixo do caminho para armazenamento de imagens", "save": "Salvar Configuração", "test": "Testar Conexão", "setAsPrimary": "Definir como Principal", "error": "Erro de Configuração", "requiredFields": "Por favor, preencha os campos obrigatórios: ID da Chave de Acesso, Chave de Acesso Secreta, Região e Bucket", "saveSuccess": "Configuração Salva", "saveSuccessDesc": "A configuração do S3 foi salva", "saveError": "Falha ao Salvar Configuração", "testSuccess": "Teste de Conexão Bem-sucedido", "testSuccessDesc": "A conexão S3 está funcionando, pronta para enviar imagens", "testFailed": "Falha no Teste de Conexão", "testFailedDesc": "Por favor, verifique a configuração e a conexão de rede", "testFirstDesc": "Por favor, teste a conexão com sucesso antes de definir como principal", "setPrimarySuccess": "Definido com Sucesso", "setPrimarySuccessDesc": "O S3 foi definido como a hospedagem de imagem principal" } }, "imageMethod": { "title": "Reconhecimento de Imagem", "desc": "Aqui, você pode configurar definições relacionadas ao reconhecimento de imagem, suportando OCR e VLM de duas maneiras.", "setPrimary": "Definir como padrão", "isPrimary": "{type} foi definido como padrão", "ocr": { "title": "OCR", "languagePacks": "Pacote de Idioma", "checkModels": "Aqui você pode pesquisar todos os modelos", "modelInstruction": "Separados por vírgula, por exemplo: eng,chi_sim" }, "vlm": { "title": "Modelo de Linguagem Visual", "desc": "Use o modelo de linguagem visual para reconhecer o conteúdo da imagem." }, "enable": { "title": "Ativar reconhecimento de imagens", "desc": "Quando ativado, ao registrar uma captura de tela ou inserir uma imagem, o reconhecimento será feito automaticamente. Quando desativado, a etapa de reconhecimento de imagem será ignorada." } }, "backupSync": { "title": "Dados de Backup", "desc": "Aqui, você pode usar outros métodos para fazer backup de seus dados, você pode fazer backup regularmente para garantir a segurança dos dados.", "localBackup": { "tabTitle": "Backup Local", "export": { "title": "Exportar Backup", "desc": "Empacote os dados do aplicativo em um arquivo .zip e salve no local especificado.", "button": "Escolher Local e Exportar", "simpleButton": "Exportar", "exporting": "Exportando..." }, "import": { "title": "Importar Backup", "desc": "Restaure os dados do aplicativo a partir de um arquivo .zip, irá sobrescrever todos os dados atuais.", "button": "Escolher Arquivo e Importar", "importing": "Importando...", "warning": "A operação de importação sobrescreverá todos os dados atuais, por favor, garanta que o conteúdo importante esteja salvo!" }, "exportDialog": { "title": "Escolha o local para salvar o arquivo de backup" }, "importDialog": { "title": "Escolha o arquivo de backup para importar" }, "exportSuccess": "Backup exportado com sucesso!", "exportError": "Falha na exportação do backup", "importSuccess": "Backup importado com sucesso! O aplicativo será reiniciado para aplicar as alterações.", "importError": "Falha na importação do backup", "restartConfirm": "Importação concluída! Reiniciar o aplicativo agora para aplicar as alterações?" } }, "template": { "title": "Modelo", "desc": "Aqui você pode criar e gerenciar templates de organização personalizados para ajudar a IA a organizar o conteúdo dos registros de acordo com suas necessidades.", "customTemplate": "Template Personalizado", "addTemplate": "Adicionar Template Personalizado", "deleteConfirm": "Tem certeza de que deseja excluir este template?", "status": "Estado", "name": "Nome", "content": "Conteúdo", "scope": "Escopo", "selectScope": "Selecionar Escopo", "addTemplateDesc": "Por favor, insira o nome e o conteúdo do template personalizado, ajudando a IA a entender melhor suas necessidades.", "editTemplate": "Editar Template Personalizado", "noContent": "Nenhum conteúdo", "range": { "all": "Todos", "today": "Hoje", "week": "Semana Passada", "month": "Mês Passado", "threeMonth": "Últimos 3 Meses", "year": "Último Ano" } }, "shortcut": { "title": "Atalhos", "screenshot": "Registro por Captura de Tela", "link": "Registro por Link", "textRecord": "Registro por Texto", "windowPin": "Fixar Janela" }, "theme": { "title": "Aparência", "appTheme": "Tema do aplicativo", "previewTheme": "Tema do conteúdo de visualização", "codeTheme": "Tema de destaque do bloco de código", "selectTheme": "Selecionar Tema" }, "chat": { "title": "Configurações de Chat", "desc": "Configure as configurações relacionadas ao chat aqui, incluindo geração de resumo.", "primaryModel": { "title": "Modelo Principal", "model": { "title": "Modelo de Chat Principal", "desc": "Selecione o modelo de IA principal para conversas diárias" } }, "toolbar": { "title": "Configurações da Barra de Ferramentas", "chatToolbar": { "title": "Barra de Ferramentas de Chat", "desc": "Personalize a visibilidade e a ordem dos botões da barra de ferramentas de chat", "button": "Configurar", "modelSelect": { "desc": "Alternar o modelo de IA para conversa" }, "promptSelect": { "desc": "Selecionar o prompt predefinido para a conversa" }, "chatLanguage": { "desc": "Definir o idioma da conversa" }, "chatLink": { "title": "Vincular Etiqueta", "desc": "Vincular conteúdo de notas da etiqueta atual ao contexto da conversa" }, "fileLink": { "desc": "Vincular arquivos ou pastas ao contexto da conversa" }, "mcpButton": { "desc": "Selecionar e conectar servidores MCP para usar ferramentas externas" }, "ragSwitch": { "title": "Base de Conhecimento", "desc": "Ativar busca na base de conhecimento vetorial" }, "clipboardMonitor": { "title": "Monitorar Área de Transferência", "desc": "Monitorar automaticamente alterações no conteúdo da área de transferência" }, "newChat": { "desc": "Iniciar nova conversa" }, "clearContext": { "desc": "Limpar contexto da conversa, manter histórico" }, "clearChat": { "desc": "Excluir todos os registros de chat" } } }, "condense": { "title": "Resumo da Conversa", "enable": { "title": "Ativar Resumo", "desc": "Comprimir automaticamente conversas longas para economizar uso de tokens" }, "model": { "title": "Modelo de Resumo", "desc": "Selecione o modelo de IA para gerar resumos", "placeholder": "Usar modelo principal" }, "threshold": { "title": "Limiar de Gatilho", "desc": "Verificar compressão quando mensagens da IA excederem esta contagem" }, "minToken": { "title": "Contagem Mínima de Tokens", "desc": "Comprimir apenas mensagens que excedam esta contagem de tokens" }, "keepLatest": { "title": "Manter Mais Recentes", "desc": "Manter as últimas N mensagens da IA não compactadas" }, "maxLength": { "title": "Comprimento Máximo do Resumo", "desc": "Controlar a contagem máxima de palavras dos resumos gerados" }, "prompt": { "title": "Prompt de Resumo Personalizado", "desc": "Personalize o modelo de prompt para gerar resumos", "label": "Modelo de Prompt", "placeholder": "Digite o prompt personalizado...", "help": "Use {content} como um espaço reservado para o conteúdo original", "save": "Salvar", "reset": "Redefinir para o Padrão" } }, "inspiration": { "title": "Modelo de Inspiração", "model": { "title": "Gerador de Sugestões Rápidas", "desc": "Gere sugestões de prompt rápidas para ajudar os usuários a iniciar conversas" } }, "conversationTitle": { "title": "会话标题", "model": { "title": "标题生成模型", "desc": "选择用于生成会话标题的 AI 模型" } } }, "dev": { "title": "Desenvolvedor", "desc": "Aqui você pode configurar opções de desenvolvedor, incluindo proxy de rede, limpeza de dados e gerenciamento de arquivos de configuração.", "clearData": "Limpar Dados", "clearDataConfirm": "Tem certeza de que deseja limpar os dados?", "proxy": "Proxy, usado para resolver problemas de rede, após a configuração, é recomendado reiniciar o aplicativo.", "proxyPlaceholder": "Insira o endereço do proxy", "proxyTitle": "Proxy de Rede", "clearDataTitle": "Limpar Dados", "clearDataDesc": "Limpar informações de dados, incluindo configuração do sistema e banco de dados (incluindo registros).", "clearFileTitle": "Limpar Arquivos", "clearFileDesc": "Limpar arquivos, incluindo imagens e artigos.", "clearButton": "Limpar", "configFileTitle": "Gerenciamento de Arquivo de Configuração", "configFileDesc": "Importar e exportar arquivos de configuração. A importação sobrescreverá a configuração atual e terá efeito após a reinicialização.", "importConfigTitle": "Importar Arquivo de Configuração", "exportConfigTitle": "Exportar Arquivo de Configuração", "importConfigSuccessMobile": "Configuração baixada com sucesso, por favor, reinicie o aplicativo manualmente", "exportConfigSuccess": "Exportação bem-sucedida", "importButton": "Importar", "exportButton": "Exportar" }, "ai": { "title": "Gerenciamento de Modelos", "desc": "Aqui, você pode adicionar e gerenciar vários serviços de modelo personalizados. Após a configuração, você desbloqueará recursos relacionados à IA, como funções de organização e conversação.", "modelTitle": "Nome Personalizado", "modelConfigTitle": "Configuração do Modelo", "modelConfigDesc": "Cada configuração corresponde a um modelo de IA, você pode criar novas configurações através de templates ou personalizadas.", "providerInfo": "Informações do Provedor", "providerInfoDesc": "Esta configuração é criada com base em um template de provedor, com nome e URL pré-configurados.", "create": "Criar", "createDesc": "Selecione uma configuração vazia ou crie uma nova configuração usando o template do fornecedor.", "createSection": { "title": "Configuração de Modelo Personalizado", "descWithoutModels": "Adicione configurações de modelo de IA personalizadas para usar serviços de modelo mais poderosos." }, "config": "Configurar", "custom": "Personalizado", "addCustomModel": "Personalizado", "deleteCustomModel": "Excluir", "deleteCustomModelConfirm": "Tem certeza de que deseja excluir este modelo personalizado?", "copyConfig": "Copiar", "builtin": "Embutido", "modelSupport": "Suporta apenas modelos de IA com protocolo OpenAI", "apiKeyUrl": "Criar Chave de API", "modelType": { "title": "Tipo de Modelo", "desc": "Selecione o tipo de modelo de IA com base em sua capacidade", "chat": "Bate-papo", "image": "Imagem", "video": "Vídeo", "tts": "Texto para Fala (TTS)", "stt": "Fala para Texto (STT)", "embedding": "Embedding", "rerank": "Reordenação", "audio": "Áudio" }, "modelList": { "error": { "title": "Falha ao obter lista de modelos", "description": "Por favor, verifique se a Chave de API ou a rede estão corretas" } }, "selectModel": "Por favor, selecione um modelo", "modelProviderDesc": "Modelos personalizados suportam apenas modelos de IA com protocolo OpenAI.", "modelTitleDesc": "Nome personalizado, usado para identificar modelos de IA, por favor, não repita.", "modelBaseUrlDesc": "Você só precisa configurar o número da versão, por exemplo: https://api.openai.com/v1, o sufixo será adicionado automaticamente.", "modelDesc": "Alguns modelos suportam a obtenção da lista de modelos, se não for suportado, por favor, configure manualmente.", "temperatureDesc": "Controla a aleatoriedade da saída. Valores mais baixos tornam o conteúdo gerado mais determinístico.", "topPDesc": "Um método de amostragem nucleus, onde o modelo considera os resultados dos tokens com massa de probabilidade top_p. Então, 0.1 significa considerar apenas os 10% superiores da massa de probabilidade. Geralmente, sugerimos alterar este ou a temperatura, mas não ambos.", "customHeaders": "Cabeçalhos Personalizados", "customHeadersDesc": "Adicione cabeçalhos HTTP personalizados com pares chave-valor.", "headerKey": "Chave", "headerValue": "Valor", "addHeader": "Adicionar Cabeçalho", "connectionSuccess": "Teste de conexão com IA bem-sucedido", "voice": "Tipo de Voz", "voiceDesc": "Especifique o tipo de voz para modelos de áudio, como 'alloy', 'echo', 'fable', etc.", "voicePlaceholder": "Insira o tipo de voz, ex: alloy", "defaultModels": { "title": "Modelos Gratuitos Padrão", "desc": "O NoteGen fornece serviços de modelo de IA gratuitos para usuários, permitindo funcionalidade básica sem configuração.", "chatModel": { "name": "Qwen/Qwen3-8B", "type": "Modelo de Chat", "desc": "Adequado para conversas diárias e geração de texto" }, "embeddingModel": { "name": "BAAI/bge-m3", "type": "Modelo de Embedding", "desc": "Usado para vetorização de texto e busca semântica" }, "visionModel": { "name": "OpenGVLab/InternVL2-8B", "type": "Modelo de Visão", "desc": "Suporta compreensão de imagens e perguntas visuais" }, "completionModel": { "name": "Conclusão Rápida", "type": "Modelo de Conclusão", "desc": "Conclusão inline de IA para editor Markdown, semelhante ao GitHub Copilot, gera rapidamente conteúdo de continuação" }, "commit": { "title": "Mensagem de Commit", "desc": "Usado para gerar automaticamente mensagens de commit Git, gerando inteligentemente mensagens de commit descritivas com base nas alterações do conteúdo do arquivo." }, "poweredBy": "Fornecido por SiliconFlow" }, "connectionFailed": "Falha na conexão", "enableStream": "Resposta em streaming", "enableStreamDesc": "Ativar resposta em streaming permite mostrar o conteúdo gerado em tempo real, mas alguns modelos podem não oferecer suporte a este recurso.", "selectConfig": "Selecione uma configuração", "models": "Lista de modelos", "modelsDesc": "Gerencie aqui todos os modelos da configuração atual. Cada modelo pode ter tipos e parâmetros diferentes.", "addModel": "Adicionar modelo", "newModel": "Novo modelo", "checkConnection": "Testar conexão", "model": "Modelo" }, "ocr": { "title": "OCR", "languagePacks": "Pacotes de Idioma", "checkModels": "Verifique todos os modelos aqui", "modelInstruction": "Separe com vírgulas, ex: eng,chi_sim" }, "file": { "title": "Configurações de Arquivo", "desc": "Aqui, você pode gerenciar as configurações do workspace e outras opções relacionadas a arquivos.", "workspace": { "title": "Configurações do Workspace", "desc": "Defina o diretório do workspace do aplicativo onde os arquivos serão salvos", "current": "Caminho Atual do Workspace", "defaultPath": "Workspace Padrão", "default": "Usando caminho do workspace padrão", "custom": "Usando caminho do workspace personalizado", "select": "Selecionar Diretório do Workspace", "reset": "Redefinir para Caminho Padrão", "history": "Caminhos Históricos", "selectFromHistory": "Selecionar workspace do histórico", "clearHistory": "Limpar Histórico", "actions": "Ações", "searchPlaceholder": "Buscar caminhos do workspace...", "noResults": "Nenhum resultado encontrado" }, "info": { "title": "Informações do Workspace", "desc": "Após alterar o workspace, você precisa reiniciar o aplicativo para que as alterações tenham efeito total. Os arquivos no novo workspace serão exibidos após a reinicialização." }, "toast": { "updated": "Workspace Atualizado", "updatedDesc": "Workspace definido para: {path}", "reset": "Workspace Redefinido", "resetDesc": "Restaurado para o workspace padrão", "error": "Falha na Seleção do Workspace", "errorDesc": "Não foi possível selecionar o diretório do workspace, por favor, tente novamente", "resetError": "Falha na Redefinição do Workspace", "resetErrorDesc": "Não foi possível redefinir para o workspace padrão, por favor, tente novamente" }, "assets": { "title": "Caminho dos Recursos", "desc": "Defina o caminho onde os recursos (ex: imagens, vídeos, arquivos, etc.) usados na escrita serão salvos. Os recursos serão salvos no mesmo nível do arquivo markdown atualmente editado.", "select": "Defina o caminho onde os recursos usados na escrita serão salvos" } }, "shortcuts": { "title": "Atalhos", "desc": "Aqui, você pode configurar atalhos para ajudá-lo a usar o NoteGen com mais eficiência.", "resetDefaults": "Redefinir", "clear": "Limpar", "noShortcut": "Nenhum Atalho", "shortcuts": { "openWindow": { "title": "Abrir/Ocultar Janela", "desc": "Abrir/Ocultar a janela principal." }, "quickRecordText": { "title": "Gravação Rápida de Texto", "desc": "Abrir rapidamente a janela principal e alternar para a gravação de texto." } } }, "skills": { "title": "Skills", "desc": "Skills são pacotes reutilizáveis de capacidades de IA, permitindo que o assistente aplique automaticamente comportamentos específicos conforme a tarefa.", "enable": "Ativar Skills", "enableDesc": "Quando ativado, a IA pode usar as Skills configuradas.", "autoMatch": "Combinar Skills automaticamente", "autoMatchDesc": "Seleciona automaticamente Skills adequadas com base no que você digitar.", "project": "Skills do workspace", "global": "Skills globais", "globalPath": "Local de armazenamento das Skills globais", "openInFileManager": "Abrir no gerenciador de arquivos", "createSkill": "Criar Skill", "editSkill": "Editar Skill", "deleteSkill": "Excluir Skill", "exportSkill": "Exportar Skill", "importSkill": "Importar Skill", "selectSkillZip": "Selecionar arquivo .zip de Skill", "importHelp": "Suporta importar Skill em formato .zip. O arquivo .zip precisa conter um arquivo SKILL.md.", "importing": "Importando...", "imported": "Importado", "importSuccess": "Importado com sucesso", "importError": "Falha ao importar", "noSkills": "Ainda não há Skills", "noSkillsDesc": "Crie ou importe Skills para começar a usar.", "noSkillsGlobal": "Ainda não há Skills globais", "noSkillsGlobalDesc": "Crie ou importe Skills para usar em todos os projetos.", "emptyWorkspace": "Não há Skills neste workspace", "emptyWorkspaceDesc": "Crie um arquivo SKILL.md na pasta skills para adicionar uma Skill.", "installedGlobalSkills": "Skills globais instaladas", "basicSettings": "Configurações básicas", "metadata": "Metadados", "skillName": "Nome da Skill", "skillDescription": "Descrição", "skillVersion": "Versão", "skillAuthor": "Autor", "nameRequired": "Informe o nome da Skill", "descriptionRequired": "Informe a descrição", "namePlaceholder": "note-organizer", "versionPlaceholder": "1.0.0", "descriptionPlaceholder": "Organiza e otimiza automaticamente a estrutura das notas...", "authorPlaceholder": "Seu nome", "descriptionHelp": "Usado para a IA combinar; descreva a função desta Skill e quando ela deve ser aplicada.", "allowedTools": "Ferramentas permitidas", "allowedToolsHelp": "Essas ferramentas podem ser usadas sem confirmação do usuário.", "userInvocable": "Mostrar no menu de barra (/)", "userInvocableHelp": "O usuário pode acionar manualmente via /nome-da-skill", "instructions": "Conteúdo das instruções", "instructionsHelp": "Instruções detalhadas para a IA (suporta Markdown).", "instructionsPlaceholder": "Digite instruções detalhadas para a IA...", "content": "Conteúdo das instruções", "deleteSkillTitle": "Excluir Skill", "deleteSkillDesc": "Tem certeza de que deseja excluir esta Skill? Esta ação não pode ser desfeita.", "skillDeleted": "Skill excluída com sucesso" }, "readAloud": { "title": "Leitura em voz alta", "desc": "Aqui você pode configurar opções de leitura em voz alta para reproduzir o conteúdo do chat em áudio.", "noModel": "Não usar modelo", "alert": { "title": "Você está usando a leitura do sistema", "description": "Nenhum modelo de áudio foi configurado. Usando a leitura do próprio sistema." }, "options": { "audioModel": { "title": "Modelo de áudio", "desc": "Escolha o modelo de IA para texto-para-fala (TTS). Suporta diferentes vozes e parâmetros." }, "speed": { "title": "Velocidade", "desc": "Ajuste a velocidade da voz (de 0,25× a 4×). O padrão é 1×." } } } }, "record": { "trash": { "title": "Esvaziar Lixeira", "confirm": "Tem certeza de que deseja esvaziar a lixeira?", "records": "{count} registros podem ser restaurados", "empty": "Esvaziar", "close": "Fechar Lixeira" }, "queue": { "ocr": "Reconhecimento OCR", "ai": "Reconhecimento de conteúdo por IA", "upload": "Upload para host de imagem", "jsdelivr": "Notificar cache jsdelivr", "recording": "Gravando...", "recorded": "Gravado", "record": "Gravar", "detected": "Detectado", "save": "Salvar" }, "mark": { "empty": "Nenhum registro ainda", "loading": "Carregando...", "createdAt": "Criado em", "type": { "scan": "Digitalização", "image": "Imagem", "screenshot": "Captura de Tela", "text": "Texto", "recording": "Gravação", "file": "Arquivo", "link": "Vínculo", "todo": "Todo", "pdf": "PDF", "upload": "Upload de Registro", "download": "Download de Registro", "uploadTo": "Sincronizar do local para {provider}", "downloadFrom": "Sincronizar de {provider} para local" }, "uploadSuccess": "Upload de registro bem-sucedido", "downloadSuccess": "Download de registro bem-sucedido", "desc": "Descrição", "content": "Conteúdo", "progress": { "cacheImage": "Armazenando imagem em cache", "ocr": "Reconhecimento OCR", "aiAnalysis": "Análise de conteúdo por IA", "uploadImage": "Enviando para host de imagem", "jsdelivrCache": "Notificando cache jsdelivr", "cacheFile": "Armazenando arquivo em cache", "cacheScreenshot": "Armazenando captura de tela em cache", "textAnalysis": "Análise de texto", "save": "Salvando", "saveImage": "Salvando imagem", "newToken": "Criar token de acesso", "newTokenDesc": "O novo token deve ser configurado com permissão de 'repo', a configuração criará automaticamente um repositório de arquivos (privado) e um repositório de imagens." }, "text": { "title": "Gravar Texto", "description": "Grave um pedaço de texto, que será inserido na posição apropriada ao organizar notas.", "characterCount": "{count} caracteres", "save": "Salvar", "autoReadClipboard": "Ler texto da área de transferência automaticamente" }, "link": { "title": "Gravar Link", "description": "Insira um link de página da web, e o sistema rastreará automaticamente o conteúdo da página e o salvará", "save": "Salvar", "autoReadClipboard": "Ler link da área de transferência automaticamente" }, "todo": { "title": "Registro Todo", "description": "Crie itens todo para gerenciar suas tarefas", "titlePlaceholder": "Digite o título do todo...", "descriptionPlaceholder": "Digite descrição detalhada (opcional)", "priority": "Prioridade", "priorityLow": "Baixa", "priorityMedium": "Média", "priorityHigh": "Alta", "dateRange": "Intervalo de Datas", "dateRangePlaceholder": "Selecione o intervalo de datas", "dueDate": "Data de Vencimento", "dueDatePlaceholder": "Selecione a data", "save": "Criar Todo", "saveEdit": "Salvar", "edit": "Editar Todo", "editDescription": "Modificar os detalhes do item todo", "cancel": "Cancelar", "selectTag": "Selecionar Tag", "completed": "Concluído", "uncompleted": "Não Concluído" }, "clipboard": { "detectedImage": "Imagem da área de transferência detectada", "detectedText": "Texto da área de transferência detectado" }, "tag": { "searchPlaceholder": "Crie ou pesquise tags...", "noResults": "Nenhuma tag correspondente encontrada", "quickAdd": "Criação Rápida", "pinned": "Fixadas", "others": "Outras", "rename": "Renomear", "delete": "Excluir", "pin": "Fixar", "unpin": "Desafixar", "newTag": "Nova Tag", "newTagPlaceholder": "Insira o nome da tag...", "add": "Adicionar" }, "mark": { "empty": "Nenhum registro", "emptyHint": "Use a barra de ferramentas no topo para criar seu primeiro registro!", "type": { "text": "Texto" }, "chat": { "modeSelect": { "chat": "Chat", "agent": "Agente" }, "agent": { "running": "Agente em Execução", "thinking": "Pensando", "acting": "Agindo", "observation": "Observação", "toolCalls": "Chamadas de Ferramenta", "thought": "Pensamento", "action": "Ação", "confirmation": { "title": "Confirmar Ação", "description": "O agente deseja executar a seguinte ação. Por favor, confirme para continuar.", "tool": "Ferramenta", "parameters": "Parâmetros", "cancel": "Cancelar", "confirm": "Confirmar", "confirmed": "Confirmado", "cancelled": "Cancelado" } }, "placeholder": { "default": "Faça perguntas ou organize suas notas em um artigo...", "noApiKey": "Chave de API não configurada, recurso de chat com IA indisponível...", "on": "Sugestão da IA: ligado", "off": "Sugestão da IA: desligado" }, "header": { "configApiKey": "Configurar CHAVE DE API", "clearChat": "Limpar Chat", "configPrompt": "Configurar Prompt", "selectPrompt": "Selecionar Prompt" }, "clipboard": { "image": { "detected": "Imagem detectada na área de transferência:", "recording": "Gravando...", "recorded": "Gravado", "record": "Gravar" }, "text": { "detected": "Texto detectado na área de transferência:", "recorded": "Gravado", "record": "Gravar" } }, "messageControl": { "words": "palavras", "summary": "Resumo" }, "mcp": { "maxIterationsReached": "Número máximo de iterações de chamada de ferramenta atingido", "toolCall": "Servidor MCP", "params": "Parâmetros", "result": "Resultado", "copy": "Copiar", "paramsCopied": "Parâmetros copiados", "resultCopied": "Resultado copiado", "calling": "Chamando", "success": "Concluído", "error": "Falha" }, "empty": { "title": "Iniciar Conversa com IA", "subtitle": "Use o modo Chat ou Agent para interagir com IA", "currentModel": "Modelo Atual", "currentPrompt": "Prompt Atual", "currentMode": "Modo de Conversa", "noModel": "Nenhum modelo definido", "noPrompt": "Nenhum prompt definido", "configureModel": "Configurar Modelo", "modeHint": "Toque no botão à esquerda do campo de entrada", "modeHintSuffix": "para alternar o modo de conversa", "recentConversations": "Conversas Recentes", "deleteConversation": "Excluir conversa", "conversationHistory": "Histórico", "viewMore": "Ver mais", "messages": "mensagens", "searchPlaceholder": "Pesquisar conversas...", "noMatchingConversations": "Nenhuma conversa correspondente encontrada", "noConversationHistory": "Sem histórico de conversa", "quickPrompts": { "title": "Início Rápido", "writeNote": "Ajude-me a escrever uma nota", "summarize": "Ajude-me a resumir este conteúdo", "brainstorm": "Ajude-me a brainstormar ideias", "explain": "Ajude-me a explicar este conceito" } }, "content": { "organize": "Organize seus registros em um artigo:" }, "note": { "writing": "Escrever", "convert": "Converter Artigo", "description": "A nota atual é gerada por IA e não pode ser editada. Converta a nota atual em um artigo (gere um arquivo local) para edição posterior na página de escrita.", "filename": "Nome do Arquivo", "selectFolder": "Selecionar pasta", "rootDirectory": "Diretório raiz", "deleteTag": "Excluir tag atual, registros e notas (pode ser restaurado da lixeira)", "warning": "Após a conversão, você será redirecionado para a página de escrita.", "convert_button": "Converter", "organizeAs": "Organize seus registros em um artigo:", "templateContent": "Conteúdo do template", "recordRange": "Intervalo de registros", "filterThinkingContent": "Remover conteúdo de 'pensamento' dos registros", "startOrganize": "Começar a organizar", "manageTemplate": "Gerenciar template", "cancel": "Cancelar" }, "mark": { "recorded": "Gravado", "record": "Gravar" }, "send": "Enviar" }, "text": { "title": "Gravar Texto", "description": "Grave um pedaço de texto, que será inserido na posição apropriada ao organizar notas.", "characterCount": "{count} caracteres", "save": "Salvar" }, "clipboard": { "detectedImage": "Imagem da área de transferência detectada", "detectedText": "Texto da área de transferência detectado" }, "tag": { "searchPlaceholder": "Crie ou pesquise tags...", "noResults": "Nenhuma tag correspondente encontrada", "quickAdd": "Criação Rápida", "pinned": "Fixadas", "others": "Outras", "rename": "Renomear", "delete": "Excluir", "pin": "Fixar", "unpin": "Desafixar" }, "progress": { "cacheImage": "Armazenando imagem em cache", "ocr": "Reconhecimento OCR", "aiAnalysis": "Análise de conteúdo por IA", "uploadImage": "Enviando para host de imagem", "jsdelivrCache": "Notificando cache jsdelivr", "cacheFile": "Armazenando arquivo em cache", "cacheScreenshot": "Armazenando captura de tela em cache", "textAnalysis": "Análise de texto", "save": "Salvando", "saveImage": "Salvando imagem" } }, "toolbar": { "search": "Pesquisar", "trash": "Lixeira", "restore": "Restaurar", "delete": "Excluir", "deleteConfirm": "Tem certeza de que deseja excluir?", "moveTag": "Mover para Tag", "convertTo": "Converter para {type}", "copyLink": "Copiar Link", "copied": "Copiado para a área de transferência!", "regenerateDesc": "Gerar Descrição Novamente", "viewFolder": "Ver na Pasta", "viewFile": "Ver Arquivo Original", "deleteForever": "Excluir Permanentemente", "sortByName": "Ordenar por Nome", "sortByCreated": "Ordenar por Data de Criação", "sortByModified": "Ordenar por Data de Modificação", "sortAsc": "Ordem Crescente", "sortDesc": "Ordem Decrescente", "sort": "Ordenar", "processingVectors": "Processando Dados Vetoriais", "calculateVectors": "Calcular Vetores de Documento", "multiSelect": "Seleção Múltipla", "exitMultiSelect": "Sair da Seleção Múltipla", "selectAll": "Selecionar Tudo", "deselectAll": "Desmarcar Tudo", "selectedCount": "{count} itens selecionados", "moveSelectedTags": "Mover {count} itens selecionados", "deleteSelected": "Excluir {count} itens selecionados", "deleteSelectedForever": "Excluir {count} itens selecionados permanentemente", "organizeNotes": "Organizar Notas", "organizeSuccess": "Notas organizadas com sucesso: {title}", "organizeError": "Falha ao organizar notas", "currentTag": "Tag Atual", "text": "Gravar Texto", "recording": "Gravação de Áudio", "scan": "Digitalizar Imagem", "image": "Carregar Imagem", "link": "Gravar Link", "file": "Carregar Arquivo", "todo": "Registro Todo", "closeTrash": "Fechar lixeira" }, "list": { "title": "Registros" }, "note": { "organizeAs": "Organizar como", "template": "Modelo", "setting": "Configurações", "confirm": "Confirmar", "cancel": "Cancelar", "removeThinking": "Remover processo de raciocínio", "stop": "Parar" }, "imageGallery": { "expand": "Expandir", "collapse": "Recolher" } }, "chat": { "empty": { "title": "Iniciar Conversa com IA", "subtitle": "Use o modo Chat ou Agent para interagir com IA", "currentModel": "Modelo Atual", "currentPrompt": "Prompt Atual", "noModel": "Nenhum modelo definido", "noPrompt": "Nenhum prompt definido", "modeHint": "Clique no botão", "modeHintSuffix": "à esquerda da caixa de entrada para alternar o modo de conversa", "currentMode": "Modo de conversa", "configureModel": "Configurar modelo", "features": [ { "chat": "Converse com o assistente de IA" }, { "linked": "Vinculado aos seus registros ou notas" }, { "clipboard": "Reconhece texto e imagens da área de transferência" }, { "organize": "Organiza seus registros em notas" } ], "recentConversations": "Conversas Recentes", "deleteConversation": "Excluir Conversa", "conversationHistory": "Histórico", "viewMore": "Ver Mais", "messages": "mensagens", "searchPlaceholder": "Pesquisar conversas...", "noMatchingConversations": "Nenhuma conversa correspondente encontrada", "noConversationHistory": "Ainda não há histórico de conversas", "quickPrompts": { "title": "快速开始", "writeNote": "帮我写一篇笔记", "summarize": "帮我总结这段内容", "brainstorm": "帮我头脑风暴一些想法", "explain": "帮我解释这个概念" } }, "newChat": "Novo Chat com Nova Tag", "removeChat": "Remover Chat com Tag Atual", "confirmNew": "Criar Nova Tag", "confirmNewDescription": "Tem certeza de que deseja criar uma nova tag para iniciar uma conversa?", "confirmRemove": "Excluir Tag", "confirmRemoveDescription": "Note que excluir esta tag também removerá todos os registros contidos nela. Confirme a ação para continuar.", "content": { "organize": "Organize seus registros em um artigo:" }, "note": { "organize": "Organizar", "writing": "Escrever", "convert": "Converter Artigo", "description": "A nota atual é gerada por IA e não pode ser editada. Converta a nota atual em um artigo (gere um arquivo local) para edição posterior na página de escrita.", "filename": "Nome do Arquivo", "selectFolder": "Selecionar pasta", "rootDirectory": "Diretório raiz", "deleteTag": "Excluir tag atual, registros e notas (pode ser restaurado da lixeira)", "warning": "Após a conversão, você será redirecionado para a página de escrita.", "convert_button": "Converter", "organizeAs": "Organize seus registros em um artigo:", "templateContent": "Conteúdo do template", "recordRange": "Intervalo de registros", "filterThinkingContent": "Remover conteúdo de 'pensamento' dos registros", "startOrganize": "Começar a organizar", "manageTemplate": "Gerenciar template", "cancel": "Cancelar", "stop": "Parar" }, "mark": { "recorded": "Gravado", "record": "Gravar" }, "input": { "organize": "Organizar", "chat": "Bate-papo", "placeholder": { "default": "Digite uma mensagem...", "noApiKey": "Nenhuma Chave de API configurada, não é possível usar o chat de IA...", "on": "Sugestões de IA ativadas", "off": "Sugestões de IA desativadas", "noPrimaryModel": "Nenhum modelo principal configurado, não é possível usar o chat de IA..." }, "translate": { "tooltip": "Traduzir", "translating": "Traduzindo...", "showOriginal": "Mostrar Original", "alreadyTranslated": "Traduzido para" }, "clipboardMonitor": { "enable": "Monitoramento da área de transferência (ligado)", "disable": "Monitoramento da área de transferência (desligado)" }, "send": "Enviar", "stop": "Parar", "terminate": "Terminar", "tagLink": { "on": "Vinculado à tag", "off": "Não vinculado à tag" }, "modelSelect": { "tooltip": "Selecionar modelo de IA", "placeholder": "Pesquisar modelos de IA", "noModel": "Nenhum modelo encontrado" }, "promptSelect": { "tooltip": "Selecionar prompt", "placeholder": "Pesquisar prompts" }, "clearChat": "Limpar Chat", "clearContext": { "tooltip": "Limpar contexto" }, "mcp": { "tooltip": "Servidor MCP" }, "chatLanguage": { "tooltip": "Selecionar idioma do chat", "placeholder": "Pesquisar idioma" }, "rag": { "notSupported": "Modelo vetorial não é suportado", "enabled": "Busca na Base de Conhecimento (Habilitada)", "disabled": "Busca na Base de Conhecimento (Desabilitada)" }, "modeSelect": { "tooltip": "Selecionar modo de entrada", "chat": "Modo Chat", "gen": "Modo Organizar", "translate": "Modo Traduzir" }, "chatModeSelect": { "chatDescription": "Conversa rápida, foco em análise", "agentDescription": "Assistente inteligente, pode executar ações" }, "attachImage": "Anexar imagens", "agent": { "running": "Agente em Execução", "thinking": "Pensando", "analyzingRequest": "O agente está analisando sua solicitação...", "acting": "Agindo", "observation": "Observação", "toolCalls": "Chamadas de Ferramenta", "autoFinal": { "createNote": "Nota \"{name}\" criada.", "createFile": "Arquivo \"{name}\" criado." }, "thought": "Pensamento", "action": "Ação", "confirmation": { "title": "Confirmar Ação", "description": "O agente deseja executar a seguinte ação. Por favor, confirme para continuar.", "tool": "Ferramenta", "parameters": "Parâmetros", "cancel": "Cancelar", "confirm": "Confirmar", "confirmed": "Confirmado", "cancelled": "Cancelado" } }, "imageSelector": { "title": "Selecionar Imagens", "local": "Arquivos Locais", "records": "Dos Registros", "selectFiles": "Selecionar Imagens Locais", "noRecords": "Nenhum registro de imagem disponível", "cancel": "Cancelar", "confirm": "Confirmar" }, "fileLink": { "tooltip": "Vincular Arquivo", "selectFile": "Selecionar Arquivo", "linkedFile": "Arquivo Vinculado", "searchPlaceholder": "Pesquisar arquivos...", "noFiles": "Nenhum arquivo encontrado", "loading": "Carregando..." }, "stopped": "A conversa foi encerrada", "newChat": "开始新对话" }, "header": { "configApiKey": "Configurar CHAVE DE API", "clearChat": "Limpar Chat", "selectPrompt": "Selecionar Prompt", "noModel": "Modelo de IA não selecionado", "configPrompt": "Configurar Prompt" }, "clipboard": { "image": { "detected": "Imagem detectada na área de transferência:", "recording": "Gravando...", "recorded": "Gravado", "record": "Gravar" }, "text": { "detected": "Texto detectado na área de transferência:", "recorded": "Gravado", "record": "Gravar" } }, "messageControl": { "words": "palavras", "summary": "Resumo", "readAloud": "Ler em Voz Alta", "playing": "Reproduzindo", "loading": "Carregando", "stop": "Parar Reprodução", "copy": "Copiar", "copied": "Copiado" }, "ragSources": { "label": "Encontrado {count} notas na base de conhecimento", "openFile": "Abrir arquivo" }, "preview": { "close": "Fechar", "copy": "Copiar", "copied": "Copiado!" }, "control": { "edit": "Editar", "save": "Salvar", "cancel": "Cancelar", "delete": "Excluir", "deleteConfirm": "Tem certeza de que deseja excluir esta mensagem?" }, "condensing": "正在压缩上下文...", "condensed": { "message": "已压缩 {count} 条历史消息" }, "quote": { "lineSingle": "引用自 {fileName} 第 {line} 行", "lineRange": "引用自 {fileName} 第 {startLine}-{endLine} 行", "noLine": "引用自 {fileName}" } }, "tag": { "add": "Adicionar Tag", "edit": "Editar Tag", "delete": "Excluir Tag", "deleteConfirm": "Tem certeza de que deseja excluir esta tag?", "placeholder": "Insira o nome da tag" } }, "search": { "placeholder": "Pesquisar notas e artigos...", "results": "{count} resultados da pesquisa", "noResults": "Nenhum resultado de pesquisa", "tryDifferentKeywords": "Tente usar palavras-chave diferentes", "item": { "record": "Registro", "article": "Artigo", "matches": "{count} correspondências", "scanType": "digitalização" }, "mode": { "fuzzy": "Aproximada", "exact": "Exata" } }, "image": { "root": "Repositório de Imagens", "noData": { "title": "Recurso de sincronização não habilitado", "desc": "Por favor, vá para a página de configurações do sistema para configurar a sincronização do Github.", "goToSettings": "Ir para Configurações", "howToUse": "Como usar o recurso de sincronização?" } }, "navigation": { "chat": "Conversa", "record": "Registro", "quickRecord": "Registro Rápido", "write": "Escrever", "search": "Pesquisar", "githubImageHosting": "Hospedagem de Imagens Github", "login": "Entrar", "loading": "Carregando", "view": "Visualizar", "logout": "Sair", "setting": "Configurações", "activity": "Atividade", "files": "Notas", "outline": "Sumário", "hideLeftSidebar": "Ocultar Barra Lateral Esquerda", "showLeftSidebar": "Mostrar Barra Lateral Esquerda", "hideRightSidebar": "Ocultar Barra Lateral Direita", "showRightSidebar": "Mostrar Barra Lateral Direita", "searchPlaceholder": "Pesquisar notas ou registros...", "showCenterPanel": "Mostrar editor", "hideCenterPanel": "Ocultar editor" }, "activity": { "title": "Calendário de Atividade", "description": "Veja seus registros, conversas e atividade de escrita por dia. Esta primeira versão é calculada a partir dos registros existentes, conversas do usuário e horários de modificação das notas.", "drawer": { "title": "Atividade", "description": "Veja rapidamente o status de hoje e a tendência recente da sua atividade.", "today": "Hoje" }, "loading": "Carregando dados de atividade...", "empty": "Ainda não há dados de atividade", "refresh": "Atualizar", "summary": { "totalCount": "Atividade Total", "activeDays": "Dias Ativos", "records": "Registros", "chats": "Conversas", "writing": "Escrita" }, "labels": { "record": "Registro", "writing": "Escrita", "chat": "Conversa" }, "heatmap": { "title": "Últimas 26 Semanas", "range": "{startDate} - {endDate}", "less": "Menos", "more": "Mais", "dayCount": "atividades", "emptyDay": "Sem atividade" }, "detail": { "title": "Detalhes do Dia", "empty": "Selecione um dia para ver seus detalhes de atividade." } }, "marks": { "types": { "screenshot": "Captura de Tela", "text": "Texto", "image": "Imagem" } }, "tags": { "inspiration": "Inspiração" }, "sync": { "status": "Status do Repositório de Sincronização", "imageRepo": "Repositório de Imagens", "articleRepo": "Repositório de Artigos" }, "ai": { "thinking": "Pensando", "error": { "title": "Erro de IA", "noAddress": "Por favor, defina o endereço da IA primeiro" } }, "article": { "sync": { "syncingRemote": "Buscando arquivo remoto...", "syncComplete": "Sincronização Concluída", "pullingRemote": "Obtendo conteúdo mais recente do servidor remoto..." }, "syncConfirm": { "title": "Atualização de Arquivo Remoto Detectada", "description": "Arquivo {fileName} tem atualizações remotas", "commitInfo": "Informações do Último Commit", "commitMessage": "Mensagem do Commit", "author": "Autor", "changes": "Alterações", "confirmMessage": "Tem certeza de que deseja buscar a versão remota e substituir o arquivo local? Esta ação não pode ser desfeita.", "cancel": "Cancelar", "confirmPull": "Confirmar Busca" }, "emptyState": { "title": "Começar a Criar", "subtitle": "Selecione um arquivo para começar a editar ou crie uma nova nota", "tip": "💡 Dica: Você também pode selecionar arquivos no gerenciador de arquivos à esquerda", "actions": { "newNote": { "title": "Criar Nota", "desc": "Criar uma nova nota Markdown" }, "newRecord": { "title": "Criar Registro", "desc": "Abrir função de registro de texto" }, "globalSearch": { "title": "Pesquisa Global", "desc": "Encontre rapidamente o conteúdo de suas notas" }, "openWorkspace": { "title": "Abrir Workspace", "desc": "Selecionar ou alternar diretório de workspace" } }, "onboarding": { "title": "Onboarding", "subtitle": "Siga estas três tarefas para conhecer o fluxo principal do NoteGen.", "dismiss": "Pular introducao", "reopen": "Mostrar onboarding novamente", "start": "Começar", "viewHint": "Ver dica", "continue": "Continuar", "completed": "Concluído", "allDone": "Todas as tarefas iniciais foram concluídas. Você já experimentou o fluxo principal do NoteGen.", "stepLabel": "Tarefa ({current}/{total})", "stepCompletedLabel": "Tarefa concluída ({current}/{total})", "afterOrganizeDialog": { "title": "Tarefa concluída (2/3)", "description": "Seu registro virou uma nota. Quer continuar e usar o AI Agent para transformar essa nota em uma versão bilíngue?", "confirm": "Continuar", "cancel": "Agora não" }, "agentPrompt": { "label": "Prompt de exemplo", "use": "Usar este prompt", "intro": "Please directly revise the note I just organized into a bilingual Chinese-English version.", "requirement1": "", "requirement2": "", "requirement3": "", "requirement4": "", "outro": "" }, "steps": { "createRecord": { "title": "Criar o primeiro registro", "desc": "Salve um registro de exemplo e veja onde fica a captura rápida." }, "organizeNote": { "title": "Organizar em nota", "desc": "Transforme esse registro em uma nota estruturada." }, "aiPolish": { "title": "Usar Agent para tradução bilíngue", "desc": "Use o AI Agent para transformar a nota recém-organizada em uma versão bilíngue." } }, "completedStates": { "create-record": { "title": "Seu primeiro registro foi criado", "desc": "Agora você já sabe onde fica a captura rápida." }, "organize-note": { "title": "Seu registro virou uma nota", "desc": "Agora vale experimentar a IA editando essa nota." }, "ai-polish": { "title": "Você usou o Agent na nota", "desc": "Você concluiu o fluxo de captura, organização e processamento com Agent no NoteGen." } }, "spotlight": { "create-record": { "title": "Aqui fica a captura rápida", "desc": "Clique aqui para abrir o registro em texto. Vamos preencher um exemplo automaticamente para você salvar logo." }, "organize-note": { "title": "Este botão organiza registros em uma nota", "desc": "Use-o para transformar o registro salvo em uma nota Markdown completa." }, "ai-polish": { "title": "Use o Agent aqui na nota que acabou de criar", "desc": "Insira o prompt de exemplo no chat e envie. O Agent vai gerar uma versão bilíngue com base na nota atual." } } } }, "unsupportedFile": { "title": "Não É Possível Visualizar Este Arquivo", "fileName": "Nome do Arquivo", "filePath": "Caminho do Arquivo", "fileSize": "Tamanho do Arquivo", "modifiedTime": "Data de Modificação", "createdTime": "Data de Criação", "pathCopied": "Caminho copiado", "openExternal": "Abrir com App Externo", "openDirectory": "Abrir Diretório do Arquivo" }, "file": { "toolbar": { "accessRepo": "Acessar Repositório", "loadingSync": "Carregando informações de sincronização", "configSync": "Configurar Sincronização", "newArticle": "Novo Artigo", "newFolder": "Nova Pasta", "refresh": "Atualizar", "toggleFolders": "Alternar Pastas", "expandAll": "Expandir Tudo", "collapseAll": "Recolher Tudo", "sortByName": "Ordenar por Nome", "sortByCreated": "Ordenar por Data de Criação", "sortByModified": "Ordenar por Data de Modificação", "sortAsc": "Ordem Crescente", "sortDesc": "Ordem Decrescente", "sort": "Ordenar", "hideCloudFiles": "Ocultar Arquivos da Nuvem", "showCloudFiles": "Mostrar Arquivos da Nuvem", "processingVectors": "Processando Dados Vetoriais", "calculateVectors": "Cálculo da Base de Conhecimento (Completo)", "importMarkdown": "Importar", "importing": "Importando...", "importSuccess": "Importação Bem-sucedida", "importSuccessDesc": "Importados {count} arquivos com sucesso", "importError": "Falha na Importação" }, "sync": { "syncingRemote": "Buscando arquivo remoto...", "syncComplete": "Sincronização Concluída", "pullingRemote": "Buscando conteúdo mais recente do servidor remoto...", "pullComplete": "Pull Concluído" }, "context": { "viewDirectory": "Ver Diretório", "cut": "Recortar", "copy": "Copiar", "paste": "Colar", "rename": "Renomear", "deleteSyncFile": "Excluir Arquivo Sincronizado", "deleteLocalFile": "Excluir Arquivo Local", "delete": "Excluir", "confirmDelete": "Tem certeza de que deseja excluir a pasta \"{name}\"? Isso excluirá a pasta e todo o seu conteúdo.", "deleteSuccess": "Excluído com sucesso", "deleteFailed": "Falha ao excluir", "newFile": "Novo Arquivo", "newFolder": "Nova Pasta", "syncFolder": "Sincronizar Pasta", "syncFolderDesc": "Sincronizar todos os arquivos Markdown na pasta atual", "syncFolderSuccess": "Sucesso ao sincronizar pasta", "syncFolderError": "Erro ao sincronizar pasta", "syncFolderProgress": "Sincronizando pasta...", "deleteSyncFileSuccess": "Sucesso ao Excluir Arquivo Sincronizado", "deleteSyncFileError": "Erro ao Excluir Arquivo Sincronizado", "knowledgeBase": "Base de Conhecimento", "calculateVectors": "Calcular Vetores", "updateVectors": "Atualizar Vetores", "deleteVectors": "Excluir Vetores", "includeInKB": "Incluir na Base de Conhecimento", "includeInKBFile": "Incluir na Base de Conhecimento", "autoVectorCalc": "Cálculo Automático de Vetores", "vectorCalculated": "Vetor Atualizado", "vectorCalcCompleted": "Cálculo de Vetor Concluído", "vectorCalcFailed": "Falha no Cálculo de Vetor", "vectorDeleted": "Vetor Excluído", "vectorDeleteFailed": "Falha ao Excluir Vetor", "batchCalcSuccess": "Vetores calculados com sucesso para {count} arquivos", "batchCalcPartial": "Cálculo concluído: {success} succeeded, {failed} failed", "batchCalcFailed": "Falha no cálculo em lote de vetores", "batchDeleteSuccess": "Vetores excluídos com sucesso para {count} arquivos", "batchDeletePartial": "Exclusão concluída: {success} succeeded, {failed} failed", "batchDeleteFailed": "Falha na exclusão em lote de vetores", "noMarkdownFiles": "Nenhum arquivo Markdown na pasta", "includedInKB": "Incluído na Base de Conhecimento", "excludedFromKB": "Excluído da Base de Conhecimento", "autoCalcEnabled": "Cálculo automático de vetores habilitado", "autoCalcDisabled": "Cálculo automático de vetores desabilitado", "settingFailed": "Falha na configuração", "confirmDeleteVectors": "Tem certeza de que deseja excluir vetores de {count} arquivos?" }, "folderView": { "vectorDbNotEnabled": "Banco de dados vetorial não está habilitado", "calculateVectors": "Calcular Vetores", "indexed": "Indexado", "vectorCount": "Contagem de Vetores", "databaseSize": "Tamanho do Banco de Dados", "lastCalculated": "Último Cálculo", "never": "Nunca", "calculating": "Calculando...", "failed": "Falhou", "recalculateVectors": "Recalcular Vetores", "skills": "Skills", "skillNotFound": "Skill Não Encontrado", "skillNotFoundDesc": "Não foi possível encontrar Skill com ID {id}", "loadingSkills": "Carregando Skills...", "loadingSkill": "Carregando Skill...", "globalSkills": "Skills Globais", "workspaceSkills": "Skills do Workspace", "instructions": "Instruções", "examples": "Exemplos", "scripts": "Scripts", "references": "Referências", "assets": "Ativos" }, "error": { "fileExists": "O nome do arquivo já existe" }, "clipboard": { "copied": "Copiado para a área de transferência", "cut": "Recortado para a área de transferência", "pasted": "Colado com sucesso", "pasteFailed": "Falha na operação de colar", "empty": "A área de transferência está vazia", "confirmOverwrite": "O arquivo já existe, deseja sobrescrevê-lo?", "mark": { "title": "Registros", "tooltip": "Usar Registros", "description": "Converta registros em conteúdo para inserir no artigo.", "noRecords": "Nenhum registro", "ocrNoContent": "OCR não reconheceu nenhum conteúdo" }, "question": { "tooltip": "Perguntas e Respostas", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Texto de referência: \n{content}\nCom base na pergunta: \n{question}\n, forneça diretamente o conteúdo da resposta." }, "continue": { "tooltip": "Continuar", "promptTemplate": "Com base no texto anterior: \n{content}\n continue escrevendo e retorne um conteúdo que não exceda 100 palavras.\nVocê pode referenciar o seguinte texto: \n{endContent}\n, mas evite duplicar seu conteúdo." }, "polish": { "tooltip": "Polir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Polir este texto: \n{content}\n, mantenha o idioma inalterado, corrija erros de digitação e gramaticais, retorne diretamente o resultado polido." }, "eraser": { "tooltip": "Simplificar", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Simplificar este texto: \n{content}\n, este texto está muito verboso, reduza a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado otimizado." }, "expansion": { "tooltip": "Expandir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Expandir este texto: \n{content}\n, este texto está muito curto, aumente a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado expandido." }, "translation": { "tooltip": "Traduzir", "description": "Traduzir o texto selecionado", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Traduzir este texto: \n{content}\n, para {language}, retorne diretamente o resultado traduzido." }, "notSupported": "Esta ação não é suportada" }, "deleteConfirm": "Confirmar exclusão deste arquivo?" }, "editor": { "copySuccess": "Cópia Bem-sucedida", "copySuccessDescription": "Copiado para a área de transferência", "search": { "placeholder": "Localizar no documento", "replacePlaceholder": "Substituir por", "caseSensitive": "Diferenciar maiúsculas e minúsculas", "replace": "Substituir", "replaceAll": "Substituir tudo", "findPrev": "Anterior", "findNext": "Próximo" }, "floatbar": { "quote": { "tooltip": "Citar" }, "readAloud": { "start": "Ler em Voz Alta", "stop": "Parar Leitura", "loading": "Carregando..." } }, "toolbar": { "organize": { "tooltip": "Organizar Notas" }, "mark": { "title": "Registros", "tooltip": "Registros", "description": "Converta registros em conteúdo para inserir no artigo.", "noRecords": "Nenhum registro", "ocrNoContent": "OCR não reconheceu nenhum conteúdo" }, "question": { "tooltip": "Perguntas e Respostas", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Texto de referência: \n{content}\nCom base na pergunta: \n{question}\n, forneça diretamente o conteúdo da resposta." }, "continue": { "tooltip": "Continuar", "promptTemplate": "Com base no texto anterior: \n{content}\n continue escrevendo e retorne um conteúdo que não exceda 100 palavras.\nVocê pode referenciar o seguinte texto: \n{endContent}\n, mas evite duplicar seu conteúdo." }, "polish": { "tooltip": "Polir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Polir este texto: \n{content}\n, mantenha o idioma inalterado, corrija erros de digitação e gramaticais, retorne diretamente o resultado polido." }, "eraser": { "tooltip": "Simplificar", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Simplificar este texto: \n{content}\n, este texto está muito verboso, reduza a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado otimizado." }, "expansion": { "tooltip": "Expandir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Expandir este texto: \n{content}\n, este texto está muito curto, aumente a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado expandido." }, "translation": { "tooltip": "Traduzir", "description": "Traduzir o texto selecionado", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Traduzir este texto: \n{content}\n, para {language}, retorne diretamente o resultado traduzido.", "fail": "Falha na tradução", "failNoSelection": "Por favor, selecione o texto para traduzir", "translating": "Traduzindo", "translatingTo": "Traduzindo para {language}...", "success": "Tradução concluída", "successTo": "Traduzido para {language}", "customLanguage": "Idioma personalizado...", "customLanguagePlaceholder": "Digite o idioma de destino, ex.: Inglês, Japonês, etc.", "customLanguageEmpty": "Por favor, digite o idioma de destino", "customLanguageExample": "ex.: Inglês, Japonês, Francês, etc." } }, "upload": { "error": "Falha no upload", "needToken": "O upload de imagens precisa configurar o accessToken", "uploading": "Enviando imagem" }, "saveDialog": { "title": "Salvar arquivo", "emptyContent": "Conteúdo vazio", "emptyContentDesc": "Digite algum conteúdo antes de salvar.", "success": "Salvo com sucesso", "successDesc": "O arquivo foi salvo.", "error": "Falha ao salvar", "errorDesc": "Não foi possível salvar o arquivo. Tente novamente." } }, "footer": { "wordCount": "Contagem de Palavras", "pull": { "pull": "Pull", "checking": "Verificando atualizações...", "noUpdate": "Sem atualizações remotas", "clickToPull": "Clique para puxar atualizações remotas", "pullSuccess": "Pull Bem-sucedido", "pullFailed": "Pull Falhou", "ignored": "Ignorado", "ignoreUpdate": "Ignorar Esta Atualização" }, "sync": { "sync": "Sincronizar", "synced": "Sincronizado", "syncing": "Sincronizando", "syncFailed": "Falha na Sincronização", "checkNetworkOrToken": "Por favor, verifique a conexão de rede ou o token", "quickSync": "Sincronização Rápida", "push": "Enviar", "pushed": "Enviado" }, "history": { "loadingHistory": "Carregando histórico", "historyRecords": "Registros do Histórico", "noHistory": "Nenhum Histórico", "loading": "Carregando", "recordsCount": "registros", "filterQuickSync": "Filtrar Sincronizações Rápidas", "committedAt": "enviado em", "pull": "Pull", "quickSync": "Sincronização Rápida" }, "vectorCalc": { "tooltip": { "default": "Status do Índice Vetorial", "none": "Clique para iniciar o cálculo vetorial", "indexed": "Indexado", "pending": "Atualização pendente, clique para calcular agora", "calculating": "Calculando..." }, "status": { "calculating": "Calculando" } } } }, "mobile": { "chat": { "drawer": { "settings": { "title": "Configurações de Chat" }, "tools": { "title": "Ferramentas", "clearContext": "Limpar Contexto", "clearContextDesc": "Limpar contexto da conversa, manter histórico", "clearChat": "Limpar Chat", "clearChatDesc": "Excluir todos os registros de chat", "clear": "Limpar", "newChat": "开始新对话", "start": "开始" }, "attachments": { "title": "Anexos", "gallery": "Galeria", "camera": "Câmera", "file": "Arquivo", "linkNote": "Vincular Nota" } } } }, "mcp": { "selectServers": "Servidores MCP", "searchServers": "Buscar servidores...", "noServers": "Serviço MCP não habilitado", "noServersFound": "Nenhum servidor correspondente encontrado", "addServer": "Adicionar servidor...", "goToSettings": "Ir para Configurações", "close": "Fechar", "navigate": "Selecionar", "confirm": "Confirmar", "tools": "ferramentas", "connecting": "Conectando", "disconnected": "Desconectado" }, "recording": { "title": "Gravação de Voz", "description": "Clique no botão do microfone para iniciar a gravação, o sistema reconhecerá automaticamente e converterá para texto", "recording": "Gravando", "paused": "Pausado", "ready": "Pronto", "processing": "Processando...", "cancel": "Cancelar", "error": "Erro", "success": "Sucesso", "noModelConfigured": "Modelo de reconhecimento de fala não configurado, configure nas configurações primeiro", "speechUnavailable": "O modo atual de reconhecimento de fala não está disponível. Verifique o suporte local ou a configuração do modelo.", "fallbackToModel": "O reconhecimento local não está disponível, então o app mudou automaticamente para a transcrição por modelo.", "startError": "Não é possível iniciar a gravação", "noAudioData": "Nenhum dado de áudio gravado", "transcriptionSuccess": "Reconhecimento de fala concluído", "transcriptionEmpty": "Resultado do reconhecimento está vazio", "transcriptionError": "Falha no reconhecimento de fala", "configureModel": "Configurar modelo", "retryTranscription": "Transcrever novamente", "retrying": "Transcrevendo novamente...", "retrySuccess": "Transcrição atualizada", "retryError": "Falha ao transcrever novamente", "noContentDetected": "Nenhum conteúdo detectado", "doubleClickToSelectFile": "Clique duas vezes para selecionar o arquivo de áudio", "mode": { "builtin": "Reconhecimento do Navegador", "builtinDesc": "Gratuito, reconhecimento em tempo real", "model": "Reconhecimento por Modelo de IA", "modelDesc": "Requer modelo STT, mais preciso" } }, "editor": { "placeholder": "Digite / para abrir o menu, ou comece a escrever...", "outline": { "title": "Esboço", "open": "Abrir Esboço", "close": "Fechar Esboço" }, "copySuccess": "Cópia Bem-sucedida", "copySuccessDescription": "Copiado para a área de transferência", "search": { "placeholder": "Localizar no documento", "replacePlaceholder": "Substituir por", "caseSensitive": "Diferenciar maiúsculas e minúsculas", "replace": "Substituir", "replaceAll": "Substituir tudo", "findPrev": "Anterior", "findNext": "Próximo" }, "floatbar": { "readAloud": { "start": "Ler em Voz Alta", "stop": "Parar Leitura", "loading": "Carregando..." } }, "toolbar": { "mark": { "title": "Registros", "tooltip": "Registros", "description": "Converta registros em conteúdo para inserir no artigo.", "noRecords": "Nenhum registro", "ocrNoContent": "OCR não reconheceu nenhum conteúdo" }, "question": { "tooltip": "Perguntas e Respostas", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Texto de referência: \n{content}\nCom base na pergunta: \n{question}\n, forneça diretamente o conteúdo da resposta." }, "continue": { "tooltip": "Continuar", "promptTemplate": "Com base no texto anterior: \n{content}\n continue escrevendo e retorne um conteúdo que não exceda 100 palavras.\nVocê pode referenciar o seguinte texto: \n{endContent}\n, mas evite duplicar seu conteúdo." }, "polish": { "tooltip": "Polir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Polir este texto: \n{content}\n, mantenha o idioma inalterado, corrija erros de digitação e gramaticais, retorne diretamente o resultado polido." }, "eraser": { "tooltip": "Simplificar", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Simplificar este texto: \n{content}\n, este texto está muito verboso, reduza a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado otimizado." }, "expansion": { "tooltip": "Expandir", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Expandir este texto: \n{content}\n, este texto está muito curto, aumente a contagem de palavras pela metade, mantenha o idioma inalterado, retorne diretamente o resultado expandido." }, "translation": { "tooltip": "Traduzir", "description": "Traduzir o texto selecionado", "selectContent": "Por favor, selecione o conteúdo primeiro", "promptTemplate": "Traduzir este texto: \n{content}\n, para {language}, retorne diretamente o resultado traduzido.", "fail": "Falha na tradução", "failNoSelection": "Por favor, selecione o texto para traduzir", "translating": "Traduzindo...", "translatingTo": "Traduzindo para {language}...", "success": "Tradução concluída", "successTo": "Traduzido para {language}", "customLanguageEmpty": "Por favor, digite o idioma de destino", "customLanguageExample": "ex.: Inglês, Japonês, Francês, etc." }, "quoteDisplay": { "fromFile": "Citado de {fileName}", "line": "Citado de {fileName} linha {line}", "lines": "Citado de {fileName} linhas {start}-{end}" } }, "upload": { "error": "Falha no upload", "needToken": "O upload de imagens precisa configurar o accessToken", "uploading": "Enviando imagem" } }, "footer": { "wordCount": "Palavras", "sync": { "push": "Push", "pushed": "Enviado", "syncing": "Enviando", "syncFailed": "Falha no Push", "checkNetworkOrToken": "Por favor, verifique a conexão de rede ou o token", "quickSync": "Sincronização Rápida" }, "history": { "loadingHistory": "Carregando histórico", "historyRecords": "Registros do Histórico", "noHistory": "Nenhum Histórico", "loading": "Carregando", "recordsCount": "registros", "filterQuickSync": "Filtrar Sincronizações Rápidas", "committedAt": "enviado em", "pull": "Pull", "quickSync": "Sincronização Rápida" }, "vectorCalc": { "tooltip": "Cálculo Vetorial: Cálculo automático 30s após a edição, ou clique para calcular agora", "calculating": "Calculando", "pending": "Pendente {progress}%", "synced": "Sincronizado" } }, "quickRecord": { "description": "Clique para selecionar uma ferramenta de registro e criar registros rapidamente" }, "editor": { "bubbleMenu": { "ai": "IA", "polish": "Polir", "concise": "Conciso", "expand": "Expandir", "translate": "Traduzir", "translateSubtitle": "Traduzir para", "quoteToChat": "Citar no Chat", "link": "Link", "linkPlaceholder": "Digite a URL do link", "confirm": "Confirmar", "cancel": "Cancelar", "bold": "Negrito", "italic": "Itálico", "strike": "Tachado", "underline": "Sublinhado", "inlineCode": "Código na linha", "highlight": "Destacar", "blockquote": "Citação", "bulletList": "Lista com marcadores", "orderedList": "Lista numerada", "taskList": "Lista de tarefas", "codeBlock": "Bloco de código", "languages": { "English": "Inglês", "Japanese": "Japonês", "Korean": "Coreano", "French": "Francês", "German": "Alemão", "Spanish": "Espanhol", "Portuguese": "Português", "Russian": "Russo", "Arabic": "Árabe" }, "customLanguagePlaceholder": "Idioma personalizado..." }, "aiSuggestion": { "accept": "Aceitar", "reject": "Rejeitar", "generating": "Gerando...", "abort": "Abortar" }, "image": { "insert": "Inserir imagem", "uploading": "Enviando...", "uploadSuccess": "Imagem enviada para o servidor de imagens", "saveSuccess": "Imagem salva localmente", "uploadFailed": "Falha ao inserir imagem", "sizeSmall": "Pequeno (25%)", "sizeMedium": "Médio (50%)", "sizeLarge": "Grande (75%)", "sizeOriginal": "Tamanho Original", "editAlt": "Editar texto alternativo", "editSrc": "Editar URL", "altPlaceholder": "Digite o texto alternativo...", "srcPlaceholder": "Digite a URL da imagem...", "delete": "Excluir imagem" }, "mermaid": { "rendering": "Renderizando...", "renderError": "Erro de renderização", "clickToEdit": "Clique para editar código", "clickToAdd": "Clique para adicionar diagrama", "placeholder": "Digite o código do diagrama Mermaid...", "preview": "Visualizar", "done": "Concluído", "diagramTypes": { "flowchart": "Fluxograma", "sequence": "Sequência", "classDiagram": "Diagrama de Classes", "stateDiagram": "Diagrama de Estados", "er": "Diagrama ER", "gantt": "Gantt", "pie": "Gráfico de Pizza", "journey": "Jornada" }, "templates": { "flowchart": "graph TD\n A[Início] --> B[Processo]\n B --> C[Fim]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Olá\n Bob-->>Alice: Resposta", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title Plano de Projeto\n dateFormat YYYY-MM-DD\n section Fase 1\n Tarefa1 :a1, 2024-01-01, 30d\n section Fase 2\n Tarefa2 :after a1, 20d", "pie": "pie title Alocação de Recursos\n \"CPU\" : 45\n \"Memória\" : 30\n \"Armazenamento\" : 25", "journey": "journey\n title Meu Trabalho Diário\n section Manhã\n Deslocamento : 7:00, 5\n Trabalho : 9:00, 8" } }, "slashCommand": { "groups": { "ai": "IA", "heading": "Título", "list": "Lista", "block": "Bloco", "align": "Alinhamento", "embed": "Incorporar", "math": "Matemática", "chart": "Gráfico" }, "items": { "continue": "Continuar", "continueDesc": "IA continua escrevendo o conteúdo", "heading1": "Título 1", "heading1Desc": "Título grande", "heading2": "Título 2", "heading2Desc": "Título médio", "heading3": "Título 3", "heading3Desc": "Título pequeno", "bulletList": "Lista com Marcadores", "bulletListDesc": "Criar uma lista com marcadores simples", "orderedList": "Lista Ordenada", "orderedListDesc": "Criar uma lista numerada", "taskList": "Lista de Tarefas", "taskListDesc": "Criar uma lista de tarefas com caixas de seleção", "image": "Imagem", "imageDesc": "Inserir imagem local ou hospedada", "table": "Tabela", "tableDesc": "Inserir uma tabela", "blockquote": "Citação", "blockquoteDesc": "Capturar conteúdo citado", "codeBlock": "Bloco de Código", "codeBlockDesc": "Capturar trechos de código", "divider": "Divisor", "dividerDesc": "Criar um divisor horizontal", "inlineMath": "Math Inline", "inlineMathDesc": "Inserir fórmula LaTeX inline", "blockMath": "Math em Bloco", "blockMathDesc": "Inserir fórmula LaTeX em bloco", "flowchart": "Fluxograma", "flowchartDesc": "Inserir um fluxograma", "sequence": "Diagrama de Sequência", "sequenceDesc": "Inserir um diagrama de sequência", "gantt": "Gráfico de Gantt", "ganttDesc": "Inserir um gráfico de Gantt", "classDiagram": "Diagrama de Classes", "classDiagramDesc": "Inserir um diagrama de classes", "stateDiagram": "Diagrama de Estados", "stateDiagramDesc": "Inserir um diagrama de estados", "pie": "Gráfico de Pizza", "pieDesc": "Inserir um gráfico de pizza", "erDiagram": "Diagrama ER", "erDiagramDesc": "Inserir um diagrama de entidade-relacionamento", "journey": "Mapa de Jornada", "journeyDesc": "Inserir um mapa de jornada do usuário" }, "imageUpload": { "success": "Upload bem-sucedido", "saveSuccess": "Salvo com sucesso", "savePath": "Salvo em: {path}", "failed": "Falha ao inserir imagem" } } }, "tabContext": { "close": "Fechar", "closeOthers": "Fechar Outros", "closeAll": "Fechar Tudo", "closeLeft": "Fechar à Esquerda", "closeRight": "Fechar à Direita" } } ================================================ FILE: messages/zh-TW.json ================================================ { "app": { "title": "筆記生成器", "description": "你的 AI 驅動的筆記助手" }, "common": { "save": "保存", "cancel": "取消", "delete": "刪除", "confirm": "確認", "edit": "編輯", "create": "創建", "theme": "主題", "light": "亮色", "dark": "暗色", "system": "跟隨系統", "pin": "置頂", "unpin": "取消置頂", "settings": "設置", "back": "返回", "sync": "同步", "language": "語言", "success": "成功", "error": "失敗", "defaultFileName": "未命名文件", "restartToApply": ",請重啟應用使配置生效", "close": "關閉", "open": "打開", "add": "添加", "remove": "移除", "search": "搜索", "filter": "篩選", "sort": "排序", "export": "導出", "import": "導入", "refresh": "刷新", "loading": "加載中...", "warning": "警告", "info": "信息", "unsaved": "未保存", "saving": "保存中...", "configureSync": "配置同步" }, "settings": { "defaultModels": { "title": "預設模型" }, "others": "高級", "general": { "title": "常規設置", "desc": "在這裡,你可以配置應用的基本設置,包括界面主題、語言等選項。", "interface": { "title": "界面設置", "theme": { "title": "主題", "desc": "選擇應用的外觀主題", "options": { "light": "亮色", "dark": "暗色", "system": "跟隨系統" } }, "language": { "title": "語言", "desc": "選擇應用的顯示語言" }, "scale": { "title": "界面縮放", "desc": "調整應用界面的整體縮放比例", "placeholder": "選擇縮放比例" }, "contentTextScale": { "title": "正文縮放", "desc": "調整編輯器和對話中 Markdown 內容的文字大小" }, "fileManagerTextSize": { "title": "文件管理器文字大小", "desc": "調整文件管理器中文件和文件夾列表的文字大小" }, "recordTextSize": { "title": "記錄文字大小", "desc": "調整記錄列表中記錄項的文字大小" }, "customCss": { "title": "自訂 CSS", "desc": "添加自訂 CSS 樣式來覆蓋應用的默認樣式", "button": "編輯 CSS", "dialogTitle": "自訂 CSS", "dialogDesc": "在下方輸入自訂 CSS 代碼,可以覆蓋應用的默認樣式。修改後點擊保存即可生效。", "placeholder": "在此輸入自訂 CSS 代碼。", "save": "保存", "cancel": "取消" }, "tray": { "enabled": { "title": "啟用托盤", "desc": "關閉窗口時選擇最小化到托盤或直接關閉軟件" } }, "customTheme": { "title": "自定义主题颜色", "desc": "自定义应用的主题颜色,包括背景色、前景色、边框色等", "button": "编辑颜色", "dialogTitle": "自定义主题颜色", "dialogDesc": "配置自定义主题颜色。颜色更改会实时保存并生效,同时覆盖亮色和暗色主题。", "close": "關閉", "reset": "重置全部", "tabs": { "custom": "自定义", "presets": "预设方案", "importExport": "导入导出" }, "export": { "title": "导出配色方案", "button": "生成导出代码", "placeholder": "点击生成按钮将当前配色导出为代码" }, "import": { "title": "导入配色方案", "button": "导入配色", "placeholder": "粘贴配色方案的 JSON 代码" }, "colors": { "background": "背景色", "foreground": "前景色", "card": "卡片背景色", "cardForeground": "卡片前景色", "primary": "主色调", "primaryForeground": "主色调前景色", "secondary": "次要色调", "secondaryForeground": "次要色调前景色", "third": "第三色调", "thirdForeground": "第三色调前景色", "muted": "柔和色", "mutedForeground": "柔和色前景色", "accent": "强调色", "accentForeground": "强调色前景色", "border": "边框色", "shadow": "阴影色" }, "presets": { "apply": "应用", "reset": { "name": "恢复默认" }, "default": { "name": "默认白色" }, "ocean": { "name": "海洋蓝" }, "forest": { "name": "森林绿" }, "sunset": { "name": "日落红" }, "lavender": { "name": "薰衣草紫" }, "midnight": { "name": "午夜暗" }, "deepSea": { "name": "深海蓝" }, "darkForest": { "name": "暗夜绿" }, "darkViolet": { "name": "紫罗兰暗" }, "coralWarm": { "name": "珊瑚暖" }, "slateGray": { "name": "石板灰" }, "darkGold": { "name": "暗夜金" }, "beigeWarm": { "name": "米黄暖" }, "beigeDark": { "name": "米黄暗" } } } }, "tools": { "title": "工具設置", "chatToolbar": { "title": "對話工具欄", "desc": "自訂對話工具欄按鈕的顯示順序和可見性,打造個性化的對話體驗", "button": "設置", "dialogTitle": "配置對話工具欄", "dialogDesc": "拖動工具調整排序,使用開關控制顯示或隱藏", "groups": { "pc": "PC 端", "mobile": "移動端", "bottom": "底部工具欄", "topLeft": "頂部工具欄 - 左側", "topRight": "頂部工具欄 - 右側" } }, "desc": "配置各种工具栏按钮的显示和排序", "recordToolbar": { "title": "记录工具栏", "desc": "自定义记录工具栏按钮的显示顺序和可见性", "button": "設置", "dialogTitle": "配置记录工具栏", "dialogDesc": "拖动工具调整排序,使用开关控制显示或隐藏" } } }, "rag": { "title": "知識庫", "desc": "在這裡,你可以配置知識庫相關設置,知識庫基於 RAG 技術,透過嵌入模型將文本轉換為向量,然後透過向量搜索來實現智慧搜索和智慧回答。", "settingsTitle": "參數設置", "settingsDesc": "通過調解參數,可以更加精確的控制知識庫的檢索效果。", "deleteVectorConfirm": "確定清空知識庫嗎?", "deleteVectorSuccess": "清空知識庫成功", "enable": "啟用知識庫檢索", "enableDesc": "啟用後,AI 將在回答問題時檢索你的筆記內容,提供更準確的回答。", "topPDesc": "Top P 參數控制模型生成文本的多樣性,值越小生成的文本越確定,值越大生成的文本越多樣。", "chunkSize": "分塊大小", "chunkSizeDesc": "文本分塊的最大字元數,較大的分塊可能包含更多上下文,但會增加向量計算的複雜度。", "chunkOverlap": "重疊大小", "chunkOverlapDesc": "文本分塊間的重疊字元數,較大的重疊可以保持上下文連貫性。", "resultCount": "檢索數量", "resultCountDesc": "檢索時返回的相關文件數量,數量越多提供的資訊可能更豐富,但也可能引入噪聲。", "similarityThreshold": "相似度閾值", "similarityThresholdDesc": "文件與查詢的最小相似度閾值,只有超過此閾值的文件才會被返回。值範圍 0.0-1.0,越高要求越嚴格。", "resetToDefaults": "重設預設值", "deleteVector": "清空知識庫" }, "mcp": { "title": "MCP", "desc": "Model Context Protocol 允許 AI 調用外部工具和訪問資源,擴展 AI 的能力邊界。", "servers": "伺服器列表", "serversDesc": "管理 MCP 伺服器配置,每個伺服器可以提供不同的工具和資源。", "addServer": "添加伺服器", "addFirstServer": "添加第一個伺服器", "editServer": "編輯伺服器", "serverName": "伺服器名稱", "serverNamePlaceholder": "例如:文件系統伺服器", "serverEnabled": "啟用伺服器", "serverEnabledDesc": "啟用後,此伺服器將自動連接並提供工具。", "serverType": "伺服器類型", "stdio": "本地命令", "http": "HTTP 服務", "command": "命令", "args": "參數", "argsDesc": "命令行參數,用空格分隔", "env": "環境變數", "envDesc": "JSON 格式的環境變數配置", "url": "服務地址", "headers": "請求頭", "headersDesc": "JSON 格式的 HTTP 請求頭", "testConnection": "測試連接", "test": "測試", "testSuccess": "連接測試成功", "testFailed": "連接測試失敗", "connected": "已連接", "connecting": "連線中", "disconnected": "未連接", "error": "錯誤", "tools": "工具", "noServers": "未啟用 MCP 服務功能", "noServersFound": "未找到匹配的伺服器", "serverAdded": "伺服器添加成功", "serverUpdated": "伺服器更新成功", "serverDeleted": "伺服器刪除成功", "deleteServerTitle": "刪除伺服器", "deleteServerDesc": "確定要刪除這個伺服器嗎?此操作無法撤銷。", "nameRequired": "請輸入伺服器名稱", "commandRequired": "請輸入命令", "urlRequired": "請輸入服務地址", "toolBrowser": "工具瀏覽器", "searchTools": "搜索工具...", "noToolsFound": "未找到工具", "parameters": "參數", "testAll": "測試所有連接", "testAllCompleted": "所有連接測試完成", "testAllFailed": "連接測試失敗", "save": "保存", "cancel": "取消", "delete": "刪除", "importJson": "導入 JSON", "jsonImportTitle": "從 JSON 導入伺服器配置", "jsonImportDesc": "粘貼 MCP 伺服器的 mcpServers 配置格式", "jsonInput": "JSON 配置", "jsonInputHelp": "支持 mcpServers 格式,會自動使用伺服器名稱作為 key", "jsonRequired": "請輸入 JSON 配置", "jsonEmpty": "JSON 配置不能為空", "jsonInvalidJson": "JSON 格式錯誤", "jsonInvalidFormat": "配置格式無效,必須包含 name 和 type 字段", "jsonInvalidType": "伺服器類型必須是 stdio 或 http", "jsonMissingCommand": "stdio 類型伺服器必須指定 command", "jsonMissingUrl": "http 類型伺服器必須指定 url", "jsonImportSuccess": "成功導入 {count} 個伺服器", "jsonImportSkipped": "跳過 {count} 個已存在的伺服器", "jsonImportNoServers": "沒有導入任何伺服器", "import": "導入", "mobileHttpOnlyTitle": "本地命令 MCP 僅限桌面端", "mobileHttpOnlyDesc": "本地命令型 MCP 伺服器僅支援桌面端,行動端目前只支援 HTTP MCP。", "runtimeEnvironment": "執行環境", "runtimeEnvironmentDesc": "在測試 MCP 伺服器前,先檢查所需的本地執行環境是否可用。", "checkEnvironment": "檢查環境", "recheckEnvironment": "重新檢查環境", "runtimeCheckFailed": "環境檢查失敗", "detectedLauncher": "偵測到的啟動器", "runtimeInstalled": "已安裝", "runtimeMissing": "缺失", "runtimeVersion": "版本", "runtimeInstalledSummary": "已安裝 {installed}/{total}", "showRuntimeDetails": "展開執行環境詳情", "hideRuntimeDetails": "收起執行環境詳情", "runtimeNotChecked": "尚未檢查此執行環境。", "runtimeCurrentUserScope": "若支援,建議命令會安裝到目前使用者環境。", "runtimeManualOnly": "目前平台暫不支援自動安裝此執行環境,請手動安裝後重新檢查。", "installRuntime": "安裝執行環境", "runtimeInstallTitle": "安裝執行環境", "runtimeInstallDesc": "確認後,NoteGen 將執行以下安裝命令。", "runtimeInstallPreparing": "準備安裝", "runtimeInstallRunning": "安裝中", "runtimeInstallCompleted": "安裝完成", "runtimeInstallCancelled": "已取消", "runtimeInstallFailedState": "安裝失敗", "runtimeInstallLogs": "安裝日誌", "runtimeInstallWaitingLogs": "等待安裝輸出...", "runtimeInstallClose": "關閉", "runtimeInstallCancel": "終止安裝", "runtimeInstallCancelledByUser": "使用者已要求取消安裝。", "runtimeInstallCancelFailed": "終止安裝失敗", "runtimeInstallSuccess": "執行環境安裝完成", "runtimeInstallFailed": "執行環境安裝失敗", "runtimeNoGuidedSupport": "目前此命令尚未提供引導式執行環境輔助。", "enableTitle": "启用 MCP 功能", "enableDesc": "启用后,AI 可以调用配置的 MCP 服务器提供的工具。" }, "editor": { "title": "編輯器設置", "interfaceSettings": "界面設置", "desc": "在這裡,你可以對編輯器進行自定義配置,打造更適合你的寫作方式。", "centeredContent": "置中內容", "centeredContentDesc": "啟用後,編輯器內容將在中間顯示,兩側留白。", "outlineEnable": "預設啟用大綱", "outlineEnableDesc": "啟用後,編輯器將默認顯示大綱。", "outlinePosition": "大綱位置", "outlinePositionDesc": "設置大綱位置。", "outlinePositionOptions": { "left": "左側", "right": "右側" }, "showUndoRedo": "復原/重做按鈕", "showUndoRedoDesc": "在編輯器標籤列顯示復原和重做按鈕。", "completion": { "title": "快速補全", "model": { "title": "快速補全模型", "desc": "選擇用於編輯器 AI 內聯補全的模型" } }, "commit": { "title": "自動生成 Commit", "model": { "title": "提交模型", "desc": "用於自動生成 Git 提交信息,基於文件內容變化智能生成描述性提交信息" } }, "mermaid": { "title": "圖表", "rendering": "渲染中...", "renderError": "渲染錯誤", "clickToEdit": "點擊編輯源碼", "clickToAdd": "點擊添加圖表", "placeholder": "輸入 Mermaid 圖表代碼...", "preview": "預覽", "done": "完成", "diagramTypes": { "flowchart": "流程圖", "sequence": "時序圖", "classDiagram": "類圖", "stateDiagram": "狀態圖", "er": "ER圖", "gantt": "甘特圖", "pie": "餅圖", "journey": "旅程圖" }, "templates": { "flowchart": "graph TD\n A[開始] --> B[處理]\n B --> C[結束]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: 你好\n Bob-->>Alice: 回覆", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title 項目計劃\n dateFormat YYYY-MM-DD\n section 第一階段\n 任務1 :a1, 2024-01-01, 30d\n section 第二階段\n 任務2 :after a1, 20d", "pie": "pie title 資源分配\n \"CPU\" : 45\n \"記憶體\" : 30\n \"儲存\" : 25", "journey": "journey\n title 我的日常工作\n section 上午\n 通勤 : 7:00, 5\n 工作 : 9:00, 8" } } }, "record": { "title": "記錄設置", "desc": "在這裡,你可以配置記錄相關的設置,包括記錄描述和工具欄配置。", "model": { "title": "模型設置", "markDesc": { "title": "記錄描述", "desc": "用於處理 OCR 識別後的記錄,生成記錄描述" } }, "toolbar": { "title": "工具欄設置", "recordToolbar": { "title": "記錄工具欄", "desc": "自定義記錄工具欄按鈕的顯示順序和可見性", "button": "設置", "text": { "desc": "记录文本内容" }, "recording": { "desc": "录音记录功能" }, "scan": { "desc": "扫描识别图片中的文字" }, "image": { "desc": "上传图片到笔记" }, "link": { "desc": "记录网页链接" }, "file": { "desc": "上传文件到笔记" }, "todo": { "desc": "创建待办事项" } } } }, "uploadStore": { "uploadConfirm": "上傳配置請確保同步倉庫為私有,否則數據將會洩露!", "downloadConfirm": "下載配置將會覆蓋本地配置,並且重啟生效!", "uploadSuccess": "上傳成功", "downloadSuccess": "下載成功", "upload": "上傳配置", "download": "下載配置" }, "prompt": { "title": "Prompt", "promptTitle": "Prompt 名稱", "desc": "在這裡,你可以添加和管理 Prompt,幫助 AI 更好地理解你的需求。", "addPrompt": "新增 Prompt", "selectPrompt": "選擇 Prompt", "configPrompt": "配置 Prompt", "noContent": "暫無內容", "addPromptDesc": "請輸入 Prompt 名稱和內容,幫助AI更好地理解你的需求。", "promptTitlePlaceholder": "請輸入 Prompt 名稱", "promptContentPlaceholder": "請輸入 Prompt 內容", "promptContent": "Prompt 內容", "optimizePrompt": "最佳化提示詞", "optimizing": "最佳化中...", "optimizeSuccess": "提示詞最佳化成功", "optimizeFailed": "提示詞最佳化失敗,請稍後重試", "noContentToOptimize": "請先輸入提示詞內容" }, "memories": { "title": "記憶管理", "desc": "AI 長期記憶功能,讓 AI 記住你的寫作偏好、知識體系和筆記習慣。", "stats": { "total": "總記憶數", "preferences": "偏好", "knowledge": "知識", "memories": "记忆" }, "form": { "title": "新增記憶", "contentLabel": "記憶內容", "contentPlaceholder": "例如:我喜歡用中文回答、我是React專家...", "categoryLabel": "類型", "preferenceDesc": "偏好(語言、格式、風格等)", "knowledgeDesc": "知識(事實、經驗、專長等)", "save": "儲存記憶", "saving": "儲存中...", "categoryDescription": "记忆分为两种类型:", "preferenceDescription": "偏好:语言、格式、风格等设置,每次对话都会自动加载", "memoryDescription": "记忆:事实、经验、专长等信息,根据对话内容智能匹配", "preferenceLabel": "偏好", "memoryLabel": "记忆", "memoryDesc": "事实、经验、专长等" }, "listTitle": "我的記憶", "addMemory": "新增記憶", "empty": "暫無記憶,新增第一條記憶吧!", "emptyHint": "你可以手動新增記憶,或在對話中使用「請記住」「記住這個」等話術讓 AI 自動記憶。", "preference": "偏好", "knowledge": "知識", "replaced": "已替換", "accessCount": "存取 {count} 次", "tabs": { "all": "全部", "preference": "偏好", "knowledge": "知識", "memory": "记忆" }, "success": "成功", "saved": "記憶已儲存", "updated": "記憶已更新(已替換相似記憶)", "deleted": "記憶已刪除", "cleared": "所有記憶已清空", "found": "找到 {count} 條記憶", "error": "錯誤", "errorEmpty": "請輸入記憶內容", "errorSave": "儲存失敗", "errorDelete": "刪除失敗", "errorList": "取得記憶列表失敗", "errorEmbedding": "無法生成向量嵌入,請檢查嵌入模型設定", "errorClear": "清空失敗", "memory": "记忆" }, "defaultModel": { "title": "默認模型", "desc": "在這裡,你可以針對不同的場景使用不同的模型,提高效率降低成本。", "tooltip": "使用主要模型", "noModel": "不使用模型", "placeholder": "請選擇或搜索模型", "mainModel": "主要模型", "options": { "primaryModel": { "title": "主要模型", "desc": "作為所有場景的主要模型,如果其他對話模型未選擇默認模型,則使用此模型。" }, "markDesc": { "title": "記錄描述", "desc": "用於處理 OCR 識別後的紀錄,生成記錄描述。" }, "placeholder": { "title": "AI 建議", "desc": "AI 建議提示作用於記錄頁面 AI 對話 placeholder 內容生成。" }, "completion": { "title": "快速補全", "desc": "用於 Markdown 編輯器的 AI 內聯補全,類似 GitHub Copilot,快速生成續寫內容。" }, "commit": { "title": "自動生成 commit 資訊", "desc": "用於自動生成 Git 提交資訊,基於文件內容變化智能生成描述性提交資訊。" }, "embedding": { "title": "嵌入模型", "desc": "用於處理文本嵌入和向量化的場景。" }, "reranking": { "title": "重排模型", "desc": "用於搜索結果的重新排序和最佳化。" }, "condense": { "title": "摘要模型", "desc": "用于压缩历史对话内容,节省 token 使用量" } } }, "readAloud": { "title": "朗讀", "desc": "在這裡,你可以配置朗讀相關設置,為聊天內容提供語音播放功能。", "noModel": "不使用模型", "alert": { "title": "你正在使用系統朗讀", "description": "當前未配置音訊模型,正在使用系統朗讀。" }, "options": { "audioModel": { "title": "音訊模型", "desc": "選擇用於文本轉語音的AI模型,支持多種語音類型和參數配置。" }, "speed": { "title": "語速", "desc": "調整語音播放的速度,範圍從0.25倍到4倍速度,預設為1倍正常速度。" } } }, "about": { "title": "關於", "desc": "一款專注於記錄與寫作的 AI 筆記。", "version": "NoteGen v{version}", "checkReleases": "查詢歷史版本", "language": "語言", "checkUpdate": "檢查更新", "checkError": "檢查更新失敗", "updateAvailable": "更新至最新版本", "updateDownloading": "更新中 {downloaded} / {contentLength}", "updateInstalled": "重啟應用", "noUpdate": "當前已是最新版本", "ignoreVersion": "忽略此版本", "ignoreVersionSuccess": "已忽略此版本更新", "items": { "home": { "title": "官網", "buttonName": "打開", "desc": "訪問官網,了解 NoteGen 的更多資訊。" }, "guide": { "title": "配置指南", "buttonName": "打開", "desc": "查看配置指南,了解如何配置模型、同步等資訊。" }, "github": { "title": "GitHub", "buttonName": "查看", "desc": "如果 NoteGen 幫助到了你,請給顆 star 鼓勵一下!" }, "releases": { "title": "更新日誌", "buttonName": "查看", "desc": "查看更新日誌,了解 NoteGen 的更新資訊。" }, "issues": { "title": "問題回饋", "buttonName": "回饋", "desc": "如果發現 NoteGen 有 bug,請在這裡回饋。" }, "discussions": { "title": "交流討論", "buttonName": "討論", "desc": "如果你想和作者或其他用戶交流,可以加群討論。" } } }, "sync": { "title": "同步配置", "desc": "在這裡,你可以配置同步倉庫,它可以幫助你同步記錄、markdown 文件、系統配置等資訊。", "selectPlatform": "選擇同步平台", "platformSettings": "選擇平台", "settings": "同步設置", "platformDesc": "配置 Token 和倉庫資訊以啟用同步功能", "moreSettings": "更多設置", "repoStatus": "倉庫狀態", "syncRepo": "同步倉庫", "syncRepoDesc": "同步寫作中的 markdown 文件。", "imageRepo": "圖床倉庫", "imageRepoDesc": "同步你的圖片到圖床倉庫。", "status": { "connected": "已連接", "disconnected": "未連接", "failed": "連線失敗", "unconfigured": "未配置" }, "uploadRecords": "上載記錄和配置", "downloadConfig": "下載記錄和配置", "cloudSync": "記錄與配置同步", "localBackupAll": "本地備份(全部)", "private": "私有", "public": "公開", "createdAt": "創建於 {time}", "updatedAt": "最後更新於 {time}", "newToken": "創建 access token", "newTokenDesc": "新建 token 時,請務必勾選 repo 權限,配置後將自動創建文件倉庫(私有)和圖床倉庫。", "giteeTokenDesc": "Gitee 私人令牌用於同步數據,需要有倉庫的讀寫權限,配置後將自動創建文件倉庫(私有)和圖床倉庫。", "imageRepoSetting": "開啟圖床", "imageRepoSettingDesc": "你已經配置了圖床倉庫,開啟此項將使用圖床倉庫,否則將使用本地儲存。", "jsdelivrSetting": "jsDelivr", "jsdelivrSettingDesc": "使用 jsdelivr 加速圖片訪問。", "autoSyncDesc": "啟用後,編輯器會在輸入停止 10 秒後自動同步到 GitHub", "giteeAutoSyncDesc": "啟用後,編輯器會在輸入停止 10 秒後自動同步到 Gitee", "customSyncRepo": "自訂同步倉庫名", "customSyncRepoDesc": "留空則使用默認倉庫名", "customImageRepo": "自訂圖床倉庫名", "customImageRepoDesc": "留空則使用默認倉庫名", "backupMethod": "備份方式", "backupMethodDesc": "設置為主要備份方式後,寫作中的所有同步相關功能將使用當前備份方式(圖床功能除外)", "createRepo": "創建倉庫", "creating": "創建中", "checkRepo": "檢查倉庫", "checking": "檢查中", "enterToken": "請輸入 Access Token", "enterTokenHint": "請先輸入 Access Token 以檢查倉庫狀態", "defaultRepoName": "默認: {name}", "gitlabInstanceType": "GitLab 實例類型", "gitlabInstanceTypeDesc": "選擇要連接的 GitLab 實例類型", "gitlabInstanceTypePlaceholder": "選擇 GitLab 實例類型", "gitlabInstanceTypeOptions": { "selfHosted": "自建實例", "selfHostedDesc": "輸入您的自建 GitLab 伺服器地址(如:https://gitlab.example.com)" }, "gitlabAccessTokenDesc": "在 {instanceDisplayName} 創建個人訪問令牌,需要 api 權限", "autoSync": "自動同步", "autoSyncOptions": { "placeholder": "選擇自動同步時間", "disabled": "關閉", "2s": "2 秒", "3s": "3 秒", "5s": "5 秒", "10s": "10 秒", "20s": "20 秒", "30s": "30 秒", "1m": "1 分鐘", "2m": "2 分鐘" }, "autoPullOnOpen": "開啟檔案時自動拉取", "autoPullOnOpenDesc": "開啟檔案時,若遠端有新版本則自動拉取覆蓋本地", "autoPullOnSwitch": "切換檔案時自動拉取", "autoPullOnSwitchDesc": "切換到其他檔案時,若遠端有新版本則自動拉取覆蓋本地", "exclusions": { "title": "同步排除配置", "desc": "以下配置項不會在設備間同步,因為它們是設備特定的", "workspacePath": "工作區路徑", "workspaceHistory": "工作區歷史路徑", "assetsPath": "資源路徑", "uiScale": "界面縮放", "contentTextScale": "正文文字縮放", "customCss": "自訂 CSS", "reason": "這些配置在不同設備上可能不同,不進行同步可以避免路徑錯誤等問題" }, "settingsSync": { "uploadSuccess": "配置上傳成功", "uploadFailed": "配置上傳失敗", "downloadSuccess": "配置下載成功", "downloadFailed": "配置下載失敗", "autoSync": "上傳/下載時會自動同步配置(排除工作區路徑等設備特定配置)" }, "giteaInstanceType": "Gitea 实例类型", "giteaInstanceTypeDesc": "选择要连接的 Gitea 实例类型", "giteaInstanceTypePlaceholder": "选择 Gitea 实例类型", "giteaInstanceTypeOptions": { "selfHosted": "自建实例", "selfHostedDesc": "输入您的自建 Gitea 服务器地址(如:https://gitea.example.com)" }, "giteaAccessTokenDesc": "在 {instanceDisplayName} 创建个人访问令牌,需要完整的 repository 权限", "s3": { "title": "S3 同步", "description": "使用 S3 兼容存储同步你的笔记", "status": "连接状态", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "请输入 Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "请输入 Secret Access Key", "region": "区域", "bucket": "存储桶", "bucketPlaceholder": "请输入存储桶名称", "endpoint": "端点", "pathPrefix": "路径前缀", "pathPrefixPlaceholder": "请输入路径前缀", "pathPrefixDesc": "用于区分不同用户的文件,类似仓库名", "customDomain": "自定义域名", "testConnection": "测试连接", "testing": "测试中", "saveConfig": "保存配置", "saving": "保存中" }, "webdav": { "title": "WebDAV 同步", "description": "使用 WebDAV 协议同步你的笔记", "status": "连接状态", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "url": "服务器地址", "urlPlaceholder": "请输入 WebDAV 服务器地址", "urlDesc": "支持群晖、QNAP、Nextcloud 等 WebDAV 服务", "username": "用户名", "usernamePlaceholder": "请输入用户名", "password": "密码", "passwordPlaceholder": "请输入密码", "pathPrefix": "路径前缀", "pathPrefixPlaceholder": "请输入路径前缀", "pathPrefixDesc": "用于区分不同用户的文件", "testConnection": "测试连接", "testing": "测试中", "saveConfig": "保存配置", "saving": "保存中" } }, "imageHosting": { "title": "圖床設置", "desc": "在這裡,你可以配置圖床服務,用於儲存和管理你的圖片。", "type": "選擇平台", "typeDesc": "選擇圖床服務提供商", "customRepoName": "自訂倉庫名", "customRepoNameDesc": "留空則使用默認倉庫名", "isPrimaryBackup": "當前 {type} 為主要圖床", "setPrimaryBackup": "設為主要圖床", "smms": { "token": { "desc": "請創建並輸入 SM.MS Token。", "createToken": "創建 Token" }, "disk": "磁碟使用情況", "error": "獲取失敗,請檢查網路或 Token 是否正確。" }, "picgo": { "desc": "PicGo 伺服器地址", "ok": "檢測到服務正在運行,請確保 PicGo 圖床已配置。", "error": "服務未運行,請確保 PicGo(需要 v2.2.0+) 應用正在運行,否則無法上傳圖片。" }, "github": { "title": "GitHub 圖床", "description": "使用 GitHub 倉庫作為圖片儲存服務", "repoStatus": "倉庫狀態", "repoExists": "倉庫已存在", "repoNotExists": "倉庫不存在", "checking": "檢測中", "creating": "創建中", "manualCreateTitle": "需要手動創建圖床倉庫", "manualCreateDesc": "請按以下步驟創建圖床倉庫:", "createSteps": { "step1": "訪問 GitHub 並登入您的帳戶", "step2": "點擊右上角的 \"+\" 按鈕,選擇 \"New repository\"", "step3": "倉庫名稱設置為:", "step4": "可以選擇設置為私有倉庫(推薦)", "step5": "點擊 \"Create repository\" 完成創建", "step6": "創建完成後,點擊下方的\"重新檢測\"按鈕" }, "createNewRepo": "創建新倉庫", "recheckRepo": "重新檢測", "recheckingRepo": "檢測中..." }, "s3": { "title": "S3 對象儲存", "description": "配置 AWS S3 或相容 S3 協議的對象儲存服務作為圖床", "status": "連接狀態", "connected": "已連接", "connecting": "連線中", "disconnected": "未連接", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "輸入 Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "輸入 Secret Access Key", "region": "區域", "bucket": "儲存桶", "bucketPlaceholder": "輸入儲存桶名稱", "advancedSettings": "進階設定", "endpoint": "自訂端點", "endpointDesc": "留空使用 AWS S3,或輸入相容 S3 的服務端點", "customDomain": "自訂域名", "customDomainDesc": "可選,用於訪問圖片的自訂域名", "pathPrefix": "路徑前綴", "pathPrefixDesc": "可選,圖片儲存的路徑前綴", "save": "保存配置", "test": "測試連接", "setAsPrimary": "設為主要圖床", "error": "配置錯誤", "requiredFields": "請填寫必填欄位:Access Key ID、Secret Access Key、區域和儲存桶", "saveSuccess": "配置保存成功", "saveSuccessDesc": "S3 配置已保存", "saveError": "配置保存失敗", "testSuccess": "連接測試成功", "testSuccessDesc": "S3 連接正常,可以上傳圖片", "testFailed": "連接測試失敗", "testFailedDesc": "請檢查配置資訊和網路連接", "testFirstDesc": "請先測試連接成功後再設為主要圖床", "setPrimarySuccess": "設置成功", "setPrimarySuccessDesc": "S3 已設為主要圖床" } }, "backupSync": { "title": "備用方案", "desc": "在這裡,你可以使用其他方案來備份你的數據,你可以定期進行備份,以確保數據的安全。", "localBackup": { "tabTitle": "本地備份", "export": { "title": "匯出備份", "desc": "將應用數據打包為 .zip 文件,保存到指定位置。", "button": "選擇位置並匯出", "simpleButton": "匯出", "exporting": "匯出中..." }, "import": { "title": "匯入備份", "desc": "從 .zip 文件恢復應用數據,將覆蓋當前所有數據。", "button": "選擇文件並匯入", "importing": "匯入中...", "warning": "匯入操作將覆蓋所有當前數據,請確保已備份重要內容!" }, "exportDialog": { "title": "選擇備份文件保存位置" }, "importDialog": { "title": "選擇要匯入的備份文件" }, "exportSuccess": "備份匯出成功!", "exportError": "備份匯出失敗", "importSuccess": "備份匯入成功!應用將重啟以應用更改。", "importError": "備份匯入失敗", "restartConfirm": "匯入完成!是否立即重啟應用以應用更改?" } }, "template": { "title": "整理模板", "desc": "在這裡,你可以創建和管理自訂整理模板,幫助 AI 按照你的需求整理記錄內容。", "customTemplate": "自訂模板", "addTemplate": "新增模板", "deleteConfirm": "確認刪除模板嗎?", "status": "狀態", "name": "名稱", "content": "內容", "scope": "範圍", "selectScope": "選擇範圍", "addTemplateDesc": "請輸入自訂模板名稱和內容,幫助 AI 更好地理解你的需求。", "editTemplate": "編輯自訂模板", "noContent": "暫無內容", "range": { "all": "全部", "today": "今天", "week": "近一週", "month": "近一月", "threeMonth": "近三個月", "year": "近一年" } }, "shortcut": { "title": "快捷鍵", "screenshot": "截圖記錄", "link": "連結記錄", "textRecord": "文本記錄", "windowPin": "窗口置頂" }, "theme": { "title": "外觀", "appTheme": "應用配色", "previewTheme": "預覽內容主題", "codeTheme": "代碼塊高亮主題", "selectTheme": "選擇主題" }, "chat": { "title": "對話設置", "desc": "在這裡,你可以配置對話相關的設置,包括摘要生成等功能。", "primaryModel": { "title": "主要模型", "model": { "title": "主要聊天模型", "desc": "選擇用於日常對話的主要 AI 模型" } }, "toolbar": { "title": "工具欄設置", "chatToolbar": { "title": "對話工具欄", "desc": "自定義對話工具欄按鈕的顯示順序和可見性", "button": "設置", "modelSelect": { "desc": "切換用於對話的 AI 模型" }, "promptSelect": { "desc": "選擇對話使用的預設提示詞" }, "chatLanguage": { "desc": "設置對話的語言" }, "chatLink": { "title": "關聯標籤", "desc": "關聯當前標籤的筆記內容到對話上下文" }, "fileLink": { "desc": "關聯文件或文件夾到對話上下文" }, "mcpButton": { "desc": "選擇並連接 MCP 伺服器以使用外部工具" }, "ragSwitch": { "title": "知識庫檢索", "desc": "啟用向量知識庫檢索功能" }, "clipboardMonitor": { "title": "剪貼板監聽", "desc": "自動監聽剪貼板內容變化" }, "newChat": { "desc": "開始新對話" }, "clearContext": { "desc": "清除對話上下文,保留聊天記錄" }, "clearChat": { "desc": "刪除所有聊天記錄" } } }, "condense": { "title": "對話摘要", "enable": { "title": "啟用摘要", "desc": "自動壓縮長對話以節省 token 使用量" }, "model": { "title": "摘要模型", "desc": "選擇用於生成摘要的 AI 模型", "placeholder": "使用主模型" }, "threshold": { "title": "觸發閾值", "desc": "AI 消息超過此數量時檢查壓縮" }, "minToken": { "title": "最小 Token 數", "desc": "單條消息超過此 token 數才進行壓縮" }, "keepLatest": { "title": "保留最新條數", "desc": "保留最新的 N 條 AI 消息不進行壓縮" }, "maxLength": { "title": "摘要長度限制", "desc": "控制生成摘要的最大字數" }, "prompt": { "title": "自定義摘要提示詞", "desc": "自定義生成摘要時使用的提示詞模板", "label": "提示詞模板", "placeholder": "輸入自定義提示詞...", "help": "使用 {content} 作為原始內容的佔位符", "save": "保存", "reset": "重置為默認" } }, "inspiration": { "title": "靈感模型", "model": { "title": "靈感生成模型", "desc": "用於生成快速提示詞建議,幫助用戶快速開始對話" } }, "conversationTitle": { "title": "会话标题", "model": { "title": "标题生成模型", "desc": "选择用于生成会话标题的 AI 模型" } } }, "dev": { "title": "開發者", "desc": "在這裡,你可以配置開發者選項,包括網路代理、數據清理和設定檔管理等進階功能。", "clearData": "清理數據", "clearDataConfirm": "確定清理數據嗎?", "proxy": "代理,用於解決網路問題,配置後建議重啟應用。", "proxyPlaceholder": "請輸入代理地址", "proxyTitle": "網路代理", "clearDataTitle": "清理數據", "clearDataDesc": "清理數據資訊,包括系統配置資訊、資料庫(包含記錄)。", "clearFileTitle": "清理文件", "clearFileDesc": "清理文件,包括圖片、文章。", "clearButton": "清理", "configFileTitle": "設定檔管理", "configFileDesc": "設定檔匯入與匯出,匯入設定檔將覆蓋當前配置,並且重啟後生效。", "importConfigTitle": "匯入設定檔", "exportConfigTitle": "匯出設定檔", "importConfigSuccessMobile": "配置下載成功,請手動重啟應用", "exportConfigSuccess": "匯出成功", "importButton": "匯入", "exportButton": "匯出" }, "ai": { "title": "模型配置", "desc": "在這裡,你可以添加和管理各種自訂模型提供服務,配置後將解鎖 AI 相關功能,例如整理和對話功能。", "modelTitle": "自訂名稱", "modelConfigTitle": "模型配置", "modelConfigDesc": "每一個配置對應一個 AI 模型,你可以通過模板或自訂創建新的配置。", "providerInfo": "供應商資訊", "providerInfoDesc": "此配置基於供應商模板創建,名稱和地址已預設,無需修改。", "create": "創建新配置", "createDesc": "選擇空配置或使用供應商模板創建新的配置。", "createSection": { "title": "自訂模型配置", "descWithoutModels": "添加自訂 AI 模型配置來使用更強大的模型服務。" }, "config": "配置單", "custom": "自訂模型配置", "addCustomModel": "自訂", "deleteCustomModel": "刪除", "deleteCustomModelConfirm": "確認刪除此自訂模型配置嗎?", "copyConfig": "複製", "builtin": "內建", "modelSupport": "僅支持 openai 協議的 AI 模型", "apiKeyUrl": "創建 API Key", "modelType": { "title": "模型類型", "desc": "根據 AI 模型能力選擇模型類型,用以調用不同的介面。", "chat": "對話", "image": "生圖", "video": "影片", "audio": "語音", "embedding": "嵌入", "rerank": "重排序", "tts": "文本转语音", "stt": "语音转文本" }, "modelList": { "error": { "title": "獲取模型列表失敗", "description": "請檢查 API Key 或網路是否正確" } }, "selectModel": "請選擇模型", "modelProviderDesc": "自訂模型僅支持 openai 協議的 AI 模型。", "modelTitleDesc": "自訂名稱,用於標識 AI 模型,請勿重複。", "modelBaseUrlDesc": "你只需要配置到版本號即可,例如:https://api.openai.com/v1,後綴會自動添加。", "modelDesc": "部分模型支持獲取模型列表,如果不支持請手動配置。", "temperatureDesc": "使用什麼採樣溫度,介於 0 和 2 之間。較高的值(如 0.8)將使輸出更加隨機,而較低的值(如 0.2)將使輸出更加集中和確定。 我們通常建議改變這個或top_p但不是兩者。", "topPDesc": "一種替代溫度採樣的方法,稱為核採樣,其中模型考慮具有 top_p 機率質量的標記的結果。所以 0.1 意味著只考慮構成前 10% 機率質量的標記。 我們通常建議改變這個或temperature但不是兩者。", "customHeaders": "自訂請求頭", "customHeadersDesc": "添加自訂 HTTP 請求頭,支持多個鍵值對配置。", "headerKey": "鍵", "headerValue": "值", "addHeader": "添加 Header", "connectionSuccess": "AI 連接測試通過", "connectionFailed": "連接失敗", "voice": "語音類型", "voiceDesc": "指定音訊模型使用的語音類型,如 'alloy'、'echo'、'fable' 等。", "voicePlaceholder": "請輸入語音類型,如:alloy", "enableStream": "流式響應", "enableStreamDesc": "啟用流式響應可以即時顯示生成內容,但某些模型可能不支持此功能。", "selectConfig": "請選擇配置", "models": "模型列表", "modelsDesc": "在這裡管理當前配置下的所有模型,每個模型可以有不同的類型和參數。", "addModel": "添加模型", "newModel": "新模型", "checkConnection": "檢測連接", "model": "模型", "defaultModels": { "title": "默認免費模型", "desc": "NoteGen 為用戶提供免費的 AI 模型服務,由矽基流動提供支持,無需配置即可使用基礎功能。", "chatModel": { "name": "Qwen/Qwen3-8B", "type": "對話模型", "desc": "適用於日常對話、文本生成等場景" }, "embeddingModel": { "name": "BAAI/bge-m3", "type": "嵌入模型", "desc": "用於文本向量化、語義搜索等功能" }, "visionModel": { "name": "OpenGVLab/InternVL2-8B", "type": "視覺模型", "desc": "支持圖像理解、視覺問答等功能" }, "completionModel": { "name": "快速補全", "type": "補全模型", "desc": "用於 Markdown 編輯器的 AI 內聯補全,類似 GitHub Copilot,快速生成續寫內容" }, "poweredBy": "由 SiliconFlow 提供技術支援" } }, "imageMethod": { "title": "圖像識別", "desc": "在這裡,你可以配置圖像識別相關設置,支持 OCR 和 VLM 兩種方式。", "setPrimary": "設置為默認", "isPrimary": "{type} 已設置為默認", "ocr": { "title": "OCR", "languagePacks": "語言包", "checkModels": "在此查詢全部模型", "modelInstruction": "以逗號分隔,例如:eng,chi_sim" }, "vlm": { "title": "視覺語言模型", "desc": "通過視覺語言模型識別圖片內容。" }, "enable": { "title": "启用图像识别", "desc": "开启后,在截图记录和插图记录时会自动进行图片识别。关闭后将跳过图片识别步骤。" } }, "file": { "title": "文件管理", "desc": "在這裡,你可以管理工作區設置和其他文件相關選項。", "workspace": { "title": "工作區設置", "desc": "設置應用程式的工作區目錄,文件將保存在該目錄中。", "current": "工作區路徑", "defaultPath": "默認工作區", "default": "當前使用默認工作區路徑。", "custom": "當前使用自訂工作區路徑。", "select": "選擇工作區目錄", "reset": "重設為默認路徑", "history": "歷史路徑", "selectFromHistory": "從歷史記錄中選擇工作區", "clearHistory": "清空歷史記錄", "actions": "操作", "searchPlaceholder": "搜索工作區路徑...", "noResults": "未找到結果" }, "info": { "title": "工作區說明", "desc": "更改工作區後需要重啟應用程式才能完全生效。新工作區中的文件將在重啟後顯示。" }, "toast": { "updated": "工作區已更新", "updatedDesc": "工作區已設置為: {path}", "reset": "工作區已重設", "resetDesc": "已恢復使用默認工作區", "error": "選擇工作區失敗", "errorDesc": "無法選擇工作區目錄,請重試", "resetError": "重設工作區失敗", "resetErrorDesc": "無法重設為默認工作區,請重試" }, "assets": { "title": "寫作資源路徑", "desc": "設置寫作資源的保存路徑,例如圖片、影片、文件等,與當前編輯的 markdown 文件同級。", "select": "請設置寫作資源路徑,例如:assets" } }, "shortcuts": { "title": "快捷鍵", "desc": "在這裡,你可以配置快捷鍵,幫助你更高效地使用 NoteGen。", "resetDefaults": "重設", "clear": "清空", "noShortcut": "未設置", "shortcuts": { "openWindow": { "title": "打開/隱藏窗口", "desc": "打開/隱藏程序主窗口。" }, "quickRecordText": { "title": "快速記錄文本", "desc": "快速打開程式主窗口,並調出文本記錄。" } } }, "skills": { "title": "Skills", "desc": "Skills 是可重用的 AI 能力包,让 AI 助手能够根据任务自动应用特定的行为模式。", "enable": "启用 Skills 功能", "enableDesc": "启用后,AI 可以使用已配置的 Skills", "autoMatch": "自动匹配 Skills", "autoMatchDesc": "根据用户输入自动选择合适的 Skills", "project": "工作区 Skills", "global": "全局 Skills", "globalPath": "全局 Skills 存储位置", "openInFileManager": "在文件管理器中打开", "createSkill": "创建 Skill", "editSkill": "编辑 Skill", "deleteSkill": "删除 Skill", "exportSkill": "导出 Skill", "importSkill": "导入 Skill", "selectSkillZip": "选择 Skill zip 文件", "importSuccess": "导入成功", "importError": "导入失败", "imported": "已导入", "importing": "导入中...", "skillName": "Skill 名称", "skillDescription": "描述", "skillVersion": "版本", "skillAuthor": "作者", "allowedTools": "允许使用的工具", "userInvocable": "在斜杠菜单显示", "instructions": "指令内容", "instructionsPlaceholder": "输入给 AI 的详细指令...", "importHelp": "支持导入 zip 格式的 Skill,zip 文件需包含 SKILL.md 文件。", "metadata": "元数据", "content": "指令内容", "noSkills": "还没有 Skills", "noSkillsDesc": "创建或导入 Skills 以开始使用", "noSkillsGlobal": "还没有全局 Skills", "noSkillsGlobalDesc": "创建或导入 Skills 以在所有项目中使用", "emptyWorkspace": "工作区中没有 Skills", "emptyWorkspaceDesc": "在 skills 文件夹中创建 SKILL.md 文件来添加 Skill", "basicSettings": "基础设置", "installedGlobalSkills": "已安装的全局 Skills", "nameRequired": "请输入 Skill 名称", "descriptionRequired": "请输入描述", "namePlaceholder": "note-organizer", "versionPlaceholder": "1.0.0", "descriptionPlaceholder": "自动整理和优化笔记结构...", "authorPlaceholder": "Your Name", "descriptionHelp": "用于 AI 匹配,描述此 Skill 的功能和适用场景", "allowedToolsHelp": "这些工具使用时不需要用户确认", "userInvocableHelp": "用户可以通过 /skill-name 手动触发", "instructionsHelp": "给 AI 的详细指令,支持 Markdown 格式", "deleteSkillTitle": "删除 Skill", "deleteSkillDesc": "确定要删除这个 Skill 吗?此操作无法撤销。", "skillDeleted": "Skill 删除成功" }, "audio": { "title": "语音设置", "desc": "在这里,你可以配置语音相关设置,包括文本转语音(朗读)和语音转文本(录音识别)功能。", "mode": { "title": "運行方式", "auto": "自動(推薦)", "local": "僅本地", "model": "僅模型" }, "tts": { "title": "文本转语音(TTS)", "desc": "配置朗读功能,为聊天内容提供语音播放。", "modeDesc": "預設優先使用瀏覽器與系統語音,需要更佳效果時再使用模型。", "model": { "title": "朗读模型", "desc": "可選。配置後可在自動模式下增強體驗,或在僅模型模式下使用。" }, "speed": { "title": "语速", "desc": "调整语音播放的速度,范围从0.5倍到2倍速度,默认为1倍正常速度。" } }, "stt": { "title": "语音转文本(STT)", "desc": "配置录音识别功能,将语音转换为文字记录。", "modeDesc": "預設優先使用瀏覽器原生識別,不支援時再回退到模型識別。", "model": { "title": "识别模型", "desc": "可選。配置後可在自動模式下回退使用,或在僅模型模式下強制使用。" } } }, "readAloud": { "title": "朗讀", "desc": "配置文字朗讀方式,預設優先使用系統語音,模型作為增強能力。", "options": { "mode": { "title": "運行方式", "desc": "自動模式會優先使用系統語音,不可用時再嘗試模型。", "auto": "自動(推薦)", "local": "僅本地", "model": "僅模型" }, "audioModel": { "title": "朗讀模型", "desc": "可選。配置後可在自動模式下增強體驗,或在僅模型模式下使用。" }, "speed": { "title": "語速", "desc": "調整朗讀速度,範圍從0.5倍到2倍,預設為1倍。" } } } }, "record": { "trash": { "title": "清空回收站", "confirm": "確定清空回收站嗎?", "records": "共 {count} 條紀錄可還原", "empty": "清空", "close": "關閉回收站" }, "queue": { "ocr": "OCR 識別", "ai": "AI 內容識別", "upload": "上傳至圖床", "jsdelivr": "通知 jsdelivr 快取", "recording": "記錄中...", "recorded": "已記錄", "record": "記錄", "detected": "檢測到", "save": "保存" }, "mark": { "empty": "暫無記錄", "loading": "載入中...", "type": { "scan": "截圖", "image": "插圖", "screenshot": "截圖", "text": "文本", "file": "文件", "link": "連結", "todo": "待辦", "pdf": "PDF", "upload": "上傳記錄", "download": "下載記錄", "uploadTo": "從本地同步到 {provider}", "downloadFrom": "從 {provider} 同步到本地", "recording": "录音" }, "note": { "organizeAs": "整理為", "template": "模板", "setting": "設置", "confirm": "確認", "cancel": "取消", "removeThinking": "移除思考過程", "stop": "停止" }, "uploadSuccess": "記錄上傳成功", "downloadSuccess": "記錄下載成功", "desc": "描述", "content": "內容", "createdAt": "創建於", "progress": { "cacheImage": "快取圖片", "ocr": "OCR 識別", "aiAnalysis": "AI 內容識別", "uploadImage": "上傳至圖床", "jsdelivrCache": "通知 jsdelivr 快取", "cacheFile": "快取文件", "cacheScreenshot": "快取截圖", "textAnalysis": "文本分析", "save": "保存", "saveImage": "保存圖片" }, "text": { "title": "記錄文本", "description": "記錄一段文本,筆記整理時將插入到合適的位置。", "characterCount": "{count} 字元", "save": "記錄", "autoReadClipboard": "自動讀取剪貼簿文本" }, "link": { "title": "連結記錄", "description": "輸入網頁連結,系統將自動爬取頁面內容並保存", "save": "保存", "autoReadClipboard": "自動讀取剪貼簿連結" }, "todo": { "title": "待辦記錄", "description": "創建待辦事項,管理你的任務", "titlePlaceholder": "輸入待辦標題...", "descriptionPlaceholder": "輸入詳細描述(可選)", "priority": "優先級", "priorityLow": "低", "priorityMedium": "中", "priorityHigh": "高", "dateRange": "日期範圍", "dateRangePlaceholder": "選擇日期範圍", "dueDate": "截止日期", "dueDatePlaceholder": "選擇日期", "save": "創建待辦", "saveEdit": "保存", "edit": "編輯待辦", "editDescription": "修改待辦事項的詳細信息", "cancel": "取消", "selectTag": "選擇標籤", "completed": "已完成", "uncompleted": "未完成" }, "clipboard": { "detectedImage": "檢測到剪貼簿圖片", "detectedText": "檢測到剪貼簿文本" }, "tag": { "searchPlaceholder": "創建或查詢標籤...", "noResults": "未查詢到相關標籤", "quickAdd": "快速創建", "pinned": "置頂", "others": "其他", "rename": "重命名", "delete": "刪除", "pin": "置頂", "unpin": "取消置頂", "newTag": "新建標籤", "newTagPlaceholder": "輸入標籤名稱...", "add": "添加" }, "mark": { "empty": "暫無記錄", "emptyHint": "使用頂部工具欄開始你的第一條紀錄吧!", "type": { "text": "文本" }, "chat": { "modeSelect": { "chat": "對話", "agent": "智能體" }, "agent": { "running": "Agent 運行中", "thinking": "思考中", "acting": "執行中", "observation": "觀察結果", "toolCalls": "工具調用", "thought": "思考", "action": "行動", "confirmation": { "title": "確認操作", "description": "Agent 想要執行以下操作,請確認後繼續。", "tool": "工具", "parameters": "參數", "cancel": "取消", "confirm": "確認", "confirmed": "已確認", "cancelled": "已取消" } }, "placeholder": { "default": "你可以提問或將記錄整理為文章...", "noApiKey": "未配置 API Key,無法使用 AI 對話功能...", "on": "AI建議開啟", "off": "AI建議關閉" }, "header": { "configApiKey": "配置 API KEY", "clearChat": "清空對話", "configPrompt": "配置 Prompt", "selectPrompt": "選擇 Prompt" }, "clipboard": { "image": { "detected": "檢測到剪貼簿存在圖片:", "recording": "正在記錄", "recorded": "已記錄", "record": "記錄" }, "text": { "detected": "檢測到剪貼簿存在文本:", "recorded": "已記錄", "record": "記錄" } }, "messageControl": { "words": "字", "summary": "摘要" }, "mcp": { "maxIterationsReached": "達到最大工具調用次數限制", "toolCall": "MCP 伺服器", "params": "參數", "result": "返回結果", "copy": "複製", "paramsCopied": "參數已複製", "resultCopied": "結果已複製", "calling": "調用中", "success": "已完成", "error": "失敗" }, "empty": { "title": "開始與 AI 對話", "subtitle": "使用 Chat 或 Agent 模式與 AI 互動", "currentModel": "當前模型", "currentPrompt": "當前 Prompt", "currentMode": "對話模式", "noModel": "未設置模型", "noPrompt": "未設置 Prompt", "configureModel": "配置模型", "recentConversations": "最近對話", "deleteConversation": "刪除對話", "conversationHistory": "歷史對話", "viewMore": "查看更多", "messages": "條消息", "searchPlaceholder": "搜索對話...", "noMatchingConversations": "沒有找到匹配的對話", "noConversationHistory": "暫無歷史對話", "quickPrompts": { "title": "快速開始", "writeNote": "幫我寫一篇筆記", "summarize": "幫我總結這段內容", "brainstorm": "幫我頭腦風暴一些想法", "explain": "幫我解釋這個概念" }, "modeHint": "點擊輸入框左側的", "modeHintSuffix": "按鈕可切換對話模式" }, "content": { "organize": "將你的紀錄整理為文章:" }, "note": { "writing": "寫作", "convert": "轉化文章", "description": "當前的筆記是由 AI 生成且無法編輯,將當前筆記轉化為文章(生成本地文件),可在寫作頁面中進行二次創作。", "filename": "檔案名", "selectFolder": "選擇文件夾", "rootDirectory": "根目錄", "deleteTag": "刪除當前標籤、記錄和筆記(回收站可恢復)", "warning": "轉換後將跳轉到寫作頁面。", "convert_button": "轉化" }, "mark": { "recorded": "已記錄", "record": "記錄" }, "send": "發送" }, "text": { "title": "記錄文本", "description": "記錄一段文本,筆記整理時將插入到合適的位置。", "characterCount": "{count} 字元", "save": "記錄" }, "clipboard": { "detectedImage": "檢測到剪貼簿圖片", "detectedText": "檢測到剪貼簿文本" }, "tag": { "searchPlaceholder": "創建或查詢標籤...", "noResults": "未查詢到相關標籤", "quickAdd": "快速創建", "pinned": "置頂", "others": "其他", "rename": "重命名", "delete": "刪除", "pin": "置頂", "unpin": "取消置頂" }, "progress": { "cacheImage": "快取圖片", "ocr": "OCR 識別", "aiAnalysis": "AI 內容識別", "uploadImage": "上傳至圖床", "jsdelivrCache": "通知 jsdelivr 快取", "cacheFile": "快取文件", "cacheScreenshot": "快取截圖", "textAnalysis": "文本分析", "save": "保存", "saveImage": "保存圖片" } }, "toolbar": { "search": "搜索", "trash": "回收站", "restore": "還原", "delete": "刪除", "deleteConfirm": "確定要刪除嗎?", "moveTag": "轉移標籤", "convertTo": "轉換為{type}", "copyLink": "複製連結", "copied": "已複製到剪切板!", "regenerateDesc": "重新生成描述", "viewFolder": "查看目錄", "viewFile": "查看原文件", "deleteForever": "徹底刪除", "multiSelect": "多選", "exitMultiSelect": "退出多選", "selectAll": "全選", "deselectAll": "取消全選", "selectedCount": "已選擇 {count} 項", "moveSelectedTags": "轉移選中的 {count} 項", "deleteSelected": "刪除選中的 {count} 項", "deleteSelectedForever": "徹底刪除選中的 {count} 項", "organizeNotes": "整理筆記", "organizeSuccess": "筆記整理成功:{title}", "organizeError": "整理筆記失敗", "currentTag": "當前標籤", "text": "記錄文本", "recording": "錄音記錄", "scan": "掃描圖片", "image": "上傳圖片", "link": "記錄連結", "file": "上傳文件", "todo": "待辦記錄", "closeTrash": "關閉回收站" }, "list": { "title": "記錄" }, "imageGallery": { "expand": "展开", "collapse": "收起" } }, "chat": { "empty": { "features": [ { "chat": "與 AI 機器人進行聊天" }, { "linked": "已與你的紀錄或筆記關聯" }, { "clipboard": "識別剪貼簿中的文字和圖片" }, { "organize": "將你的紀錄整理為筆記" } ], "title": "開始與 AI 對話", "subtitle": "使用 Chat 或 Agent 模式與 AI 互動", "currentModel": "當前模型", "currentPrompt": "當前 Prompt", "currentMode": "對話模式", "noModel": "未設置模型", "noPrompt": "未設置 Prompt", "configureModel": "配置模型", "recentConversations": "最近對話", "deleteConversation": "刪除對話", "conversationHistory": "歷史對話", "viewMore": "查看更多", "messages": "條消息", "searchPlaceholder": "搜索對話...", "noMatchingConversations": "沒有找到匹配的對話", "noConversationHistory": "暫無歷史對話", "quickPrompts": { "title": "快速开始", "writeNote": "帮我写一篇笔记", "summarize": "帮我总结这段内容", "brainstorm": "帮我头脑风暴一些想法", "explain": "帮我解释这个概念" } }, "newChat": "使用新標籤開始對話", "removeChat": "刪除當前標籤對話", "confirmNew": "創建新標籤", "confirmNewDescription": "請確認要創建一個新的標籤開始對話嗎?", "confirmRemove": "刪除標籤", "confirmRemoveDescription": "請注意,刪除此標籤會連帶刪除內部的紀錄,請再次確認。", "input": { "organize": "整理", "chat": "聊天", "placeholder": { "default": "你可以提問或將記錄整理為文章...", "noApiKey": "未配置 API Key,無法使用 AI 對話功能...", "on": "AI 建議 (開啟)", "off": "AI 建議 (關閉)", "noPrimaryModel": "未配置主模型,無法使用 AI 對話功能..." }, "translate": { "tooltip": "翻譯", "translating": "翻譯中...", "showOriginal": "顯示原文", "alreadyTranslated": "已翻譯為" }, "clipboardMonitor": { "enable": "剪貼簿監聽(開啟)", "disable": "剪貼簿監聽(關閉)" }, "send": "發送", "stop": "停止", "terminate": "終止", "tagLink": { "on": "已關聯標籤", "off": "未關聯標籤" }, "modelSelect": { "tooltip": "選擇 AI 模型", "placeholder": "搜索 AI 模型", "noModel": "未找到模型" }, "promptSelect": { "tooltip": "選擇 Prompt", "placeholder": "搜索 Prompt" }, "clearChat": "清空對話", "clearContext": { "tooltip": "清除上下文" }, "chatLanguage": { "tooltip": "選擇對話語言", "placeholder": "搜索語言" }, "rag": { "notSupported": "向量模型不可用", "enabled": "知識庫檢索(開啟)", "disabled": "知識庫檢索(關閉)" }, "modeSelect": { "tooltip": "選擇輸入模式", "chat": "對話模式", "gen": "整理模式", "translate": "翻譯模式" }, "chatModeSelect": { "chatDescription": "快速對話,分析優先", "agentDescription": "智能助手,可執行操作" }, "attachImage": "附加圖片", "imageSelector": { "title": "選擇圖片", "local": "本地文件", "records": "從記錄中選擇", "selectFiles": "選擇本地圖片", "noRecords": "沒有可用的圖片記錄", "cancel": "取消", "confirm": "確認" }, "agent": { "running": "Agent 運行中", "thinking": "思考中", "analyzingRequest": "Agent 正在分析您的請求...", "acting": "執行中", "observation": "觀察結果", "toolCalls": "工具調用", "autoFinal": { "createNote": "已建立筆記《{name}》。", "createFile": "已建立檔案《{name}》。" }, "thought": "思考", "action": "行動", "confirmation": { "title": "確認操作", "description": "Agent 想要執行以下操作,請確認後繼續。", "tool": "工具", "parameters": "參數", "cancel": "取消", "confirm": "確認", "confirmed": "已確認", "cancelled": "已取消" } }, "fileLink": { "tooltip": "關聯文件", "selectFile": "選擇文件", "linkedFile": "關聯文件", "searchPlaceholder": "搜尋文件...", "noFiles": "未找到文件", "loading": "載入中..." }, "stopped": "对话已终止", "mcp": { "tooltip": "MCP 服务器" }, "newChat": "开始新对话" }, "header": { "configApiKey": "配置 API KEY", "clearChat": "清空聊天", "configPrompt": "配置 Prompt", "selectPrompt": "選擇 Prompt", "noModel": "未選擇 AI 模型" }, "clipboard": { "image": { "detected": "檢測到剪貼簿存在圖片:", "recording": "正在記錄", "recorded": "已記錄", "record": "記錄" }, "text": { "detected": "檢測到剪貼簿存在文本:", "recorded": "已記錄", "record": "記錄" } }, "messageControl": { "words": "字", "summary": "摘要", "readAloud": "朗讀", "playing": "播放中", "loading": "準備中", "stop": "停止播放", "copy": "複製", "copied": "已複製" }, "ragSources": { "label": "知識庫檢索到 {count} 篇筆記", "openFile": "打開文件" }, "preview": { "close": "關閉", "copy": "複製", "copied": "已複製!" }, "control": { "edit": "編輯", "save": "保存", "cancel": "取消", "delete": "刪除", "deleteConfirm": "確定要刪除這條消息嗎?" }, "content": { "organize": "將你的紀錄整理為文章:" }, "quote": { "lineSingle": "引用自 {fileName} 第 {line} 行", "lineRange": "引用自 {fileName} 第 {startLine}-{endLine} 行", "noLine": "引用自 {fileName}" }, "note": { "organize": "整理", "writing": "寫作", "convert": "轉化文章", "description": "當前的筆記是由 AI 生成且無法編輯,將當前筆記轉化為文章(生成本地文件),可在寫作頁面中進行二次創作。", "filename": "檔案名", "selectFolder": "選擇文件夾", "rootDirectory": "根目錄", "deleteTag": "刪除當前標籤、記錄和筆記(回收站可恢復)", "warning": "轉換後將跳轉到寫作頁面。", "convert_button": "轉化", "organizeAs": "將記錄整理成...", "templateContent": "模板內容", "recordRange": "記錄選擇範圍", "filterThinkingContent": "移除記錄中的思考", "startOrganize": "開始整理", "manageTemplate": "管理模板", "cancel": "取消", "stop": "停止" }, "mark": { "recorded": "已記錄", "record": "記錄" }, "condensing": "正在压缩上下文...", "condensed": { "message": "已压缩 {count} 条历史消息" } }, "tag": { "add": "添加標籤", "edit": "編輯標籤", "delete": "刪除標籤", "deleteConfirm": "確定要刪除這個標籤嗎?", "placeholder": "輸入標籤名稱" } }, "search": { "placeholder": "搜尋筆記和文章...", "results": "{count} 個搜索結果", "noResults": "暫無搜索結果", "tryDifferentKeywords": "嘗試使用不同的關鍵字搜索", "mode": { "fuzzy": "模糊", "exact": "精確" }, "item": { "record": "記錄", "article": "文章", "matches": "{count}個匹配項", "scanType": "截圖" } }, "image": { "root": "圖床倉庫", "noData": { "title": "同步功能未開啟", "desc": "請先跳轉至系統設置頁面,配置 Github 同步。", "goToSettings": "前往設置", "howToUse": "如何使用同步功能?" } }, "navigation": { "chat": "對話", "record": "記錄", "quickRecord": "快捷記錄", "write": "寫作", "search": "搜索", "githubImageHosting": "Github 圖床", "login": "登錄", "loading": "載入中", "view": "查看", "logout": "登出", "setting": "設置", "activity": "活躍度", "files": "筆記", "outline": "大綱", "hideLeftSidebar": "隱藏左側邊欄", "showLeftSidebar": "顯示左側邊欄", "hideRightSidebar": "隱藏右側邊欄", "showRightSidebar": "顯示右側邊欄", "searchPlaceholder": "搜索筆記或記錄...", "showCenterPanel": "显示编辑器", "hideCenterPanel": "隐藏编辑器" }, "activity": { "title": "活躍度日曆", "description": "按天查看你的記錄、對話與寫作活躍情況。第一版基於現有記錄、使用者對話與筆記修改時間進行統計。", "drawer": { "title": "活躍度", "description": "快速查看今天狀態和最近一段時間的活躍趨勢。", "today": "今天" }, "loading": "正在載入活躍度資料...", "empty": "暫無活躍度資料", "refresh": "重新整理", "summary": { "totalCount": "總活躍次數", "activeDays": "活躍天數", "records": "記錄次數", "chats": "對話次數", "writing": "寫作活躍" }, "labels": { "record": "記錄", "writing": "寫作", "chat": "對話" }, "heatmap": { "title": "最近 26 週熱力圖", "range": "{startDate} - {endDate}", "less": "少", "more": "多", "dayCount": "次活動", "emptyDay": "無活動" }, "detail": { "title": "當天明細", "empty": "選擇一個日期查看當天的活動明細。" } }, "marks": { "types": { "screenshot": "截圖", "text": "文本", "image": "插圖" } }, "tags": { "inspiration": "靈感" }, "sync": { "status": "同步倉庫狀態", "imageRepo": "圖床倉庫", "articleRepo": "文章倉庫" }, "ai": { "thinking": "思考", "error": { "title": "AI 錯誤", "noAddress": "請先設置 AI 地址" } }, "article": { "sync": { "syncingRemote": "正在拉取遠端檔案...", "syncComplete": "同步完成", "pullingRemote": "正在從遠端伺服器獲取最新內容..." }, "syncConfirm": { "title": "檢測到遠端檔案更新", "description": "檔案 {fileName} 有遠端更新", "commitInfo": "最新提交資訊", "commitMessage": "提交訊息", "author": "作者", "changes": "變更", "confirmMessage": "確認要拉取遠端版本並覆蓋本地檔案嗎?此操作無法撤銷。", "cancel": "取消", "confirmPull": "確認拉取" }, "emptyState": { "title": "開始創作", "subtitle": "選擇一個文件開始編輯,或創建新的筆記", "tip": "💡 提示:你也可以從左側文件管理器中選擇文件", "actions": { "newNote": { "title": "創建筆記", "desc": "新建一篇 Markdown 筆記" }, "newRecord": { "title": "創建記錄", "desc": "打開文本記錄功能" }, "globalSearch": { "title": "全局搜索", "desc": "快速查找你的筆記內容" }, "openWorkspace": { "title": "打開工作區", "desc": "選擇或切換工作區目錄" } }, "onboarding": { "title": "新手引導", "subtitle": "跟著這三步體驗 NoteGen 的核心工作流。", "dismiss": "跳過新手引導", "reopen": "重新顯示新手引導", "start": "開始引導", "viewHint": "查看提示", "continue": "繼續下一步", "completed": "已完成", "allDone": "新手任務已全部完成,你已經體驗了 NoteGen 的基礎工作流。", "stepLabel": "任務 ({current}/{total})", "stepCompletedLabel": "已完成任務 ({current}/{total})", "afterOrganizeDialog": { "title": "已完成任務 (2/3)", "description": "你已經把記錄整理成一篇筆記。要繼續體驗下一步,使用 AI Agent 將這篇筆記翻譯成雙語版本嗎?", "confirm": "繼續下一步", "cancel": "暫時不用" }, "agentPrompt": { "label": "示例提示詞", "use": "使用這條提示詞", "intro": "請將我剛剛整理出的這篇筆記直接修改為中英雙語版本。", "requirement1": "", "requirement2": "", "requirement3": "", "requirement4": "", "outro": "" }, "steps": { "createRecord": { "title": "建立第一條記錄", "desc": "先記錄一段示例內容,熟悉記錄入口。" }, "organizeNote": { "title": "整理成筆記", "desc": "把剛才的記錄整理成一篇正式筆記。" }, "aiPolish": { "title": "用 Agent 翻譯成雙語", "desc": "使用 AI Agent 將剛整理好的筆記翻譯成雙語版本。" } }, "completedStates": { "create-record": { "title": "你已經建立了第一條記錄", "desc": "現在你已經知道如何快速記錄內容了。" }, "organize-note": { "title": "你已經把記錄整理成筆記", "desc": "下一步可以體驗 AI 如何繼續修改這篇筆記。" }, "ai-polish": { "title": "你已經用 Agent 處理了筆記", "desc": "你已經體驗了從記錄到整理,再到 Agent 處理內容的完整流程。" } }, "spotlight": { "create-record": { "title": "這裡可以快速記錄內容", "desc": "點擊這個文字記錄入口,系統會自動帶入一段示例內容,你也可以自己修改。" }, "organize-note": { "title": "這裡可以整理記錄", "desc": "點擊這個按鈕,把剛才的記錄整理成一篇正式筆記。" }, "ai-polish": { "title": "這裡可以用 Agent 處理剛生成的筆記", "desc": "將示例提示詞填入對話框後送出,Agent 會基於當前筆記生成雙語版本。" } } } }, "unsupportedFile": { "title": "無法預覽此文件", "fileName": "文件名", "filePath": "文件路徑", "fileSize": "文件大小", "modifiedTime": "修改時間", "createdTime": "創建時間", "pathCopied": "路徑已複製", "openExternal": "用外部程序打開", "openDirectory": "打開文件目錄" }, "file": { "toolbar": { "accessRepo": "訪問倉庫", "loadingSync": "正在載入同步資訊", "configSync": "配置同步", "newArticle": "新建文章", "newFolder": "新建文件夾", "refresh": "刷新", "toggleFolders": "文件夾展開摺疊", "expandAll": "全部展開", "collapseAll": "全部摺疊", "sortByName": "按名稱排序", "sortByCreated": "按創建時間排序", "sortByModified": "按修改時間排序", "sortAsc": "升序排列", "sortDesc": "降序排列", "sort": "排序", "hideCloudFiles": "隱藏雲端檔案", "showCloudFiles": "顯示雲端檔案", "processingVectors": "正在處理向量數據", "calculateVectors": "知識庫計算(全量)", "importMarkdown": "匯入", "importing": "正在匯入...", "importSuccess": "匯入成功", "importSuccessDesc": "成功匯入 {count} 個文件", "importError": "匯入失敗" }, "sync": { "syncingRemote": "正在拉取遠端檔案", "syncComplete": "同步完成", "pullingRemote": "正在從遠端伺服器取得最新內容...", "pullComplete": "拉取完成" }, "context": { "viewDirectory": "查看目錄", "cut": "剪切", "copy": "複製", "paste": "黏貼", "rename": "重命名", "deleteSyncFile": "刪除同步文件", "deleteLocalFile": "刪除本地文件", "delete": "刪除", "confirmDelete": "確定要刪除文件夾 \"{name}\" 嗎?此操作將刪除文件夾及其所有內容。", "deleteSuccess": "刪除成功", "deleteFailed": "刪除失敗", "newFile": "新建文件", "newFolder": "新建文件夾", "syncFolder": "同步", "syncFolderDesc": "同步當前文件夾下的所有 Markdown 文件", "syncFolderSuccess": "文件夾同步成功", "syncFolderError": "文件夾同步失敗", "syncFolderProgress": "正在同步文件夾...", "deleteSyncFileSuccess": "刪除成功", "deleteSyncFileError": "刪除失敗", "knowledgeBase": "知識庫", "calculateVectors": "計算向量", "updateVectors": "更新向量", "deleteVectors": "刪除向量", "includeInKB": "包含在知識庫", "includeInKBFile": "包含在知識庫中", "autoVectorCalc": "自動向量計算", "vectorCalculated": "向量已更新", "vectorCalcCompleted": "向量計算完成", "vectorCalcFailed": "向量計算失敗", "vectorDeleted": "向量已刪除", "vectorDeleteFailed": "刪除向量失敗", "batchCalcSuccess": "成功計算 {count} 個文件的向量", "batchCalcPartial": "計算完成:成功 {success} 個,失敗 {failed} 個", "batchCalcFailed": "批量計算向量失敗", "batchDeleteSuccess": "成功刪除 {count} 個文件的向量", "batchDeletePartial": "刪除完成:成功 {success} 個,失敗 {failed} 個", "batchDeleteFailed": "批量刪除向量失敗", "noMarkdownFiles": "文件夾中沒有 Markdown 文件", "includedInKB": "已包含在知識庫中", "excludedFromKB": "已從知識庫中排除", "autoCalcEnabled": "已啟用自動向量計算", "autoCalcDisabled": "已禁用自動向量計算", "settingFailed": "設置失敗", "confirmDeleteVectors": "確定要刪除 {count} 個文件的向量嗎?" }, "folderView": { "vectorDbNotEnabled": "向量資料庫未啟用", "calculateVectors": "計算向量", "indexed": "已計算", "vectorCount": "向量數", "databaseSize": "資料庫大小", "lastCalculated": "最後計算", "never": "從未", "calculating": "計算中...", "failed": "失敗", "recalculateVectors": "重新計算向量", "skills": "Skills", "skillNotFound": "Skill 未找到", "skillNotFoundDesc": "無法找到 ID 為 {id} 的 Skill", "loadingSkills": "載入 Skills...", "loadingSkill": "載入 Skill...", "globalSkills": "全域 Skills", "workspaceSkills": "工作區 Skills", "instructions": "指令", "examples": "示例", "scripts": "腳本", "references": "參考文檔", "assets": "靜態資源" }, "error": { "fileExists": "檔案名已存在" }, "clipboard": { "copied": "已複製到剪貼簿", "cut": "已剪切到剪貼簿", "pasted": "已黏貼成功", "pasteFailed": "黏貼操作失敗", "empty": "剪貼簿為空", "confirmOverwrite": "文件已存在,是否覆蓋?", "notSupported": "不支持此操作" }, "deleteConfirm": "確認刪除此文件嗎?" }, "editor": { "copySuccess": "複製成功", "copySuccessDescription": "已複製到剪貼簿", "search": { "placeholder": "在文件中尋找", "replacePlaceholder": "取代為", "caseSensitive": "區分大小寫", "replace": "取代", "replaceAll": "全部取代", "findPrev": "上一個", "findNext": "下一個" }, "floatbar": { "quote": { "tooltip": "引用" }, "readAloud": { "start": "朗讀", "stop": "停止朗讀", "loading": "正在載入..." } }, "upload": { "error": "上傳失敗", "needToken": "上傳圖片需配置 accessToken", "uploading": "正在上傳圖片" }, "toolbar": { "organize": { "tooltip": "整理筆記" }, "mark": { "title": "使用記錄", "tooltip": "使用記錄", "description": "消耗記錄轉化為內容插入到文章。", "noRecords": "暫無記錄", "ocrNoContent": "OCR 未識別到任何內容" }, "question": { "tooltip": "問答", "selectContent": "請先選擇一段內容", "promptTemplate": "參考原文:\n{content}\n根據提問:\n{question}\n,直接返回回答內容。" }, "continue": { "tooltip": "續寫", "promptTemplate": "根據前文:\n{content}\n內容,直接返回續寫內容,不要超過100字。\n內容可以參考後文:\n{endContent}\n,不要與後文內容重複。" }, "polish": { "tooltip": "潤色", "selectContent": "請先選擇一段內容", "promptTemplate": "潤色這段文字:\n{content}\n要求語言不變,修復錯別字和病句,直接返回潤色後的結果。" }, "eraser": { "tooltip": "精簡", "selectContent": "請先選擇一段內容", "promptTemplate": "精簡這段文字:\n{content}\n這段文字過於臃腫,字數要求縮減一半以上,要求語言不變,直接返回最佳化後的結果。" }, "expansion": { "tooltip": "擴寫", "selectContent": "請先選擇一段內容", "promptTemplate": "擴寫這段文字:\n{content}\n這段文字過於簡短,字數要求增加一倍以上,要求語言不變,直接返回擴寫後的結果。" }, "translation": { "tooltip": "翻譯", "description": "將選中的文本進行翻譯", "selectContent": "請先選擇一段內容", "promptTemplate": "將這段文字:\n{content}\n翻譯為{language}語言,直接返回翻譯後的結果。", "fail": "翻譯失敗", "failNoSelection": "請先選擇要翻譯的文本", "translating": "翻譯中", "translatingTo": "正在翻譯為 {language}...", "success": "翻譯完成", "successTo": "已翻譯為 {language}", "customLanguage": "自定義語言...", "customLanguagePlaceholder": "輸入目標語言,如:英語、日語等", "customLanguageEmpty": "請輸入目標語言", "customLanguageExample": "例如:英語、日語、法語等" } }, "saveDialog": { "title": "保存文件", "emptyContent": "内容为空", "emptyContentDesc": "请先输入内容后再保存", "success": "保存成功", "successDesc": "文件已保存", "error": "保存失败", "errorDesc": "文件保存失败,请重试" } }, "footer": { "wordCount": "字數", "pull": { "pull": "拉取", "checking": "檢查更新中...", "noUpdate": "無遠端更新", "clickToPull": "點擊拉取遠端更新", "pullSuccess": "拉取成功", "pullFailed": "拉取失敗", "ignored": "已忽略", "ignoreUpdate": "忽略此更新" }, "sync": { "push": "推送", "pushed": "已推送", "syncing": "推送中", "syncFailed": "推送失敗", "checkNetworkOrToken": "請檢查網路連接或令牌是否正確", "quickSync": "快速同步" }, "history": { "loadingHistory": "正在讀取歷史記錄", "historyRecords": "歷史記錄", "noHistory": "無歷史記錄", "loading": "載入中", "recordsCount": "條紀錄", "filterQuickSync": "過濾快速同步", "committedAt": "提交於", "pull": "拉取", "quickSync": "快速同步" }, "vectorCalc": { "tooltip": { "default": "向量索引狀態", "none": "點擊開始向量計算", "indexed": "已索引", "pending": "待更新,點擊立即計算", "calculating": "計算中..." }, "status": { "calculating": "計算中" } } } }, "mobile": { "chat": { "drawer": { "settings": { "title": "對話設定" }, "tools": { "title": "工具", "clearContext": "清除上下文", "clearContextDesc": "清除對話上下文,保留聊天記錄", "clearChat": "清空對話", "clearChatDesc": "刪除所有聊天記錄", "clear": "清除", "newChat": "开始新对话", "start": "开始" }, "attachments": { "title": "附件", "gallery": "相簿", "camera": "照相", "file": "檔案", "linkNote": "關聯筆記" } } } }, "mcp": { "selectServers": "MCP 伺服器", "searchServers": "搜索伺服器...", "noServers": "未啟用 MCP 服務功能", "noServersFound": "未找到匹配的伺服器", "addServer": "添加伺服器...", "goToSettings": "前往設置", "close": "關閉", "navigate": "選擇", "confirm": "確認", "tools": "個工具", "connecting": "連線中", "disconnected": "未連接" }, "quickRecord": { "description": "點擊選擇記錄工具,快速創建記錄" }, "recording": { "title": "录音识别", "description": "点击麦克风按钮开始录音,系统将自动识别并转换为文字记录", "recording": "录音中", "paused": "已暂停", "ready": "准备就绪", "processing": "识别中...", "cancel": "取消", "error": "错误", "success": "成功", "noModelConfigured": "未配置语音识别模型,请先在设置中配置", "speechUnavailable": "當前識別方式不可用,請檢查本地語音支援或模型配置", "fallbackToModel": "本地語音識別不可用,已自動切換為模型識別", "startError": "无法启动录音", "noAudioData": "未录制到音频数据", "transcriptionSuccess": "语音识别完成", "transcriptionEmpty": "识别结果为空", "transcriptionError": "语音识别失败", "configureModel": "配置模型", "retryTranscription": "重新識別", "retrying": "重新識別中...", "retrySuccess": "重新識別完成", "retryError": "重新識別失敗", "noContentDetected": "未识别到内容", "doubleClickToSelectFile": "双击选择音频文件", "mode": { "builtin": "浏览器识别", "builtinDesc": "免费,实时识别", "model": "大模型识别", "modelDesc": "需配置STT模型,更准确" } }, "editor": { "placeholder": "輸入 / 叫出選單,或直接開始寫作...", "outline": { "title": "大綱", "open": "打開大綱", "close": "關閉大綱" }, "translation": { "fail": "翻譯失敗", "failNoSelection": "請先選擇要翻譯的文本", "translating": "翻譯中...", "translatingTo": "正在翻譯為 {language}...", "success": "翻譯完成", "successTo": "已翻譯為 {language}", "customLanguageEmpty": "請輸入目標語言", "customLanguageExample": "例如:英語、日語、法語等" }, "quoteDisplay": { "fromFile": "引用自 {fileName}", "line": "引用自 {fileName} 第 {line} 行", "lines": "引用自 {fileName} 第 {start}-{end} 行" }, "bubbleMenu": { "ai": "AI", "polish": "潤色", "concise": "精簡", "expand": "擴展", "translate": "翻譯", "translateSubtitle": "翻譯為", "quoteToChat": "引用到對話", "link": "連結", "linkPlaceholder": "輸入連結地址", "confirm": "確認", "cancel": "取消", "bold": "粗體", "italic": "斜體", "strike": "刪除線", "underline": "底線", "inlineCode": "行內代碼", "highlight": "高亮", "blockquote": "引用", "bulletList": "無序列表", "orderedList": "有序列表", "taskList": "任務列表", "codeBlock": "代碼塊", "languages": { "English": "英語", "Japanese": "日語", "Korean": "韓語", "French": "法語", "German": "德語", "Spanish": "西班牙語", "Portuguese": "葡萄牙語", "Russian": "俄語", "Arabic": "阿拉伯語" }, "customLanguagePlaceholder": "自定義語言..." }, "aiSuggestion": { "accept": "接受", "reject": "拒絕", "generating": "生成中...", "abort": "終止" }, "image": { "insert": "插入圖片", "uploading": "上傳中...", "uploadSuccess": "圖片已上傳到圖床", "saveSuccess": "圖片已保存到本地", "uploadFailed": "插入圖片失敗", "sizeSmall": "小 (25%)", "sizeMedium": "中 (50%)", "sizeLarge": "大 (75%)", "sizeOriginal": "原始尺寸", "editAlt": "編輯替代文本", "editSrc": "編輯地址", "altPlaceholder": "輸入替代文本...", "srcPlaceholder": "輸入圖片地址...", "delete": "刪除圖片", "confirm": "確認", "cancel": "取消" }, "mermaid": { "rendering": "渲染中...", "renderError": "渲染錯誤", "clickToEdit": "點擊編輯源碼", "clickToAdd": "點擊添加圖表", "placeholder": "輸入 Mermaid 圖表代碼...", "preview": "預覽", "done": "完成", "diagramTypes": { "flowchart": "流程圖", "sequence": "時序圖", "classDiagram": "類圖", "stateDiagram": "狀態圖", "er": "ER圖", "gantt": "甘特圖", "pie": "餅圖", "journey": "旅程圖" }, "templates": { "flowchart": "graph TD\n A[開始] --> B[處理]\n B --> C[結束]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: 你好\n Bob-->>Alice: 回覆", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title 項目計劃\n dateFormat YYYY-MM-DD\n section 第一階段\n 任務1 :a1, 2024-01-01, 30d\n section 第二階段\n 任務2 :after a1, 20d", "pie": "pie title 資源分配\n \"CPU\" : 45\n \"記憶體\" : 30\n \"儲存\" : 25", "journey": "journey\n title 我的日常工作\n section 上午\n 通勤 : 7:00, 5\n 工作 : 9:00, 8" } }, "slashCommand": { "groups": { "ai": "AI", "heading": "標題", "list": "列表", "block": "區塊", "align": "對齊", "embed": "嵌入", "math": "數學", "chart": "圖表" }, "items": { "continue": "續寫", "continueDesc": "AI 續寫內容", "heading1": "標題1", "heading1Desc": "大標題", "heading2": "標題2", "heading2Desc": "中標題", "heading3": "標題3", "heading3Desc": "小標題", "bulletList": "無序列表", "bulletListDesc": "建立簡單的項目列表", "orderedList": "有序列表", "orderedListDesc": "建立帶編號的列表", "taskList": "任務列表", "taskListDesc": "建立帶核取方塊的任務列表", "image": "圖片", "imageDesc": "插入本地圖片或圖床圖片", "table": "表格", "tableDesc": "插入表格", "blockquote": "引用", "blockquoteDesc": "擷取引用內容", "codeBlock": "程式碼區塊", "codeBlockDesc": "擷取程式碼片段", "divider": "分隔線", "dividerDesc": "在元素之間建立分隔線", "inlineMath": "行內公式", "inlineMathDesc": "插入行內 LaTeX 公式", "blockMath": "區塊公式", "blockMathDesc": "插入區塊 LaTeX 公式", "flowchart": "流程圖", "flowchartDesc": "插入流程圖", "sequence": "時序圖", "sequenceDesc": "插入時序圖", "gantt": "甘特圖", "ganttDesc": "插入甘特圖", "classDiagram": "類別圖", "classDiagramDesc": "插入類別圖", "stateDiagram": "狀態圖", "stateDiagramDesc": "插入狀態圖", "pie": "圓餅圖", "pieDesc": "插入圓餅圖", "erDiagram": "ER圖", "erDiagramDesc": "插入實體關係圖", "journey": "旅程圖", "journeyDesc": "插入使用者旅程圖" }, "imageUpload": { "success": "上傳成功", "saveSuccess": "儲存成功", "savePath": "儲存路徑: {path}", "failed": "插入圖片失敗" } } }, "tabContext": { "close": "關閉", "closeOthers": "關閉其他", "closeAll": "關閉全部", "closeLeft": "關閉左側", "closeRight": "關閉右側" } } ================================================ FILE: messages/zh.json ================================================ { "app": { "title": "笔记生成器", "description": "你的 AI 驱动的笔记助手" }, "common": { "save": "保存", "cancel": "取消", "delete": "删除", "confirm": "确认", "edit": "编辑", "create": "创建", "theme": "主题", "light": "亮色", "dark": "暗色", "system": "跟随系统", "pin": "置顶", "unpin": "取消置顶", "settings": "设置", "sync": "同步", "language": "语言", "success": "成功", "error": "失败", "defaultFileName": "未命名文档", "back": "返回", "close": "关闭", "open": "打开", "add": "添加", "remove": "移除", "search": "搜索", "filter": "筛选", "sort": "排序", "export": "导出", "import": "导入", "refresh": "刷新", "loading": "加载中...", "all": "全部", "today": "今天", "yesterday": "昨天", "warning": "警告", "info": "信息", "restartToApply": ",请重启应用使配置生效", "unsaved": "未保存", "saving": "保存中...", "configureSync": "配置同步" }, "settings": { "defaultModels": { "title": "默认模型" }, "others": "高级", "general": { "title": "常规设置", "desc": "在这里,你可以配置应用的基本设置,包括界面主题、语言等选项。", "interface": { "title": "界面设置", "theme": { "title": "主题", "desc": "选择应用的外观主题", "options": { "light": "亮色", "dark": "暗色", "system": "跟随系统" } }, "language": { "title": "语言", "desc": "选择应用的显示语言" }, "scale": { "title": "界面缩放", "desc": "调整应用界面的整体缩放比例", "placeholder": "选择缩放比例" }, "contentTextScale": { "title": "正文缩放", "desc": "调整编辑器和对话中 Markdown 内容的文字大小" }, "fileManagerTextSize": { "title": "文件管理器文字大小", "desc": "调整文件管理器中文件和文件夹列表的文字大小" }, "recordTextSize": { "title": "记录文字大小", "desc": "调整记录列表中记录项的文字大小" }, "customCss": { "title": "自定义 CSS", "desc": "添加自定义 CSS 样式来覆盖应用的默认样式", "button": "编辑 CSS", "dialogTitle": "自定义 CSS", "dialogDesc": "在下方输入自定义 CSS 代码,可以覆盖应用的默认样式。修改后点击保存即可生效。", "placeholder": "在此输入自定义 CSS 代码。", "save": "保存", "cancel": "取消" }, "customTheme": { "title": "自定义主题颜色", "desc": "自定义应用的主题颜色,包括背景色、前景色、边框色等", "button": "编辑颜色", "dialogTitle": "自定义主题颜色", "dialogDesc": "配置自定义主题颜色。颜色更改会实时保存并生效,同时覆盖亮色和暗色主题。", "close": "关闭", "reset": "重置全部", "tabs": { "custom": "自定义", "presets": "预设方案", "importExport": "导入导出" }, "export": { "title": "导出配色方案", "button": "生成导出代码", "placeholder": "点击生成按钮将当前配色导出为代码" }, "import": { "title": "导入配色方案", "button": "导入配色", "placeholder": "粘贴配色方案的 JSON 代码" }, "colors": { "background": "背景色", "foreground": "前景色", "card": "卡片背景色", "cardForeground": "卡片前景色", "primary": "主色调", "primaryForeground": "主色调前景色", "secondary": "次要色调", "secondaryForeground": "次要色调前景色", "third": "第三色调", "thirdForeground": "第三色调前景色", "muted": "柔和色", "mutedForeground": "柔和色前景色", "accent": "强调色", "accentForeground": "强调色前景色", "border": "边框色", "shadow": "阴影色" }, "presets": { "apply": "应用", "reset": { "name": "恢复默认" }, "default": { "name": "默认白色" }, "ocean": { "name": "海洋蓝" }, "forest": { "name": "森林绿" }, "sunset": { "name": "日落红" }, "lavender": { "name": "薰衣草紫" }, "midnight": { "name": "午夜暗" }, "deepSea": { "name": "深海蓝" }, "darkForest": { "name": "暗夜绿" }, "darkViolet": { "name": "紫罗兰暗" }, "coralWarm": { "name": "珊瑚暖" }, "slateGray": { "name": "石板灰" }, "darkGold": { "name": "暗夜金" }, "beigeWarm": { "name": "米黄暖" }, "beigeDark": { "name": "米黄暗" } } }, "tray": { "enabled": { "title": "启用托盘", "desc": "关闭窗口时选择最小化到托盘或直接关闭软件" } } }, "tools": { "title": "工具设置", "desc": "配置各种工具栏按钮的显示和排序", "chatToolbar": { "title": "对话工具栏", "desc": "自定义对话工具栏按钮的显示顺序和可见性", "button": "设置", "dialogTitle": "配置对话工具栏", "dialogDesc": "拖动工具调整排序,使用开关控制显示或隐藏", "groups": { "pc": "PC 端", "mobile": "移动端", "bottom": "底部工具栏", "topLeft": "顶部工具栏 - 左侧", "topRight": "顶部工具栏 - 右侧" } }, "recordToolbar": { "title": "记录工具栏", "desc": "自定义记录工具栏按钮的显示顺序和可见性", "button": "设置", "dialogTitle": "配置记录工具栏", "dialogDesc": "拖动工具调整排序,使用开关控制显示或隐藏" } } }, "rag": { "title": "知识库", "desc": "在这里,你可以配置知识库相关设置,知识库基于 RAG 技术,通过嵌入模型将文本转换为向量,然后通过向量搜索来实现智能搜索和智能回答。", "settingsTitle": "参数设置", "settingsDesc": "通过调解参数,可以更加精确的控制知识库的检索效果。", "deleteVectorConfirm": "确定清空知识库吗?", "deleteVectorSuccess": "清空知识库成功", "enable": "启用知识库检索", "enableDesc": "启用后,AI 将在回答问题时检索你的笔记内容,提供更准确的回答。", "topPDesc": "Top P 参数控制模型生成文本的多样性,值越小生成的文本越确定,值越大生成的文本越多样。", "chunkSize": "分块大小", "chunkSizeDesc": "文本分块的最大字符数,较大的分块可能包含更多上下文,但会增加向量计算的复杂度。", "chunkOverlap": "重叠大小", "chunkOverlapDesc": "文本分块间的重叠字符数,较大的重叠可以保持上下文连贯性。", "resultCount": "检索数量", "resultCountDesc": "检索时返回的相关文档数量,数量越多提供的信息可能更丰富,但也可能引入噪声。", "similarityThreshold": "相似度阈值", "similarityThresholdDesc": "文档与查询的最小相似度阈值,只有超过此阈值的文档才会被返回。值范围 0.0-1.0,越高要求越严格。", "resetToDefaults": "重置默认值", "deleteVector": "清空知识库" }, "mcp": { "title": "MCP", "desc": "Model Context Protocol 允许 AI 调用外部工具和访问资源,扩展 AI 的能力边界。", "enableTitle": "启用 MCP 功能", "enableDesc": "启用后,AI 可以调用配置的 MCP 服务器提供的工具。", "servers": "服务器列表", "serversDesc": "管理 MCP 服务器配置,每个服务器可以提供不同的工具和资源。", "addServer": "添加服务器", "addFirstServer": "添加第一个服务器", "editServer": "编辑服务器", "serverName": "服务器名称", "serverNamePlaceholder": "例如:文件系统服务器", "serverEnabled": "启用服务器", "serverEnabledDesc": "启用后,此服务器将自动连接并提供工具。", "serverType": "服务器类型", "stdio": "本地命令", "http": "HTTP 服务", "command": "命令", "args": "参数", "argsDesc": "命令行参数,用空格分隔", "env": "环境变量", "envDesc": "JSON 格式的环境变量配置", "url": "服务地址", "headers": "请求头", "headersDesc": "JSON 格式的 HTTP 请求头", "testConnection": "测试连接", "test": "测试", "testSuccess": "连接测试成功", "testFailed": "连接测试失败", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "error": "错误", "tools": "工具", "noServers": "未启用 MCP 服务功能", "noServersFound": "未找到匹配的服务器", "serverAdded": "服务器添加成功", "serverUpdated": "服务器更新成功", "serverDeleted": "服务器删除成功", "deleteServerTitle": "删除服务器", "deleteServerDesc": "确定要删除这个服务器吗?此操作无法撤销。", "nameRequired": "请输入服务器名称", "commandRequired": "请输入命令", "urlRequired": "请输入服务地址", "toolBrowser": "工具浏览器", "searchTools": "搜索工具...", "noToolsFound": "未找到工具", "parameters": "参数", "testAll": "测试所有连接", "testAllCompleted": "所有连接测试完成", "testAllFailed": "连接测试失败", "save": "保存", "cancel": "取消", "delete": "删除", "importJson": "导入 JSON", "jsonImportTitle": "从 JSON 导入服务器配置", "jsonImportDesc": "粘贴 MCP 服务器的 mcpServers 配置格式", "jsonInput": "JSON 配置", "jsonInputHelp": "支持 mcpServers 格式,会自动使用服务器名称作为 key", "jsonRequired": "请输入 JSON 配置", "jsonEmpty": "JSON 配置不能为空", "jsonInvalidJson": "JSON 格式错误", "jsonInvalidFormat": "配置格式无效,必须包含 name 和 type 字段", "jsonInvalidType": "服务器类型必须是 stdio 或 http", "jsonMissingCommand": "stdio 类型服务器必须指定 command", "jsonMissingUrl": "http 类型服务器必须指定 url", "jsonImportSuccess": "成功导入 {count} 个服务器", "jsonImportSkipped": "跳过 {count} 个已存在的服务器", "jsonImportNoServers": "没有导入任何服务器", "import": "导入", "mobileHttpOnlyTitle": "本地命令 MCP 仅限桌面端", "mobileHttpOnlyDesc": "本地命令型 MCP 服务器仅支持桌面端,移动端当前只支持 HTTP MCP。", "runtimeEnvironment": "运行时环境", "runtimeEnvironmentDesc": "在测试 MCP 服务器前,先检查所需的本地运行时是否可用。", "checkEnvironment": "检查环境", "recheckEnvironment": "重新检查环境", "runtimeCheckFailed": "环境检查失败", "detectedLauncher": "检测到的启动器", "runtimeInstalled": "已安装", "runtimeMissing": "缺失", "runtimeVersion": "版本", "runtimeInstalledSummary": "已安装 {installed}/{total}", "showRuntimeDetails": "展开运行时详情", "hideRuntimeDetails": "收起运行时详情", "runtimeNotChecked": "尚未检查该运行时。", "runtimeCurrentUserScope": "推荐命令会尽量安装到当前用户环境。", "runtimeManualOnly": "当前平台暂不支持自动安装该运行时,请手动安装后重新检查。", "installRuntime": "安装运行时", "runtimeInstallTitle": "安装运行时", "runtimeInstallDesc": "确认后,NoteGen 将执行以下安装命令。", "runtimeInstallPreparing": "准备安装", "runtimeInstallRunning": "安装中", "runtimeInstallCompleted": "安装完成", "runtimeInstallCancelled": "已取消", "runtimeInstallFailedState": "安装失败", "runtimeInstallLogs": "安装日志", "runtimeInstallWaitingLogs": "等待安装输出...", "runtimeInstallClose": "关闭", "runtimeInstallCancel": "终止安装", "runtimeInstallCancelledByUser": "用户已请求取消安装。", "runtimeInstallCancelFailed": "终止安装失败", "runtimeInstallSuccess": "运行时安装完成", "runtimeInstallFailed": "运行时安装失败", "runtimeNoGuidedSupport": "当前命令暂不支持引导式运行时辅助。" }, "skills": { "title": "Skills", "desc": "Skills 是可重用的 AI 能力包,让 AI 助手能够根据任务自动应用特定的行为模式。", "enable": "启用 Skills 功能", "enableDesc": "启用后,AI 可以使用已配置的 Skills", "autoMatch": "自动匹配 Skills", "autoMatchDesc": "根据用户输入自动选择合适的 Skills", "project": "工作区 Skills", "global": "全局 Skills", "globalPath": "全局 Skills 存储位置", "openInFileManager": "在文件管理器中打开", "createSkill": "创建 Skill", "editSkill": "编辑 Skill", "deleteSkill": "删除 Skill", "exportSkill": "导出 Skill", "importSkill": "导入 Skill", "selectSkillZip": "选择 Skill zip 文件", "importSuccess": "导入成功", "importError": "导入失败", "imported": "已导入", "importing": "导入中...", "skillName": "Skill 名称", "skillDescription": "描述", "skillVersion": "版本", "skillAuthor": "作者", "allowedTools": "允许使用的工具", "userInvocable": "在斜杠菜单显示", "instructions": "指令内容", "instructionsPlaceholder": "输入给 AI 的详细指令...", "importHelp": "支持导入 zip 格式的 Skill,zip 文件需包含 SKILL.md 文件。", "metadata": "元数据", "content": "指令内容", "noSkills": "还没有 Skills", "noSkillsDesc": "创建或导入 Skills 以开始使用", "noSkillsGlobal": "还没有全局 Skills", "noSkillsGlobalDesc": "创建或导入 Skills 以在所有项目中使用", "emptyWorkspace": "工作区中没有 Skills", "emptyWorkspaceDesc": "在 skills 文件夹中创建 SKILL.md 文件来添加 Skill", "basicSettings": "基础设置", "installedGlobalSkills": "已安装的全局 Skills", "nameRequired": "请输入 Skill 名称", "descriptionRequired": "请输入描述", "namePlaceholder": "note-organizer", "versionPlaceholder": "1.0.0", "descriptionPlaceholder": "自动整理和优化笔记结构...", "authorPlaceholder": "Your Name", "descriptionHelp": "用于 AI 匹配,描述此 Skill 的功能和适用场景", "allowedToolsHelp": "这些工具使用时不需要用户确认", "userInvocableHelp": "用户可以通过 /skill-name 手动触发", "instructionsHelp": "给 AI 的详细指令,支持 Markdown 格式", "deleteSkillTitle": "删除 Skill", "deleteSkillDesc": "确定要删除这个 Skill 吗?此操作无法撤销。", "skillDeleted": "Skill 删除成功" }, "editor": { "title": "编辑器设置", "desc": "在这里,你可以对编辑器进行自定义配置,打造更适合你的写作方式。", "interfaceSettings": "界面设置", "centeredContent": "居中内容", "centeredContentDesc": "启用后,编辑器内容将在中间显示,两侧留白。", "outlineEnable": "默认启用大纲", "outlineEnableDesc": "启用后,编辑器将默认显示大纲。", "outlinePosition": "大纲位置", "outlinePositionDesc": "设置大纲位置。", "outlinePositionOptions": { "left": "左侧", "right": "右侧" }, "showUndoRedo": "撤销/重做按钮", "showUndoRedoDesc": "在编辑器标签栏显示撤销和重做按钮。", "completion": { "title": "快速补全", "model": { "title": "快速补全模型", "desc": "选择用于编辑器 AI 内联补全的模型" } }, "commit": { "title": "自动生成 Commit", "model": { "title": "提交模型", "desc": "用于自动生成 Git 提交信息,基于文件内容变化智能生成描述性提交信息" } }, "mermaid": { "title": "图表", "rendering": "渲染中...", "renderError": "渲染错误", "clickToEdit": "点击编辑源码", "clickToAdd": "点击添加图表代码", "placeholder": "输入 Mermaid 图表代码...", "preview": "预览", "done": "完成", "diagramTypes": { "flowchart": "流程图", "sequence": "时序图", "classDiagram": "类图", "stateDiagram": "状态图", "er": "ER图", "gantt": "甘特图", "pie": "饼图", "journey": "旅程图" }, "templates": { "flowchart": "graph TD\n A[开始] --> B[处理]\n B --> C[结束]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: 你好\n Bob-->>Alice: 回复", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title 项目计划\n dateFormat YYYY-MM-DD\n section 第一阶段\n 任务1 :a1, 2024-01-01, 30d\n section 第二阶段\n 任务2 :after a1, 20d", "pie": "pie title 资源分配\n \"CPU\" : 45\n \"内存\" : 30\n \"存储\" : 25", "journey": "journey\n title 我的日常工作\n section 上午\n 通勤 : 7:00, 5\n 工作 : 9:00, 8" } } }, "record": { "title": "记录设置", "desc": "在这里,你可以配置记录相关的设置,包括记录描述和工具栏配置。", "model": { "title": "模型设置", "markDesc": { "title": "记录描述", "desc": "用于处理 OCR 识别后的记录,生成记录描述" } }, "toolbar": { "title": "工具栏设置", "recordToolbar": { "title": "记录工具栏", "desc": "自定义记录工具栏按钮的显示顺序和可见性", "button": "设置", "text": { "desc": "记录文本内容" }, "recording": { "desc": "录音记录功能" }, "scan": { "desc": "扫描识别图片中的文字" }, "image": { "desc": "上传图片到笔记" }, "link": { "desc": "记录网页链接" }, "file": { "desc": "上传文件到笔记" }, "todo": { "desc": "创建待办事项" } } } }, "uploadStore": { "uploadConfirm": "上传配置请确保同步仓库为私有,否则数据将会泄露!", "downloadConfirm": "下载配置将会覆盖本地配置,并且重启生效!", "uploadSuccess": "上传成功", "downloadSuccess": "下载成功", "upload": "上传配置", "download": "下载配置" }, "prompt": { "title": "Prompt", "promptTitle": "Prompt 名称", "desc": "在这里,你可以添加和管理 Prompt,帮助 AI 更好地理解你的需求。", "addPrompt": "新增 Prompt", "selectPrompt": "选择 Prompt", "configPrompt": "配置 Prompt", "noContent": "暂无内容", "addPromptDesc": "请输入 Prompt 名称和内容,帮助AI更好地理解你的需求。", "promptTitlePlaceholder": "请输入 Prompt 名称", "promptContentPlaceholder": "请输入 Prompt 内容", "promptContent": "Prompt 内容", "optimizePrompt": "优化提示词", "optimizing": "优化中...", "optimizeSuccess": "提示词优化成功", "optimizeFailed": "提示词优化失败,请稍后重试", "noContentToOptimize": "请先输入提示词内容" }, "memories": { "title": "记忆管理", "desc": "AI 长期记忆功能,让 AI 记住你的写作偏好、经验知识和笔记习惯。", "stats": { "total": "总记忆数", "preferences": "偏好", "memories": "记忆" }, "form": { "title": "添加新记忆", "categoryDescription": "记忆分为两种类型:", "preferenceDescription": "偏好:语言、格式、风格等设置,每次对话都会自动加载", "memoryDescription": "记忆:事实、经验、专长等信息,根据对话内容智能匹配", "contentLabel": "记忆内容", "contentPlaceholder": "例如:我喜欢用中文回答、我是React专家...", "categoryLabel": "类型", "preferenceLabel": "偏好", "memoryLabel": "记忆", "preferenceDesc": "语言、格式、风格等", "memoryDesc": "事实、经验、专长等", "save": "保存记忆", "saving": "保存中..." }, "listTitle": "我的记忆", "addMemory": "添加记忆", "empty": "暂无记忆,添加第一条记忆吧!", "emptyHint": "你可以手动添加记忆,或在对话中使用「请记住」「记住这个」等话术让 AI 自动记忆。", "preference": "偏好", "memory": "记忆", "replaced": "已替换", "accessCount": "访问 {count} 次", "tabs": { "all": "全部", "preference": "偏好", "memory": "记忆" }, "success": "成功", "saved": "记忆已保存", "updated": "记忆已更新(已替换相似记忆)", "deleted": "记忆已删除", "cleared": "所有记忆已清空", "found": "找到 {count} 条记忆", "error": "错误", "errorEmpty": "请输入记忆内容", "errorSave": "保存失败", "errorDelete": "删除记忆失败", "errorList": "获取记忆列表失败", "errorEmbedding": "无法生成向量嵌入,请检查嵌入模型配置", "errorClear": "清空记忆失败" }, "defaultModel": { "title": "默认模型", "desc": "在这里,你可以针对不同的场景使用不同的模型,提高效率降低成本。", "tooltip": "使用主要模型", "noModel": "不使用模型", "placeholder": "请选择或搜索模型", "mainModel": "主要模型", "options": { "primaryModel": { "title": "主要模型", "desc": "作为所有场景的主要模型,如果其他对话模型未选择默认模型,则使用此模型。" }, "markDesc": { "title": "记录描述", "desc": "用于处理 OCR 识别后的记录,生成记录描述。" }, "placeholder": { "title": "AI 建议", "desc": "AI 建议提示作用于记录页面 AI 对话 placeholder 内容生成。" }, "completion": { "title": "快速补全", "desc": "用于 Markdown 编辑器的 AI 内联补全,类似 GitHub Copilot,快速生成续写内容。" }, "commit": { "title": "自动生成 commit 信息", "desc": "用于自动生成 Git 提交信息,基于文件内容变化智能生成描述性提交信息。" }, "embedding": { "title": "嵌入模型", "desc": "用于处理文本嵌入和向量化的场景。" }, "reranking": { "title": "重排模型", "desc": "用于搜索结果的重新排序和优化。" }, "condense": { "title": "摘要模型", "desc": "用于压缩历史对话内容,节省 token 使用量" } } }, "audio": { "title": "语音设置", "desc": "在这里,你可以配置语音相关设置,包括文本转语音(朗读)和语音转文本(录音识别)功能。", "mode": { "title": "运行方式", "auto": "自动(推荐)", "local": "仅本地", "model": "仅模型" }, "tts": { "title": "文本转语音(TTS)", "desc": "配置朗读功能,为聊天内容提供语音播放。", "modeDesc": "默认优先使用浏览器和系统自带语音,必要时再使用模型增强体验。", "model": { "title": "朗读模型", "desc": "可选。配置后可在自动模式下作为增强体验或在仅模型模式下使用。" }, "speed": { "title": "语速", "desc": "调整语音播放的速度,范围从0.5倍到2倍速度,默认为1倍正常速度。" } }, "stt": { "title": "语音转文本(STT)", "desc": "配置录音识别功能,将语音转换为文字记录。", "modeDesc": "默认优先使用浏览器原生识别,不支持时再回退到模型识别。", "model": { "title": "识别模型", "desc": "可选。配置后可在自动模式下回退使用,或在仅模型模式下强制使用。" } } }, "readAloud": { "title": "朗读", "desc": "配置文本朗读方式,默认优先使用系统语音,模型作为增强能力。", "options": { "mode": { "title": "运行方式", "desc": "自动模式会优先使用系统语音,不可用时再尝试模型。", "auto": "自动(推荐)", "local": "仅本地", "model": "仅模型" }, "audioModel": { "title": "朗读模型", "desc": "可选。配置后可在自动模式下作为增强体验,或在仅模型模式下使用。" }, "speed": { "title": "语速", "desc": "调整朗读速度,范围从0.5倍到2倍,默认为1倍。" } } }, "about": { "title": "关于", "desc": "一款专注于记录与写作的 AI 笔记。", "version": "NoteGen v{version}", "checkReleases": "查询历史版本", "language": "语言", "checkUpdate": "检查更新", "checkError": "检查更新失败", "updateAvailable": "更新至最新版本", "updateDownloading": "更新中 {downloaded} / {contentLength}", "updateInstalled": "重启应用", "noUpdate": "当前已是最新版本", "ignoreVersion": "忽略此版本", "ignoreVersionSuccess": "已忽略此版本更新", "items": { "home": { "title": "官网", "buttonName": "打开", "desc": "访问官网,了解 NoteGen 的更多信息。" }, "guide": { "title": "配置指南", "buttonName": "打开", "desc": "查看配置指南,了解如何配置模型、同步等信息。" }, "github": { "title": "GitHub", "buttonName": "查看", "desc": "如果 NoteGen 帮助到了你,请给颗 star 鼓励一下!" }, "releases": { "title": "更新日志", "buttonName": "查看", "desc": "查看更新日志,了解 NoteGen 的更新信息。" }, "issues": { "title": "问题反馈", "buttonName": "反馈", "desc": "如果发现 NoteGen 有 bug,请在这里反馈。" }, "discussions": { "title": "交流讨论", "buttonName": "讨论", "desc": "如果你想和作者或其他用户交流,可以加群讨论。" } } }, "sync": { "title": "同步配置", "desc": "在这里,你可以配置同步仓库,它可以帮助你同步记录、markdown 文件、系统配置等信息。", "selectPlatform": "选择同步平台", "platformSettings": "选择平台", "settings": "同步设置", "platformDesc": "配置 Token 和仓库信息以启用同步功能", "moreSettings": "更多设置", "repoStatus": "仓库状态", "syncRepo": "同步仓库", "syncRepoDesc": "同步写作中的 markdown 文件。", "imageRepo": "图床仓库", "imageRepoDesc": "同步你的图片到图床仓库。", "status": { "connected": "已连接", "disconnected": "未连接", "failed": "连接失败", "unconfigured": "未配置" }, "uploadRecords": "上载记录和配置", "downloadConfig": "下载记录和配置", "cloudSync": "记录与配置同步", "localBackupAll": "本地备份(全部)", "private": "私有", "public": "公开", "createdAt": "创建于 {time}", "updatedAt": "最后更新于 {time}", "newToken": "创建 access token", "newTokenDesc": "新建 token 时,请务必勾选 repo 权限,配置后将自动创建文件仓库(私有)和图床仓库。", "giteeTokenDesc": "Gitee 私人令牌用于同步数据,需要有仓库的读写权限,配置后将自动创建文件仓库(私有)和图床仓库。", "imageRepoSetting": "开启图床", "imageRepoSettingDesc": "你已经配置了图床仓库,开启此项将使用图床仓库,否则将使用本地存储。", "jsdelivrSetting": "jsDelivr", "jsdelivrSettingDesc": "使用 jsdelivr 加速图片访问。", "autoSyncDesc": "启用后,编辑器会在输入停止 10 秒后自动同步到 GitHub", "giteeAutoSyncDesc": "启用后,编辑器会在输入停止 10 秒后自动同步到 Gitee", "customSyncRepo": "自定义同步仓库名", "customSyncRepoDesc": "留空则使用默认仓库名", "customImageRepo": "自定义图床仓库名", "customImageRepoDesc": "留空则使用默认仓库名", "backupMethod": "备份方式", "backupMethodDesc": "设置为主要备份方式后,写作中的所有同步相关功能将使用当前备份方式(图床功能除外)", "createRepo": "创建仓库", "creating": "创建中", "checkRepo": "检查仓库", "checking": "检查中", "enterToken": "请输入 Access Token", "enterTokenHint": "请先输入 Access Token 以检查仓库状态", "defaultRepoName": "默认: {name}", "gitlabInstanceType": "GitLab 实例类型", "gitlabInstanceTypeDesc": "选择要连接的 GitLab 实例类型", "gitlabInstanceTypePlaceholder": "选择 GitLab 实例类型", "gitlabInstanceTypeOptions": { "selfHosted": "自建实例", "selfHostedDesc": "输入您的自建 GitLab 服务器地址(如:https://gitlab.example.com)" }, "gitlabAccessTokenDesc": "在 {instanceDisplayName} 创建个人访问令牌,需要 api 权限", "giteaInstanceType": "Gitea 实例类型", "giteaInstanceTypeDesc": "选择要连接的 Gitea 实例类型", "giteaInstanceTypePlaceholder": "选择 Gitea 实例类型", "giteaInstanceTypeOptions": { "selfHosted": "自建实例", "selfHostedDesc": "输入您的自建 Gitea 服务器地址(如:https://gitea.example.com)" }, "giteaAccessTokenDesc": "在 {instanceDisplayName} 创建个人访问令牌,需要完整的 repository 权限", "s3": { "title": "S3 同步", "description": "使用 S3 兼容存储同步你的笔记", "status": "连接状态", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "请输入 Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "请输入 Secret Access Key", "region": "区域", "bucket": "存储桶", "bucketPlaceholder": "请输入存储桶名称", "endpoint": "端点", "pathPrefix": "路径前缀", "pathPrefixPlaceholder": "请输入路径前缀", "pathPrefixDesc": "用于区分不同用户的文件,类似仓库名", "customDomain": "自定义域名", "testConnection": "测试连接", "testing": "测试中", "saveConfig": "保存配置", "saving": "保存中" }, "webdav": { "title": "WebDAV 同步", "description": "使用 WebDAV 协议同步你的笔记", "status": "连接状态", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "url": "服务器地址", "urlPlaceholder": "请输入 WebDAV 服务器地址", "urlDesc": "支持群晖、QNAP、Nextcloud 等 WebDAV 服务", "username": "用户名", "usernamePlaceholder": "请输入用户名", "password": "密码", "passwordPlaceholder": "请输入密码", "pathPrefix": "路径前缀", "pathPrefixPlaceholder": "请输入路径前缀", "pathPrefixDesc": "用于区分不同用户的文件", "testConnection": "测试连接", "testing": "测试中", "saveConfig": "保存配置", "saving": "保存中" }, "autoSync": "自动同步", "autoSyncOptions": { "placeholder": "选择自动同步时间", "disabled": "关闭", "2s": "2 秒", "3s": "3 秒", "5s": "5 秒", "10s": "10 秒", "20s": "20 秒", "30s": "30 秒", "1m": "1 分钟", "2m": "2 分钟" }, "autoPullOnOpen": "打开文件时自动拉取", "autoPullOnOpenDesc": "打开文件时,如果远程有新版本则自动拉取覆盖本地", "autoPullOnSwitch": "切换文件时自动拉取", "autoPullOnSwitchDesc": "切换到其他文件时,如果远程有新版本则自动拉取覆盖本地", "exclusions": { "title": "同步排除配置", "desc": "以下配置项不会在设备间同步,因为它们是设备特定的", "workspacePath": "工作区路径", "workspaceHistory": "工作区历史路径", "assetsPath": "资源路径", "uiScale": "界面缩放", "contentTextScale": "正文文字缩放", "customCss": "自定义 CSS", "reason": "这些配置在不同设备上可能不同,不进行同步可以避免路径错误等问题" }, "settingsSync": { "uploadSuccess": "配置上传成功", "uploadFailed": "配置上传失败", "downloadSuccess": "配置下载成功", "downloadFailed": "配置下载失败", "autoSync": "上传/下载时会自动同步配置(排除工作区路径等设备特定配置)" } }, "imageHosting": { "title": "图床设置", "desc": "在这里,你可以配置图床服务,用于存储和管理你的图片。", "type": "选择平台", "typeDesc": "选择图床服务提供商", "customRepoName": "自定义仓库名", "customRepoNameDesc": "留空则使用默认仓库名", "isPrimaryBackup": "当前 {type} 为主要图床", "setPrimaryBackup": "设为主要图床", "smms": { "token": { "desc": "请创建并输入 SM.MS Token。", "createToken": "创建 Token" }, "disk": "磁盘使用情况", "error": "获取失败,请检查网络或 Token 是否正确。" }, "picgo": { "desc": "PicGo 服务器地址", "ok": "检测到服务正在运行,请确保 PicGo 图床已配置。", "error": "服务未运行,请确保 PicGo(需要 v2.2.0+) 应用正在运行,否则无法上传图片。" }, "github": { "title": "GitHub 图床", "description": "使用 GitHub 仓库作为图片存储服务", "repoStatus": "仓库状态", "repoExists": "仓库已存在", "repoNotExists": "仓库不存在", "checking": "检测中", "creating": "创建中", "manualCreateTitle": "需要手动创建图床仓库", "manualCreateDesc": "请按以下步骤创建图床仓库:", "createSteps": { "step1": "访问 GitHub 并登录您的账户", "step2": "点击右上角的 \"+\" 按钮,选择 \"New repository\"", "step3": "仓库名称设置为:", "step4": "可以选择设置为私有仓库(推荐)", "step5": "点击 \"Create repository\" 完成创建", "step6": "创建完成后,点击下方的\"重新检测\"按钮" }, "createNewRepo": "创建新仓库", "recheckRepo": "重新检测", "recheckingRepo": "检测中..." }, "s3": { "title": "S3 对象存储", "description": "配置 AWS S3 或兼容 S3 协议的对象存储服务作为图床", "status": "连接状态", "connected": "已连接", "connecting": "连接中", "disconnected": "未连接", "accessKeyId": "Access Key ID", "accessKeyIdPlaceholder": "输入 Access Key ID", "secretAccessKey": "Secret Access Key", "secretAccessKeyPlaceholder": "输入 Secret Access Key", "region": "区域", "bucket": "存储桶", "bucketPlaceholder": "输入存储桶名称", "advancedSettings": "高级设置", "endpoint": "自定义端点", "endpointDesc": "留空使用 AWS S3,或输入兼容 S3 的服务端点", "customDomain": "自定义域名", "customDomainDesc": "可选,用于访问图片的自定义域名", "pathPrefix": "路径前缀", "pathPrefixDesc": "可选,图片存储的路径前缀", "save": "保存配置", "test": "测试连接", "setAsPrimary": "设为主要图床", "error": "配置错误", "requiredFields": "请填写必填字段:Access Key ID、Secret Access Key、区域和存储桶", "saveSuccess": "配置保存成功", "saveSuccessDesc": "S3 配置已保存", "saveError": "配置保存失败", "testSuccess": "连接测试成功", "testSuccessDesc": "S3 连接正常,可以上传图片", "testFailed": "连接测试失败", "testFailedDesc": "请检查配置信息和网络连接", "testFirstDesc": "请先测试连接成功后再设为主要图床", "setPrimarySuccess": "设置成功", "setPrimarySuccessDesc": "S3 已设为主要图床" } }, "backupSync": { "title": "备用方案", "desc": "在这里,你可以使用其他方案来备份你的数据,你可以定期进行备份,以确保数据的安全。", "localBackup": { "tabTitle": "本地备份", "export": { "title": "导出备份", "desc": "将应用数据打包为 .zip 文件,保存到指定位置。", "button": "选择位置并导出", "simpleButton": "导出", "exporting": "导出中..." }, "import": { "title": "导入备份", "desc": "从 .zip 文件恢复应用数据,将覆盖当前所有数据。", "button": "选择文件并导入", "importing": "导入中...", "warning": "导入操作将覆盖所有当前数据,请确保已备份重要内容!" }, "exportDialog": { "title": "选择备份文件保存位置" }, "importDialog": { "title": "选择要导入的备份文件" }, "exportSuccess": "备份导出成功!", "exportError": "备份导出失败", "importSuccess": "备份导入成功!应用将重启以应用更改。", "importError": "备份导入失败", "restartConfirm": "导入完成!是否立即重启应用以应用更改?" } }, "template": { "title": "整理模板", "desc": "在这里,你可以创建和管理自定义整理模板,帮助 AI 按照你的需求整理记录内容。", "customTemplate": "自定义模板", "addTemplate": "新增模板", "deleteConfirm": "确认删除模板吗?", "status": "状态", "name": "名称", "content": "内容", "scope": "范围", "selectScope": "选择范围", "addTemplateDesc": "请输入自定义模板名称和内容,帮助 AI 更好地理解你的需求。", "editTemplate": "编辑自定义模板", "noContent": "暂无内容", "range": { "all": "全部", "today": "今天", "week": "近一周", "month": "近一月", "threeMonth": "近三个月", "year": "近一年" } }, "shortcut": { "title": "快捷键", "screenshot": "截图记录", "link": "链接记录", "textRecord": "文本记录", "windowPin": "窗口置顶" }, "theme": { "title": "外观", "appTheme": "应用配色", "previewTheme": "预览内容主题", "codeTheme": "代码块高亮主题", "selectTheme": "选择主题" }, "dev": { "title": "开发者", "desc": "在这里,你可以配置开发者选项,包括网络代理、数据清理和配置文件管理等高级功能。", "clearData": "清理数据", "clearDataConfirm": "确定清理数据吗?", "proxy": "代理,用于解决网络问题,配置后建议重启应用。", "proxyPlaceholder": "请输入代理地址", "proxyTitle": "网络代理", "clearDataTitle": "清理数据", "clearDataDesc": "清理数据信息,包括系统配置信息、数据库(包含记录)。", "clearFileTitle": "清理文件", "clearFileDesc": "清理文件,包括图片、文章。", "clearButton": "清理", "configFileTitle": "配置文件管理", "configFileDesc": "配置文件导入与导出,导入配置文件将覆盖当前配置,并且重启后生效。", "importConfigTitle": "导入配置文件", "exportConfigTitle": "导出配置文件", "importConfigSuccessMobile": "配置下载成功,请手动重启应用", "exportConfigSuccess": "导出成功", "importButton": "导入", "exportButton": "导出" }, "chat": { "title": "对话设置", "desc": "在这里,你可以配置对话相关的设置,包括摘要生成等功能。", "primaryModel": { "title": "主要模型", "model": { "title": "主要聊天模型", "desc": "选择用于日常对话的主要 AI 模型" } }, "toolbar": { "title": "工具栏设置", "chatToolbar": { "title": "对话工具栏", "desc": "自定义对话工具栏按钮的显示顺序和可见性", "button": "设置", "modelSelect": { "desc": "切换用于对话的 AI 模型" }, "promptSelect": { "desc": "选择对话使用的预设提示词" }, "chatLanguage": { "desc": "设置对话的语言" }, "chatLink": { "title": "关联标签", "desc": "关联当前标签的笔记内容到对话上下文" }, "fileLink": { "desc": "关联文件或文件夹到对话上下文" }, "mcpButton": { "desc": "选择并连接 MCP 服务器以使用外部工具" }, "ragSwitch": { "title": "知识库检索", "desc": "启用向量知识库检索功能" }, "clipboardMonitor": { "title": "剪贴板监听", "desc": "自动监听剪贴板内容变化" }, "newChat": { "desc": "开始新对话" }, "clearContext": { "desc": "清除对话上下文,保留聊天记录" }, "clearChat": { "desc": "删除所有聊天记录" } } }, "condense": { "title": "对话摘要", "enable": { "title": "启用摘要", "desc": "自动压缩长对话以节省 token 使用量" }, "model": { "title": "摘要模型", "desc": "选择用于生成摘要的 AI 模型", "placeholder": "使用主模型" }, "threshold": { "title": "触发阈值", "desc": "AI 消息超过此数量时检查压缩" }, "minToken": { "title": "最小 Token 数", "desc": "单条消息超过此 token 数才进行压缩" }, "keepLatest": { "title": "保留最新条数", "desc": "保留最新的 N 条 AI 消息不进行压缩" }, "maxLength": { "title": "摘要长度限制", "desc": "控制生成摘要的最大字数" }, "prompt": { "title": "自定义摘要提示词", "desc": "自定义生成摘要时使用的提示词模板", "label": "提示词模板", "placeholder": "输入自定义提示词...", "help": "使用 {content} 作为原始内容的占位符", "save": "保存", "reset": "重置为默认" } }, "conversationTitle": { "title": "会话标题", "model": { "title": "标题生成模型", "desc": "选择用于生成会话标题的 AI 模型" } }, "inspiration": { "title": "灵感模型", "model": { "title": "灵感生成模型", "desc": "用于生成快速提示词建议,帮助用户快速开始对话" } } }, "ai": { "title": "模型配置", "desc": "在这里,你可以添加和管理各种自定义模型提供服务,配置后将解锁 AI 相关功能,例如整理和对话功能。", "modelTitle": "自定义名称", "modelConfigTitle": "模型配置", "modelConfigDesc": "每一个配置对应一个 AI 模型,你可以通过模板或自定义创建新的配置。", "providerInfo": "供应商信息", "providerInfoDesc": "此配置基于供应商模板创建,名称和地址已预设,无需修改。", "create": "创建新配置", "createDesc": "选择空配置或使用供应商模板创建新的配置。", "createSection": { "title": "自定义模型配置", "descWithoutModels": "添加自定义 AI 模型配置来使用更强大的模型服务。" }, "config": "配置单", "custom": "自定义模型配置", "addCustomModel": "自定义", "deleteCustomModel": "删除", "deleteCustomModelConfirm": "确认删除此自定义模型配置吗?", "copyConfig": "复制", "builtin": "内置", "modelSupport": "仅支持 openai 协议的 AI 模型", "apiKeyUrl": "创建 API Key", "modelType": { "title": "模型类型", "desc": "根据 AI 模型能力选择模型类型,用以调用不同的接口。", "chat": "对话", "image": "生图", "video": "视频", "tts": "文本转语音", "stt": "语音转文本", "embedding": "嵌入", "rerank": "重排序" }, "modelList": { "error": { "title": "获取模型列表失败", "description": "请检查 API Key 或网络是否正确" } }, "selectModel": "请选择模型", "modelProviderDesc": "自定义模型仅支持 openai 协议的 AI 模型。", "modelTitleDesc": "自定义名称,用于标识 AI 模型,请勿重复。", "modelBaseUrlDesc": "你只需要配置到版本号即可,例如:https://api.openai.com/v1,后缀会自动添加。", "modelDesc": "部分模型支持获取模型列表,如果不支持请手动配置。", "temperatureDesc": "使用什么采样温度,介于 0 和 2 之间。较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使输出更加集中和确定。 我们通常建议改变这个或top_p但不是两者。", "topPDesc": "一种替代温度采样的方法,称为核采样,其中模型考虑具有 top_p 概率质量的标记的结果。所以 0.1 意味着只考虑构成前 10% 概率质量的标记。 我们通常建议改变这个或temperature但不是两者。", "customHeaders": "自定义请求头", "customHeadersDesc": "添加自定义 HTTP 请求头,支持多个键值对配置。", "headerKey": "键", "headerValue": "值", "addHeader": "添加 Header", "connectionSuccess": "AI 连接测试通过", "connectionFailed": "连接失败", "voice": "语音类型", "voiceDesc": "指定音频模型使用的语音类型,如 'alloy'、'echo'、'fable' 等。", "voicePlaceholder": "请输入语音类型,如:alloy", "enableStream": "流式响应", "enableStreamDesc": "启用流式响应可以实时显示生成内容,但某些模型可能不支持此功能。", "selectConfig": "请选择配置", "models": "模型列表", "modelsDesc": "在这里管理当前配置下的所有模型,每个模型可以有不同的类型和参数。", "addModel": "添加模型", "newModel": "新模型", "checkConnection": "检测连接", "model": "模型", "defaultModels": { "title": "默认免费模型", "desc": "NoteGen 为用户提供免费的 AI 模型服务,由硅基流动提供支持,无需配置即可使用基础功能。", "chatModel": { "name": "Qwen/Qwen3-8B", "type": "对话模型", "desc": "适用于日常对话、文本生成等场景" }, "embeddingModel": { "name": "BAAI/bge-m3", "type": "嵌入模型", "desc": "用于文本向量化、语义搜索等功能" }, "visionModel": { "name": "OpenGVLab/InternVL2-8B", "type": "视觉模型", "desc": "支持图像理解、视觉问答等功能" }, "completionModel": { "name": "快速补全", "type": "补全模型", "desc": "用于 Markdown 编辑器的 AI 内联补全,类似 GitHub Copilot,快速生成续写内容" }, "poweredBy": "由 SiliconFlow 提供技术支持" } }, "imageMethod": { "title": "图像识别", "desc": "在这里,你可以配置图像识别相关设置,支持 OCR 和 VLM 两种方式。", "enable": { "title": "启用图像识别", "desc": "开启后,在截图记录和插图记录时会自动进行图片识别。关闭后将跳过图片识别步骤。" }, "setPrimary": "设置为默认", "isPrimary": "{type} 已设置为默认", "ocr": { "title": "OCR", "languagePacks": "语言包", "checkModels": "在此查询全部模型", "modelInstruction": "以逗号分隔,例如:eng,chi_sim" }, "vlm": { "title": "视觉语言模型", "desc": "通过视觉语言模型识别图片内容。" } }, "file": { "title": "文件管理", "desc": "在这里,你可以管理工作区设置和其他文件相关选项。", "workspace": { "title": "工作区设置", "desc": "设置应用程序的工作区目录,文件将保存在该目录中。", "current": "工作区路径", "defaultPath": "默认工作区", "default": "当前使用默认工作区路径。", "custom": "当前使用自定义工作区路径。", "select": "选择工作区目录", "reset": "重置为默认路径", "history": "历史路径", "selectFromHistory": "从历史记录中选择工作区", "clearHistory": "清空历史记录", "actions": "操作", "searchPlaceholder": "搜索工作区路径...", "noResults": "未找到结果" }, "info": { "title": "工作区说明", "desc": "更改工作区后需要重启应用程序才能完全生效。新工作区中的文件将在重启后显示。" }, "toast": { "updated": "工作区已更新", "updatedDesc": "工作区已设置为: {path}", "reset": "工作区已重置", "resetDesc": "已恢复使用默认工作区", "error": "选择工作区失败", "errorDesc": "无法选择工作区目录,请重试", "resetError": "重置工作区失败", "resetErrorDesc": "无法重置为默认工作区,请重试" }, "assets": { "title": "写作资源路径", "desc": "设置写作资源的保存路径,例如图片、视频、文件等,与当前编辑的 markdown 文件同级。", "select": "请设置写作资源路径,例如:assets" } }, "shortcuts": { "title": "快捷键", "desc": "在这里,你可以配置快捷键,帮助你更高效地使用 NoteGen。", "resetDefaults": "重置", "clear": "清空", "noShortcut": "未设置", "shortcuts": { "openWindow": { "title": "打开/隐藏窗口", "desc": "打开/隐藏程序主窗口。" }, "quickRecordText": { "title": "快速记录文本", "desc": "快速打开程序主窗口,并调出文本记录。" } } } }, "record": { "trash": { "title": "清空回收站", "confirm": "确定清空回收站吗?", "records": "共 {count} 条记录可还原", "empty": "清空", "restoreAll": "全部还原", "close": "关闭回收站" }, "queue": { "ocr": "OCR 识别", "ai": "AI 内容识别", "upload": "上传至图床", "jsdelivr": "通知 jsdelivr 缓存", "save": "保存", "recording": "记录中...", "recorded": "已记录", "record": "记录", "detected": "检测到" }, "mark": { "empty": "暂无记录", "loading": "加载中...", "type": { "scan": "截图", "image": "插图", "screenshot": "截图", "text": "文本", "recording": "录音", "file": "文件", "link": "链接", "todo": "待办", "pdf": "PDF", "upload": "上传记录", "download": "下载记录", "uploadTo": "从本地同步到 {provider}", "downloadFrom": "从 {provider} 同步到本地" }, "note": { "organizeAs": "整理为", "template": "模板", "setting": "设置", "confirm": "确认", "cancel": "取消", "removeThinking": "移除思考过程", "stop": "停止" }, "uploadSuccess": "记录上传成功", "downloadSuccess": "记录下载成功", "desc": "描述", "content": "内容", "createdAt": "创建于", "progress": { "cacheImage": "缓存图片", "ocr": "OCR 识别", "aiAnalysis": "AI 内容识别", "uploadImage": "上传至图床", "jsdelivrCache": "通知 jsdelivr 缓存", "cacheFile": "缓存文件", "cacheScreenshot": "缓存截图", "textAnalysis": "文本分析", "save": "保存", "saveImage": "保存图片" }, "imageGallery": { "expand": "展开", "collapse": "收起" }, "text": { "title": "记录文本", "description": "记录一段文本,笔记整理时将插入到合适的位置。", "characterCount": "{count} 字符", "save": "记录", "autoReadClipboard": "自动读取剪贴板文本" }, "link": { "title": "链接记录", "description": "输入网页链接,系统将自动爬取页面内容并保存", "save": "保存", "autoReadClipboard": "自动读取剪贴板链接" }, "todo": { "title": "待办记录", "description": "创建待办事项,管理你的任务", "titlePlaceholder": "输入待办标题...", "descriptionPlaceholder": "输入详细描述(可选)", "priority": "优先级", "priorityLow": "低", "priorityMedium": "中", "priorityHigh": "高", "dateRange": "日期范围", "dateRangePlaceholder": "选择日期范围", "dueDate": "截止日期", "dueDatePlaceholder": "选择日期", "save": "创建待办", "saveEdit": "保存", "edit": "编辑待办", "editDescription": "修改待办事项的详细信息", "cancel": "取消", "selectTag": "选择标签", "completed": "已完成", "uncompleted": "未完成" }, "clipboard": { "detectedImage": "检测到剪贴板图片", "detectedText": "检测到剪贴板文本" }, "tag": { "searchPlaceholder": "创建或查询标签...", "noResults": "未查询到相关标签", "quickAdd": "快速创建", "pinned": "置顶", "others": "其他", "rename": "重命名", "delete": "删除", "pin": "置顶", "unpin": "取消置顶", "newTag": "新建标签", "newTagPlaceholder": "输入标签名称...", "add": "添加" }, "mark": { "empty": "暂无记录", "emptyHint": "使用顶部工具栏开始你的第一条记录吧!", "type": { "text": "文本" }, "chat": { "modeSelect": { "chat": "对话", "agent": "智能体" }, "agent": { "running": "Agent 运行中", "thinking": "思考中", "acting": "执行中", "observation": "观察结果", "thought": "思考", "action": "行动", "toolCalls": "工具调用", "confirmation": { "title": "确认操作", "description": "Agent 想要执行以下操作,请确认后继续。", "tool": "工具", "parameters": "参数", "confirm": "确认", "cancel": "取消", "confirmed": "已确认", "cancelled": "已取消" } }, "placeholder": { "default": "你可以提问或将记录整理为文章...", "noApiKey": "未配置 API Key,无法使用 AI 对话功能...", "on": "AI建议开启", "off": "AI建议关闭" }, "header": { "configApiKey": "配置 API KEY", "clearChat": "清空对话", "configPrompt": "配置 Prompt", "selectPrompt": "选择 Prompt" }, "clipboard": { "image": { "detected": "检测到剪贴板存在图片:", "recording": "正在记录", "recorded": "已记录", "record": "记录" }, "text": { "detected": "检测到剪贴板存在文本:", "recorded": "已记录", "record": "记录" } }, "messageControl": { "words": "字", "summary": "摘要" }, "mcp": { "maxIterationsReached": "达到最大工具调用次数限制", "toolCall": "MCP 服务器", "params": "参数", "result": "返回结果", "copy": "复制", "paramsCopied": "参数已复制", "resultCopied": "结果已复制", "calling": "调用中", "success": "已完成", "error": "失败" }, "empty": { "title": "开始与 AI 对话", "subtitle": "使用 Chat 或 Agent 模式与 AI 互动", "currentModel": "当前模型", "currentPrompt": "当前 Prompt", "noModel": "未设置模型", "noPrompt": "未设置 Prompt", "modeHint": "点击输入框左侧的", "modeHintSuffix": "按钮可切换对话模式" }, "content": { "organize": "将你的记录整理为文章:" }, "note": { "writing": "写作", "convert": "转化文章", "description": "当前的笔记是由 AI 生成且无法编辑,将当前笔记转化为文章(生成本地文件),可在写作页面中进行二次创作。", "filename": "文件名", "selectFolder": "选择文件夹", "rootDirectory": "根目录", "deleteTag": "删除当前标签、记录和笔记(回收站可恢复)", "warning": "转换后将跳转到写作页面。", "convert_button": "转化" }, "mark": { "recorded": "已记录", "record": "记录" }, "send": "发送" }, "text": { "title": "记录文本", "description": "记录一段文本,笔记整理时将插入到合适的位置。", "characterCount": "{count} 字符", "save": "记录" }, "clipboard": { "detectedImage": "检测到剪贴板图片", "detectedText": "检测到剪贴板文本" }, "tag": { "searchPlaceholder": "创建或查询标签...", "noResults": "未查询到相关标签", "quickAdd": "快速创建", "pinned": "置顶", "others": "其他", "rename": "重命名", "delete": "删除", "pin": "置顶", "unpin": "取消置顶" }, "progress": { "cacheImage": "缓存图片", "ocr": "OCR 识别", "aiAnalysis": "AI 内容识别", "uploadImage": "上传至图床", "jsdelivrCache": "通知 jsdelivr 缓存", "cacheFile": "缓存文件", "cacheScreenshot": "缓存截图", "textAnalysis": "文本分析", "save": "保存", "saveImage": "保存图片" } }, "toolbar": { "search": "搜索", "filter": { "title": "筛选", "description": "按内容、时间和类型即时过滤记录。", "search": "搜索", "searchPlaceholder": "搜索记录内容、描述或链接", "type": "类型", "time": "时间", "tag": "标签", "allTags": "全部标签", "clear": "清空筛选", "selectAllTypes": "选择全部类型", "clearTypes": "清空类型选择", "timeOptions": { "all": "全部时间", "today": "今天", "last7Days": "最近7天", "last30Days": "最近30天" } }, "trash": "回收站", "closeTrash": "关闭回收站", "organizeNotes": "整理笔记", "organizeSuccess": "笔记整理成功:{title}", "organizeError": "整理笔记失败", "currentTag": "当前标签", "restore": "还原", "delete": "删除", "deleteConfirm": "确定要删除吗?", "moveTag": "转移标签", "convertTo": "转换为{type}", "copyLink": "复制链接", "copied": "已复制到剪切板!", "regenerateDesc": "重新生成描述", "viewFolder": "查看目录", "viewFile": "查看原文件", "deleteForever": "彻底删除", "multiSelect": "多选", "exitMultiSelect": "退出多选", "selectAll": "全选", "deselectAll": "取消全选", "selectedCount": "已选择 {count} 项", "visibleCount": "共 {count} 条记录", "moveSelectedTags": "转移选中的 {count} 项", "deleteSelected": "删除选中的 {count} 项", "deleteSelectedForever": "彻底删除选中的 {count} 项", "view": { "list": "列表视图", "compact": "紧凑视图", "cards": "卡片视图" }, "text": "记录文本", "recording": "录音记录", "scan": "扫描图片", "image": "上传图片", "link": "记录链接", "file": "上传文件", "todo": "待办记录" }, "list": { "title": "记录", "emptyFiltered": "没有符合条件的记录", "emptyFilteredHint": "试试调整搜索词或筛选条件", "filteredLabel": "已筛选 {count} 条", "filtered": "已筛选", "filteredByTag": "标签", "filteredByType": "{count} 种类型", "filteredSummary": "当前显示 {count} 条结果 · {filters}", "searchChip": "搜索: {value}", "time": { "today": "今天", "last7Days": "最近7天", "last30Days": "最近30天" } } }, "chat": { "condensing": "正在压缩上下文...", "condensed": { "message": "已压缩 {count} 条历史消息" }, "empty": { "title": "开始与 AI 对话", "subtitle": "使用 Chat 或 Agent 模式与 AI 互动", "currentModel": "当前模型", "currentPrompt": "当前 Prompt", "currentMode": "对话模式", "noModel": "未设置模型", "noPrompt": "未设置 Prompt", "configureModel": "配置模型", "recentConversations": "最近对话", "deleteConversation": "删除对话", "conversationHistory": "历史对话", "viewMore": "查看更多", "messages": "条消息", "searchPlaceholder": "搜索对话...", "noMatchingConversations": "没有找到匹配的对话", "noConversationHistory": "暂无历史对话", "quickPrompts": { "title": "快速开始", "writeNote": "帮我写一篇笔记", "summarize": "帮我总结这段内容", "brainstorm": "帮我头脑风暴一些想法", "explain": "帮我解释这个概念" } }, "newChat": "使用新标签开始对话", "removeChat": "删除当前标签对话", "confirmNew": "创建新标签", "confirmNewDescription": "请确认要创建一个新的标签开始对话吗?", "confirmRemove": "删除标签", "confirmRemoveDescription": "请注意,删除此标签会连带删除内部的记录,请再次确认。", "input": { "organize": "整理", "chat": "聊天", "placeholder": { "default": "你可以提问或将记录整理为文章...", "noApiKey": "未配置 API Key,无法使用 AI 对话功能...", "on": "AI 建议 (开启)", "off": "AI 建议 (关闭)", "noPrimaryModel": "未配置主模型,无法使用 AI 对话功能..." }, "translate": { "tooltip": "翻译", "translating": "翻译中...", "showOriginal": "显示原文", "alreadyTranslated": "已翻译为" }, "clipboardMonitor": { "enable": "剪贴板监听(开启)", "disable": "剪贴板监听(关闭)" }, "send": "发送", "stop": "停止", "stopped": "对话已终止", "terminate": "终止", "tagLink": { "on": "已关联标签", "off": "未关联标签" }, "mcp": { "tooltip": "MCP 服务器" }, "modelSelect": { "tooltip": "选择 AI 模型", "placeholder": "搜索 AI 模型", "noModel": "未找到模型" }, "promptSelect": { "tooltip": "选择 Prompt", "placeholder": "搜索 Prompt" }, "newChat": "开始新对话", "chatLanguage": { "tooltip": "选择对话语言", "placeholder": "搜索语言" }, "rag": { "notSupported": "向量模型不可用", "enabled": "知识库检索(开启)", "disabled": "知识库检索(关闭)" }, "modeSelect": { "tooltip": "选择输入模式", "chat": "对话模式", "gen": "整理模式", "translate": "翻译模式" }, "chatModeSelect": { "chatDescription": "快速对话,分析优先", "agentDescription": "智能助手,可执行操作" }, "attachImage": "附加图片", "imageSelector": { "title": "选择图片", "local": "本地文件", "records": "从记录中选择", "selectFiles": "选择本地图片", "noRecords": "没有可用的图片记录", "cancel": "取消", "confirm": "确认" }, "agent": { "running": "Agent 运行中", "thinking": "思考中", "analyzingRequest": "Agent 正在分析您的请求...", "acting": "执行中", "observation": "观察结果", "thought": "思考", "action": "行动", "toolCalls": "工具调用", "autoFinal": { "createNote": "已创建笔记《{name}》。", "createFile": "已创建文件《{name}》。" }, "confirmation": { "title": "确认操作", "description": "Agent 想要执行以下操作,请确认后继续。", "tool": "工具", "parameters": "参数", "cancel": "取消", "confirm": "确认", "confirmed": "已确认", "cancelled": "已取消", "fallback": { "title": "即将执行操作", "description": "请确认这次操作的目标和内容。" }, "params": { "filePath": "文件路径", "content": "文件内容", "sourcePath": "来源路径", "targetPath": "目标路径", "files": "文件列表", "newName": "新名称", "scriptName": "脚本名称", "command": "命令" }, "tools": { "create_file": { "title": "创建文件", "description": "将在工作区中新建一个文件。" }, "create_files_batch": { "title": "批量创建文件", "description": "将在工作区中一次创建多个文件。" }, "rename_file": { "title": "重命名文件", "description": "将修改所选文件的名称。" }, "move_file": { "title": "移动文件", "description": "将把文件移动到新的位置。" }, "copy_file": { "title": "复制文件", "description": "将在目标位置创建该文件的副本。" }, "replace_editor_content": { "title": "替换编辑器内容", "description": "将用新内容替换当前编辑器内容。" }, "insert_at_cursor": { "title": "在光标处插入内容", "description": "会把内容插入到当前光标位置。" }, "delete_markdown_file": { "title": "删除文件", "description": "将永久删除所选文件。" }, "execute_skill_script": { "title": "运行脚本", "description": "将执行由 skill 提供的脚本或命令。" } } } }, "fileLink": { "tooltip": "关联文件", "selectFile": "选择文件", "linkedFile": "关联文件", "searchPlaceholder": "搜索文件...", "noFiles": "未找到文件", "loading": "加载中..." } }, "header": { "configApiKey": "配置 API KEY", "clearChat": "清空聊天", "configPrompt": "配置 Prompt", "selectPrompt": "选择 Prompt", "noModel": "未选择 AI 模型" }, "clipboard": { "image": { "detected": "检测到剪贴板存在图片:", "recording": "正在记录", "recorded": "已记录", "record": "记录" }, "text": { "detected": "检测到剪贴板存在文本:", "recorded": "已记录", "record": "记录" } }, "messageControl": { "words": "字", "summary": "摘要", "readAloud": "朗读", "playing": "播放中", "loading": "准备中", "stop": "停止播放", "copy": "复制", "copied": "已复制" }, "ragSources": { "label": "知识库检索到 {count} 篇笔记", "openFile": "打开文件" }, "preview": { "close": "关闭", "copy": "复制", "copied": "已复制!" }, "control": { "edit": "编辑", "save": "保存", "cancel": "取消", "delete": "删除", "deleteConfirm": "确定要删除这条消息吗?" }, "content": { "organize": "将你的记录整理为文章:" }, "quote": { "lineSingle": "引用自 {fileName} 第 {line} 行", "lineRange": "引用自 {fileName} 第 {startLine}-{endLine} 行", "noLine": "引用自 {fileName}" }, "note": { "organize": "整理", "writing": "写作", "convert": "转化文章", "description": "当前的笔记是由 AI 生成且无法编辑,将当前笔记转化为文章(生成本地文件),可在写作页面中进行二次创作。", "filename": "文件名", "selectFolder": "选择文件夹", "rootDirectory": "根目录", "deleteTag": "删除当前标签、记录和笔记(回收站可恢复)", "warning": "转换后将跳转到写作页面。", "convert_button": "转化", "organizeAs": "将记录整理成...", "templateContent": "模板内容", "recordRange": "记录选择范围", "filterThinkingContent": "移除记录中的思考", "startOrganize": "开始整理", "manageTemplate": "管理模板", "cancel": "取消", "stop": "停止" }, "mark": { "recorded": "已记录", "record": "记录" } }, "tag": { "add": "添加标签", "edit": "编辑标签", "delete": "删除标签", "deleteConfirm": "确定要删除这个标签吗?", "placeholder": "输入标签名称" } }, "search": { "placeholder": "搜索笔记和文章...", "results": "{count} 个搜索结果", "noResults": "暂无搜索结果", "tryDifferentKeywords": "尝试使用不同的关键词搜索", "item": { "record": "记录", "article": "文章", "matches": "{count}个匹配项", "scanType": "截图" } }, "image": { "root": "图床仓库", "noData": { "title": "同步功能未开启", "desc": "请先跳转至系统设置页面,配置 Github 同步。", "goToSettings": "前往设置", "howToUse": "如何使用同步功能?" } }, "navigation": { "chat": "对话", "record": "记录", "quickRecord": "快捷记录", "write": "写作", "search": "搜索", "githubImageHosting": "Github 图床", "login": "登录", "loading": "载入中", "view": "查看", "logout": "登出", "setting": "设置", "activity": "活跃度", "files": "笔记", "outline": "大纲", "showLeftSidebar": "显示左侧边栏", "hideLeftSidebar": "隐藏左侧边栏", "showCenterPanel": "显示编辑器", "hideCenterPanel": "隐藏编辑器", "showRightSidebar": "显示右侧边栏", "hideRightSidebar": "隐藏右侧边栏", "searchPlaceholder": "搜索笔记或记录..." }, "activity": { "title": "活跃度日历", "description": "按天查看你的记录、对话和写作活跃情况。第一版基于现有记录、用户对话和笔记修改时间进行统计。", "drawer": { "title": "活跃度", "description": "快速查看今天状态和最近一段时间的活跃趋势。", "today": "今天" }, "loading": "正在加载活跃度数据...", "empty": "暂无活跃度数据", "refresh": "刷新", "summary": { "totalCount": "总活跃次数", "activeDays": "活跃天数", "records": "记录次数", "chats": "对话次数", "writing": "写作活跃" }, "labels": { "record": "记录", "writing": "写作", "chat": "对话" }, "heatmap": { "title": "最近 26 周热力图", "range": "{startDate} - {endDate}", "less": "少", "more": "多", "dayCount": "次活动", "emptyDay": "无活动" }, "detail": { "title": "当天明细", "empty": "选择一个日期查看当天的活动明细。" } }, "marks": { "types": { "screenshot": "截图", "text": "文本", "image": "插图" } }, "tags": { "inspiration": "灵感" }, "sync": { "status": "同步仓库状态", "imageRepo": "图床仓库", "articleRepo": "文章仓库" }, "ai": { "thinking": "思考", "error": { "title": "AI 错误", "noAddress": "请先设置 AI 地址" } }, "article": { "sync": { "syncingRemote": "正在拉取远程文件...", "syncComplete": "同步完成" }, "syncConfirm": { "title": "检测到远程文件更新", "description": "文件 {fileName} 有远程更新", "commitInfo": "最新提交信息", "commitMessage": "提交消息", "author": "作者", "changes": "变更", "confirmMessage": "确认要拉取远程版本并覆盖本地文件吗?此操作无法撤销。", "cancel": "取消", "confirmPull": "确认拉取" }, "emptyState": { "title": "开始创作", "subtitle": "选择一个文件开始编辑,或创建新的笔记", "tip": "💡 提示:你也可以从左侧文件管理器中选择文件", "actions": { "newNote": { "title": "创建笔记", "desc": "新建一篇 Markdown 笔记" }, "newRecord": { "title": "创建记录", "desc": "打开文本记录功能" }, "globalSearch": { "title": "全局搜索", "desc": "快速查找你的笔记内容" }, "openWorkspace": { "title": "打开工作区", "desc": "选择或切换工作区目录" } }, "onboarding": { "title": "新手引导", "subtitle": "跟着这三步体验 NoteGen 的核心工作流。", "dismiss": "跳过新手引导", "reopen": "重新显示新手引导", "start": "开始引导", "viewHint": "查看提示", "continue": "继续下一步", "completed": "已完成", "allDone": "新手任务已全部完成,你已经体验了 NoteGen 的基础工作流。", "stepLabel": "任务 ({current}/{total})", "stepCompletedLabel": "已完成任务 ({current}/{total})", "afterOrganizeDialog": { "title": "已完成任务 (2/3)", "description": "你已经把记录整理成了一篇笔记。要继续体验下一步,用 AI Agent 把这篇笔记翻译成双语版本吗?", "confirm": "继续下一步", "cancel": "暂时不用" }, "agentPrompt": { "label": "示例提示词", "use": "使用这条提示词", "intro": "请将我刚刚整理出的这篇笔记直接修改为中英双语版本。", "requirement1": "", "requirement2": "", "requirement3": "", "requirement4": "", "outro": "" }, "steps": { "createRecord": { "title": "创建第一条记录", "desc": "先记录一段示例内容,熟悉记录入口。" }, "organizeNote": { "title": "整理成笔记", "desc": "把刚才的记录整理成一篇正式笔记。" }, "aiPolish": { "title": "用 Agent 翻译成双语", "desc": "用 AI Agent 将刚整理好的笔记翻译成双语版本。" } }, "completedStates": { "create-record": { "title": "你已经创建了第一条记录", "desc": "现在你已经知道如何快速记录内容了。" }, "organize-note": { "title": "你已经把记录整理成笔记", "desc": "下一步可以体验 AI 如何继续修改这篇笔记。" }, "ai-polish": { "title": "你已经用 Agent 处理了笔记", "desc": "你已经体验了从记录到整理,再到 Agent 处理内容的完整流程。" } }, "spotlight": { "create-record": { "title": "这里可以快速记录内容", "desc": "点击这个文本记录入口,系统会自动带入一段示例内容,你也可以自己改。" }, "organize-note": { "title": "这里可以整理记录", "desc": "点击这个按钮,把刚才的记录整理成一篇正式笔记。" }, "ai-polish": { "title": "这里可以用 Agent 处理刚生成的笔记", "desc": "把示例提示词填进对话框后发送,Agent 会基于当前笔记生成双语版本。" } } } }, "unsupportedFile": { "title": "无法预览此文件", "fileName": "文件名", "filePath": "文件路径", "fileSize": "文件大小", "modifiedTime": "修改时间", "createdTime": "创建时间", "pathCopied": "路径已复制", "openExternal": "用外部程序打开", "openDirectory": "打开文件目录" }, "file": { "toolbar": { "accessRepo": "访问仓库", "loadingSync": "正在加载同步信息", "configSync": "配置同步", "newArticle": "新建文章", "newFolder": "新建文件夹", "refresh": "刷新", "toggleFolders": "文件夹展开折叠", "expandAll": "全部展开", "collapseAll": "全部折叠", "sortByName": "按名称排序", "sortByCreated": "按创建时间排序", "sortByModified": "按修改时间排序", "sortAsc": "升序排列", "sortDesc": "降序排列", "sort": "排序", "hideCloudFiles": "隐藏云端文件", "showCloudFiles": "显示云端文件", "processingVectors": "正在处理向量数据", "calculateVectors": "知识库计算(全量)", "importMarkdown": "导入", "importing": "正在导入...", "importSuccess": "导入成功", "importSuccessDesc": "成功导入 {count} 个文件", "importError": "导入失败" }, "sync": { "syncingRemote": "正在拉取远程文件", "syncComplete": "同步完成", "pullingRemote": "正在从远程服务器获取最新内容...", "pullComplete": "拉取完成" }, "context": { "viewDirectory": "查看目录", "cut": "剪切", "copy": "复制", "paste": "粘贴", "rename": "重命名", "deleteSyncFile": "删除同步文件", "deleteLocalFile": "删除本地文件", "delete": "删除", "confirmDelete": "确定要删除文件夹 \"{name}\" 吗?此操作将删除文件夹及其所有内容。", "deleteSuccess": "删除成功", "deleteFailed": "删除失败", "newFile": "新建文件", "newFolder": "新建文件夹", "syncFolder": "同步", "syncFolderDesc": "同步当前文件夹下的所有 Markdown 文件", "syncFolderSuccess": "文件夹同步成功", "syncFolderError": "文件夹同步失败", "syncFolderProgress": "正在同步文件夹...", "deleteSyncFileSuccess": "删除成功", "deleteSyncFileError": "删除失败", "knowledgeBase": "知识库", "calculateVectors": "计算向量", "updateVectors": "更新向量", "deleteVectors": "删除向量", "includeInKB": "包含在知识库", "includeInKBFile": "包含在知识库中", "autoVectorCalc": "自动向量计算", "vectorCalculated": "向量已更新", "vectorCalcCompleted": "向量计算完成", "vectorCalcFailed": "向量计算失败", "vectorDeleted": "向量已删除", "vectorDeleteFailed": "删除向量失败", "batchCalcSuccess": "成功计算 {count} 个文件的向量", "batchCalcPartial": "计算完成:成功 {success} 个,失败 {failed} 个", "batchCalcFailed": "批量计算向量失败", "batchDeleteSuccess": "成功删除 {count} 个文件的向量", "batchDeletePartial": "删除完成:成功 {success} 个,失败 {failed} 个", "batchDeleteFailed": "批量删除向量失败", "noMarkdownFiles": "文件夹中没有 Markdown 文件", "includedInKB": "已包含在知识库中", "excludedFromKB": "已从知识库中排除", "autoCalcEnabled": "已启用自动向量计算", "autoCalcDisabled": "已禁用自动向量计算", "settingFailed": "设置失败", "confirmDeleteVectors": "确定要删除 {count} 个文件的向量吗?" }, "folderView": { "vectorDbNotEnabled": "向量数据库未启用", "calculateVectors": "计算向量", "indexed": "已计算", "vectorCount": "向量数", "databaseSize": "数据库大小", "lastCalculated": "最后计算", "never": "从未", "calculating": "计算中...", "failed": "失败", "recalculateVectors": "重新计算向量", "skills": "Skills", "skillNotFound": "Skill 未找到", "skillNotFoundDesc": "无法找到 ID 为 {id} 的 Skill", "loadingSkills": "加载 Skills...", "loadingSkill": "加载 Skill...", "globalSkills": "全局 Skills", "workspaceSkills": "工作区 Skills", "instructions": "指令", "examples": "示例", "scripts": "脚本", "references": "参考文档", "assets": "静态资源" }, "error": { "fileExists": "文件名已存在" }, "clipboard": { "copied": "已复制到剪贴板", "cut": "已剪切到剪贴板", "pasted": "已粘贴成功", "pasteFailed": "粘贴操作失败", "empty": "剪贴板为空", "confirmOverwrite": "文件已存在,是否覆盖?", "notSupported": "不支持此操作" }, "mobile": { "cancel": "取消", "create": "创建", "save": "保存", "emptyDir": "该目录为空", "root": "根目录", "openFiles": "打开文件", "remote": "远程文件", "remoteFileNotPulled": "仅云端 · 点击后拉取", "remoteFolderOnly": "仅云端目录", "file": "文件", "folder": "文件夹", "folderChildren": "{files} 个文件 · {folders} 个文件夹", "filePlaceholder": "示例.md", "folderPlaceholder": "示例文件夹" }, "deleteConfirm": "确认删除此文件吗?" }, "editor": { "copySuccess": "复制成功", "copySuccessDescription": "已复制到剪贴板", "search": { "placeholder": "在文档中查找", "replacePlaceholder": "替换为", "caseSensitive": "区分大小写", "replace": "替换", "replaceAll": "全部替换", "findPrev": "上一个", "findNext": "下一个" }, "floatbar": { "quote": { "tooltip": "引用" }, "readAloud": { "start": "朗读", "stop": "停止朗读", "loading": "正在加载..." } }, "upload": { "error": "上传失败", "needToken": "上传图片需配置 accessToken", "uploading": "正在上传图片" }, "saveDialog": { "title": "保存文件", "emptyContent": "内容为空", "emptyContentDesc": "请先输入内容后再保存", "success": "保存成功", "successDesc": "文件已保存", "error": "保存失败", "errorDesc": "文件保存失败,请重试" }, "toolbar": { "mark": { "title": "使用记录", "tooltip": "使用记录", "description": "消耗记录转化为内容插入到文章。", "noRecords": "暂无记录", "ocrNoContent": "OCR 未识别到任何内容" }, "question": { "tooltip": "问答", "selectContent": "请先选择一段内容", "promptTemplate": "参考原文:\n{content}\n根据提问:\n{question}\n,直接返回回答内容。" }, "continue": { "tooltip": "续写", "promptTemplate": "根据前文:\n{content}\n内容,直接返回续写内容,不要超过100字。\n内容可以参考后文:\n{endContent}\n,不要与后文内容重复。" }, "polish": { "tooltip": "润色", "selectContent": "请先选择一段内容", "promptTemplate": "润色这段文字:\n{content}\n要求语言不变,修复错别字和病句,直接返回润色后的结果。" }, "eraser": { "tooltip": "精简", "selectContent": "请先选择一段内容", "promptTemplate": "精简这段文字:\n{content}\n这段文字过于臃肿,字数要求缩减一半以上,要求语言不变,直接返回优化后的结果。" }, "expansion": { "tooltip": "扩写", "selectContent": "请先选择一段内容", "promptTemplate": "扩写这段文字:\n{content}\n这段文字过于简短,字数要求增加一倍以上,要求语言不变,直接返回扩写后的结果。" }, "translation": { "tooltip": "翻译", "description": "将选中的文本进行翻译", "selectContent": "请先选择一段内容", "promptTemplate": "将这段文字:\n{content}\n翻译为{language}语言,直接返回翻译后的结果。", "fail": "翻译失败", "failNoSelection": "请先选择要翻译的文本", "translating": "翻译中", "translatingTo": "正在翻译为 {language}...", "success": "翻译完成", "successTo": "已翻译为 {language}", "customLanguage": "自定义语言...", "customLanguagePlaceholder": "输入目标语言,如:英语、日语等", "customLanguageEmpty": "请输入目标语言", "customLanguageExample": "例如:英语、日语、法语等" } } }, "footer": { "wordCount": "字数", "pull": { "pull": "拉取", "checking": "检查更新中...", "noUpdate": "无远程更新", "clickToPull": "点击拉取远程更新", "pullSuccess": "拉取成功", "pullFailed": "拉取失败", "ignored": "已忽略", "ignoreUpdate": "忽略此更新" }, "sync": { "push": "推送", "pushed": "已推送", "syncing": "推送中", "syncFailed": "推送失败", "checkNetworkOrToken": "请检查网络连接或令牌是否正确", "quickSync": "快速同步" }, "history": { "loadingHistory": "正在读取历史记录", "historyRecords": "历史记录", "noHistory": "无历史记录", "loading": "加载中", "recordsCount": "条记录", "filterQuickSync": "过滤快速同步", "committedAt": "提交于", "pull": "拉取", "quickSync": "快速同步" }, "vectorCalc": { "tooltip": { "default": "向量索引状态", "none": "点击开始向量计算", "indexed": "已索引", "pending": "待更新,点击立即计算", "calculating": "计算中..." }, "status": { "calculating": "计算中" } } } }, "mobile": { "chat": { "drawer": { "settings": { "title": "对话设置" }, "tools": { "title": "工具", "newChat": "开始新对话", "start": "开始" }, "attachments": { "title": "附件", "gallery": "相册", "camera": "照相", "file": "文件", "linkNote": "关联笔记" } } } }, "mcp": { "selectServers": "MCP 服务器", "searchServers": "搜索服务器...", "noServers": "未启用 MCP 服务功能", "noServersFound": "未找到匹配的服务器", "addServer": "添加服务器...", "goToSettings": "前往设置", "close": "关闭", "navigate": "选择", "confirm": "确认", "tools": "个工具", "connecting": "连接中", "disconnected": "未连接" }, "recording": { "title": "录音识别", "description": "点击麦克风按钮开始录音,系统将自动识别并转换为文字记录", "recording": "录音中", "paused": "已暂停", "ready": "准备就绪", "processing": "识别中...", "cancel": "取消", "error": "错误", "success": "成功", "noModelConfigured": "未配置语音识别模型,请先在设置中配置", "speechUnavailable": "当前识别方式不可用,请检查本地语音支持或模型配置", "fallbackToModel": "本地语音识别不可用,已自动切换为模型识别", "startError": "无法启动录音", "noAudioData": "未录制到音频数据", "transcriptionSuccess": "语音识别完成", "transcriptionEmpty": "识别结果为空", "transcriptionError": "语音识别失败", "configureModel": "配置模型", "retryTranscription": "重新识别", "retrying": "重新识别中...", "retrySuccess": "重新识别完成", "retryError": "重新识别失败", "noContentDetected": "未识别到内容", "doubleClickToSelectFile": "双击选择音频文件", "mode": { "builtin": "浏览器识别", "builtinDesc": "免费,实时识别", "model": "大模型识别", "modelDesc": "需配置STT模型,更准确" } }, "quickRecord": { "description": "点击选择记录工具,快速创建记录" }, "editor": { "placeholder": "输入 / 唤起菜单,或直接开始写作...", "outline": { "title": "大纲", "open": "打开大纲", "close": "关闭大纲" }, "translation": { "fail": "翻译失败", "failNoSelection": "请先选择要翻译的文本", "translating": "翻译中", "translatingTo": "正在翻译为 {language}...", "success": "翻译完成", "successTo": "已翻译为 {language}", "customLanguageEmpty": "请输入目标语言", "customLanguageExample": "例如:英语、日语、法语等" }, "quoteDisplay": { "fromFile": "引用自 {fileName}", "line": "引用自 {fileName} 第 {line} 行", "lines": "引用自 {fileName} 第 {start}-{end} 行" }, "bubbleMenu": { "ai": "AI", "polish": "润色", "concise": "精简", "expand": "扩展", "translate": "翻译", "translateSubtitle": "翻译为", "quoteToChat": "引用到对话", "link": "链接", "linkPlaceholder": "输入链接地址", "confirm": "确认", "cancel": "取消", "bold": "粗体", "italic": "斜体", "strike": "删除线", "underline": "下划线", "inlineCode": "行内代码", "highlight": "高亮", "blockquote": "引用", "bulletList": "无序列表", "orderedList": "有序列表", "taskList": "任务列表", "codeBlock": "代码块", "languages": { "English": "英语", "Japanese": "日语", "Korean": "韩语", "French": "法语", "German": "德语", "Spanish": "西班牙语", "Portuguese": "葡萄牙语", "Russian": "俄语", "Arabic": "阿拉伯语" }, "customLanguagePlaceholder": "自定义语言..." }, "aiSuggestion": { "accept": "接受", "reject": "拒绝", "generating": "生成中...", "abort": "终止" }, "image": { "insert": "插入图片", "uploading": "上传中...", "uploadSuccess": "图片已上传到图床", "saveSuccess": "图片已保存到本地", "uploadFailed": "插入图片失败", "sizeSmall": "小 (25%)", "sizeMedium": "中 (50%)", "sizeLarge": "大 (75%)", "sizeOriginal": "原始尺寸", "editAlt": "编辑替代文本", "editSrc": "编辑地址", "altPlaceholder": "输入替代文本...", "srcPlaceholder": "输入图片地址...", "delete": "删除图片", "confirm": "确认", "cancel": "取消" }, "mermaid": { "rendering": "渲染中...", "renderError": "渲染错误", "clickToEdit": "点击编辑源码", "clickToAdd": "点击添加图表代码", "placeholder": "输入 Mermaid 图表代码...", "preview": "预览", "done": "完成", "diagramTypes": { "flowchart": "流程图", "sequence": "时序图", "classDiagram": "类图", "stateDiagram": "状态图", "er": "ER图", "gantt": "甘特图", "pie": "饼图", "journey": "旅程图" }, "templates": { "flowchart": "graph TD\n A[开始] --> B[处理]\n B --> C[结束]", "sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: 你好\n Bob-->>Alice: 回复", "classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender", "stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]", "er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses", "gantt": "gantt\n title 项目计划\n dateFormat YYYY-MM-DD\n section 第一阶段\n 任务1 :a1, 2024-01-01, 30d\n section 第二阶段\n 任务2 :after a1, 20d", "pie": "pie title 资源分配\n \"CPU\" : 45\n \"内存\" : 30\n \"存储\" : 25", "journey": "journey\n title 我的日常工作\n section 上午\n 通勤 : 7:00, 5\n 工作 : 9:00, 8" } }, "slashCommand": { "groups": { "ai": "AI", "heading": "标题", "list": "列表", "block": "块级", "align": "对齐", "embed": "嵌入", "math": "数学", "chart": "图表" }, "items": { "continue": "续写", "continueDesc": "AI 续写内容", "heading1": "标题1", "heading1Desc": "大标题", "heading2": "标题2", "heading2Desc": "中标题", "heading3": "标题3", "heading3Desc": "小标题", "bulletList": "无序列表", "bulletListDesc": "创建简单的项目列表", "orderedList": "有序列表", "orderedListDesc": "创建带编号的列表", "taskList": "任务列表", "taskListDesc": "创建带复选框的任务列表", "image": "图片", "imageDesc": "插入本地图片或图床图片", "table": "表格", "tableDesc": "插入表格", "blockquote": "引用", "blockquoteDesc": "捕获引用内容", "codeBlock": "代码块", "codeBlockDesc": "捕获代码片段", "divider": "分割线", "dividerDesc": "在元素之间创建分隔线", "inlineMath": "行内公式", "inlineMathDesc": "插入行内 LaTeX 公式", "blockMath": "块级公式", "blockMathDesc": "插入块级 LaTeX 公式", "flowchart": "流程图", "flowchartDesc": "插入流程图", "sequence": "时序图", "sequenceDesc": "插入时序图", "gantt": "甘特图", "ganttDesc": "插入甘特图", "classDiagram": "类图", "classDiagramDesc": "插入类图", "stateDiagram": "状态图", "stateDiagramDesc": "插入状态图", "pie": "饼图", "pieDesc": "插入饼图", "erDiagram": "ER图", "erDiagramDesc": "插入实体关系图", "journey": "旅程图", "journeyDesc": "插入用户旅程图" }, "imageUpload": { "success": "上传成功", "saveSuccess": "保存成功", "savePath": "保存路径: __PATH__", "failed": "插入图片失败" } } }, "tabContext": { "close": "关闭", "closeOthers": "关闭其他", "closeAll": "关闭全部", "closeLeft": "关闭左侧", "closeRight": "关闭右侧" } } ================================================ FILE: next.config.ts ================================================ import createNextIntlPlugin from 'next-intl/plugin'; import type { NextConfig } from "next"; const isProd = process.env.NODE_ENV === 'production'; const internalHost = process.env.TAURI_DEV_HOST || 'localhost'; const withNextIntl = createNextIntlPlugin(); const nextConfig: NextConfig = { /* config options here */ output: "export", images: { unoptimized: true, }, assetPrefix: isProd ? undefined : `http://${internalHost}:3456`, sassOptions: { silenceDeprecations: ['legacy-js-api'], }, reactStrictMode: false, turbopack: {}, devIndicators: false, webpack: (config) => { // 过滤掉 flushSync 警告 - 来自 Tiptap 编辑器的已知问题 config.stats = { ...config.stats, warningsFilter: (warning: string) => { return !warning.includes('flushSync'); } }; return config; } }; export default withNextIntl(nextConfig); ================================================ FILE: package.json ================================================ { "name": "note-gen", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev --turbopack -p 3456 -H 0.0.0.0", "build": "next build --turbopack", "start": "next start --turbopack -p 3456", "lint": "next lint", "tauri": "tauri", "docs:build": "npm --prefix ./docs run build", "sync-version": "./scripts/sync-version.sh", "ios-build": "npm run sync-version && pnpm tauri ios build --open" }, "dependencies": { "@antv/infographic": "^0.2.7", "@codemirror/commands": "^6.7.1", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "^3.9.1", "@octokit/core": "^6.1.2", "@radix-ui/react-accordion": "^1.2.12", "@radix-ui/react-alert-dialog": "^1.1.6", "@radix-ui/react-avatar": "^1.1.2", "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-collapsible": "^1.1.1", "@radix-ui/react-context-menu": "^2.2.2", "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-hover-card": "^1.1.2", "@radix-ui/react-label": "^2.1.0", "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-progress": "^1.1.7", "@radix-ui/react-radio-group": "^1.2.1", "@radix-ui/react-scroll-area": "^1.2.6", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slider": "^1.2.3", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-toast": "^1.2.2", "@radix-ui/react-toggle": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.3", "@sereneinserenade/tiptap-search-and-replace": "^0.1.1", "@tauri-apps/api": ">=2.0.0", "@tauri-apps/plugin-clipboard-manager": "~2", "@tauri-apps/plugin-dialog": "~2", "@tauri-apps/plugin-fs": "~2", "@tauri-apps/plugin-global-shortcut": "~2.2.0", "@tauri-apps/plugin-http": "~2.3.0", "@tauri-apps/plugin-opener": "^2.4.0", "@tauri-apps/plugin-os": "~2.2.1", "@tauri-apps/plugin-process": "~2.2.1", "@tauri-apps/plugin-shell": "~2", "@tauri-apps/plugin-sql": "~2", "@tauri-apps/plugin-store": "~2", "@tauri-apps/plugin-updater": "~2", "@tauri-apps/plugin-window-state": "~2", "@tiptap/core": "^3.19.0", "@tiptap/extension-bubble-menu": "^3.19.0", "@tiptap/extension-character-count": "^3.19.0", "@tiptap/extension-code-block-lowlight": "^3.19.0", "@tiptap/extension-color": "^3.19.0", "@tiptap/extension-dropcursor": "^3.19.0", "@tiptap/extension-floating-menu": "^3.19.0", "@tiptap/extension-highlight": "^3.19.0", "@tiptap/extension-horizontal-rule": "^3.19.0", "@tiptap/extension-image": "^3.19.0", "@tiptap/extension-link": "^3.19.0", "@tiptap/extension-mathematics": "^3.19.0", "@tiptap/extension-mention": "^3.19.0", "@tiptap/extension-placeholder": "^3.19.0", "@tiptap/extension-table": "^3.19.0", "@tiptap/extension-table-cell": "^3.19.0", "@tiptap/extension-table-header": "^3.19.0", "@tiptap/extension-table-row": "^3.19.0", "@tiptap/extension-task-item": "^3.19.0", "@tiptap/extension-task-list": "^3.19.0", "@tiptap/extension-text-align": "^3.19.0", "@tiptap/extension-text-style": "^3.19.0", "@tiptap/extension-typography": "^3.19.0", "@tiptap/extension-underline": "^3.19.0", "@tiptap/extension-unique-id": "^3.19.0", "@tiptap/extension-youtube": "^3.19.0", "@tiptap/markdown": "^3.19.0", "@tiptap/pm": "^3.19.0", "@tiptap/react": "^3.19.0", "@tiptap/starter-kit": "^3.19.0", "@tiptap/suggestion": "^3.19.0", "@types/lodash-es": "^4.17.12", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "1.0.0", "cropperjs": "1", "crypto-js": "^4.2.0", "date-fns": "^4.1.0", "date-fns-tz": "^3.2.0", "dayjs": "^1.11.13", "diff": "^7.0.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.26.2", "github-markdown-css": "^5.8.1", "highlight.js": "^11.11.1", "hotkeys-js": "^3.13.15", "html2canvas": "^1.4.1", "jspdf": "^3.0.4", "katex": "^0.16.28", "lodash": "^4.17.21", "lodash-es": "^4.17.21", "lowlight": "^3.3.0", "lucide-react": "^0.561.0", "markdown-it": "^14.1.0", "mermaid": "^11.12.2", "mitt": "^3.0.1", "next": "^15.1.0", "next-intl": "^3.26.5", "next-themes": "^0.4.3", "openai": "^4.78.1", "pdfjs-dist": "^4.10.38", "pinyin": "^4.0.0", "react": "19.1.0", "react-advanced-cropper": "^0.20.1", "react-day-picker": "^9.13.0", "react-dom": "19.1.0", "react-hook-form": "^7.53.2", "react-photo-view": "^1.2.6", "react-resizable-panels": "^2.1.7", "react-use": "^17.6.0", "tailwind-merge": "^2.5.4", "tailwindcss-safe-area": "^0.6.0", "tauri-plugin-clipboard-api": "^2.1.11", "tesseract.js": "^5.1.1", "tippy.js": "^6.3.7", "usehooks-ts": "^3.1.1", "uuid": "^11.0.3", "vaul": "^1.1.1", "words-count": "^2.0.2", "zod": "^3.23.8", "zustand": "^5.0.1" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.18", "@tailwindcss/vite": "^4.1.18", "@tauri-apps/cli": ">=2.0.0", "@types/crypto-js": "^4.2.2", "@types/diff": "^6.0.0", "@types/markdown-it": "^14.1.2", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "15.0.3", "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", "typescript": "^5" } } ================================================ FILE: postcss.config.mjs ================================================ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { "@tailwindcss/postcss": {}, }, }; export default config; ================================================ FILE: public/markdown/github-markdown-dark.css ================================================ /* dark */ .markdown-body { color-scheme: dark; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; color: #f0f6fc; background-color: #0d1117; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; font-size: 16px; line-height: 1.5; word-wrap: break-word; } .markdown-body .octicon { display: inline-block; fill: currentColor; vertical-align: text-bottom; } .markdown-body h1:hover .anchor .octicon-link:before, .markdown-body h2:hover .anchor .octicon-link:before, .markdown-body h3:hover .anchor .octicon-link:before, .markdown-body h4:hover .anchor .octicon-link:before, .markdown-body h5:hover .anchor .octicon-link:before, .markdown-body h6:hover .anchor .octicon-link:before { width: 16px; height: 16px; content: ' '; display: inline-block; background-color: currentColor; -webkit-mask-image: url("data:image/svg+xml,"); mask-image: url("data:image/svg+xml,"); } .markdown-body details, .markdown-body figcaption, .markdown-body figure { display: block; } .markdown-body summary { display: list-item; } .markdown-body [hidden] { display: none !important; } .markdown-body a { background-color: transparent; color: #4493f8; text-decoration: none; } .markdown-body abbr[title] { border-bottom: none; -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } .markdown-body b, .markdown-body strong { font-weight: 600; } .markdown-body dfn { font-style: italic; } .markdown-body h1 { margin: .67em 0; font-weight: 600; padding-bottom: .3em; font-size: 2em; border-bottom: 1px solid #3d444db3; } .markdown-body mark { background-color: #bb800926; color: #f0f6fc; } .markdown-body small { font-size: 90%; } .markdown-body sub, .markdown-body sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } .markdown-body sub { bottom: -0.25em; } .markdown-body sup { top: -0.5em; } .markdown-body img { border-style: none; max-width: 100%; box-sizing: content-box; } .markdown-body code, .markdown-body kbd, .markdown-body pre, .markdown-body samp { font-family: monospace; font-size: 1em; } .markdown-body figure { margin: 1em 2.5rem; } .markdown-body hr { box-sizing: content-box; overflow: hidden; background: transparent; border-bottom: 1px solid #3d444db3; height: .25em; padding: 0; margin: 1.5rem 0; background-color: #3d444d; border: 0; } .markdown-body input { font: inherit; margin: 0; overflow: visible; font-family: inherit; font-size: inherit; line-height: inherit; } .markdown-body [type=button], .markdown-body [type=reset], .markdown-body [type=submit] { -webkit-appearance: button; appearance: button; } .markdown-body [type=checkbox], .markdown-body [type=radio] { box-sizing: border-box; padding: 0; } .markdown-body [type=number]::-webkit-inner-spin-button, .markdown-body [type=number]::-webkit-outer-spin-button { height: auto; } .markdown-body [type=search]::-webkit-search-cancel-button, .markdown-body [type=search]::-webkit-search-decoration { -webkit-appearance: none; appearance: none; } .markdown-body ::-webkit-input-placeholder { color: inherit; opacity: .54; } .markdown-body ::-webkit-file-upload-button { -webkit-appearance: button; appearance: button; font: inherit; } .markdown-body a:hover { text-decoration: underline; } .markdown-body ::placeholder { color: #9198a1; opacity: 1; } .markdown-body hr::before { display: table; content: ""; } .markdown-body hr::after { display: table; clear: both; content: ""; } .markdown-body table { border-spacing: 0; border-collapse: collapse; display: block; width: max-content; max-width: 100%; overflow: auto; font-variant: tabular-nums; } .markdown-body td, .markdown-body th { padding: 0; } .markdown-body details summary { cursor: pointer; } .markdown-body a:focus, .markdown-body [role=button]:focus, .markdown-body input[type=radio]:focus, .markdown-body input[type=checkbox]:focus { outline: 2px solid #1f6feb; outline-offset: -2px; box-shadow: none; } .markdown-body a:focus:not(:focus-visible), .markdown-body [role=button]:focus:not(:focus-visible), .markdown-body input[type=radio]:focus:not(:focus-visible), .markdown-body input[type=checkbox]:focus:not(:focus-visible) { outline: solid 1px transparent; } .markdown-body a:focus-visible, .markdown-body [role=button]:focus-visible, .markdown-body input[type=radio]:focus-visible, .markdown-body input[type=checkbox]:focus-visible { outline: 2px solid #1f6feb; outline-offset: -2px; box-shadow: none; } .markdown-body a:not([class]):focus, .markdown-body a:not([class]):focus-visible, .markdown-body input[type=radio]:focus, .markdown-body input[type=radio]:focus-visible, .markdown-body input[type=checkbox]:focus, .markdown-body input[type=checkbox]:focus-visible { outline-offset: 0; } .markdown-body kbd { display: inline-block; padding: 0.25rem; font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; line-height: 10px; color: #f0f6fc; vertical-align: middle; background-color: #151b23; border: solid 1px #3d444db3; border-bottom-color: #3d444db3; border-radius: 6px; box-shadow: inset 0 -1px 0 #3d444db3; } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { margin-top: 1.5rem; margin-bottom: 1rem; font-weight: 600; line-height: 1.25; } .markdown-body h2 { font-weight: 600; padding-bottom: .3em; font-size: 1.5em; border-bottom: 1px solid #3d444db3; } .markdown-body h3 { font-weight: 600; font-size: 1.25em; } .markdown-body h4 { font-weight: 600; font-size: 1em; } .markdown-body h5 { font-weight: 600; font-size: .875em; } .markdown-body h6 { font-weight: 600; font-size: .85em; color: #9198a1; } .markdown-body p { margin-top: 0; margin-bottom: 10px; } .markdown-body blockquote { margin: 0; padding: 0 1em; color: #9198a1; border-left: .25em solid #3d444d; } .markdown-body ul, .markdown-body ol { margin-top: 0; margin-bottom: 0; padding-left: 2em; } .markdown-body ol ol, .markdown-body ul ol { list-style-type: lower-roman; } .markdown-body ul ul ol, .markdown-body ul ol ol, .markdown-body ol ul ol, .markdown-body ol ol ol { list-style-type: lower-alpha; } .markdown-body dd { margin-left: 0; } .markdown-body tt, .markdown-body code, .markdown-body samp { font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; font-size: 12px; } .markdown-body pre { margin-top: 0; margin-bottom: 0; font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; font-size: 12px; word-wrap: normal; } .markdown-body .octicon { display: inline-block; overflow: visible !important; vertical-align: text-bottom; fill: currentColor; } .markdown-body input::-webkit-outer-spin-button, .markdown-body input::-webkit-inner-spin-button { margin: 0; appearance: none; } .markdown-body .mr-2 { margin-right: 0.5rem !important; } .markdown-body::before { display: table; content: ""; } .markdown-body::after { display: table; clear: both; content: ""; } .markdown-body>*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !important; } .markdown-body a:not([href]) { color: inherit; text-decoration: none; } .markdown-body .absent { color: #f85149; } .markdown-body .anchor { float: left; padding-right: 0.25rem; margin-left: -20px; line-height: 1; } .markdown-body .anchor:focus { outline: none; } .markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre, .markdown-body details { margin-top: 0; margin-bottom: 1rem; } .markdown-body blockquote>:first-child { margin-top: 0; } .markdown-body blockquote>:last-child { margin-bottom: 0; } .markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link { color: #f0f6fc; vertical-align: middle; visibility: hidden; } .markdown-body h1:hover .anchor, .markdown-body h2:hover .anchor, .markdown-body h3:hover .anchor, .markdown-body h4:hover .anchor, .markdown-body h5:hover .anchor, .markdown-body h6:hover .anchor { text-decoration: none; } .markdown-body h1:hover .anchor .octicon-link, .markdown-body h2:hover .anchor .octicon-link, .markdown-body h3:hover .anchor .octicon-link, .markdown-body h4:hover .anchor .octicon-link, .markdown-body h5:hover .anchor .octicon-link, .markdown-body h6:hover .anchor .octicon-link { visibility: visible; } .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code { padding: 0 .2em; font-size: inherit; } .markdown-body summary h1, .markdown-body summary h2, .markdown-body summary h3, .markdown-body summary h4, .markdown-body summary h5, .markdown-body summary h6 { display: inline-block; } .markdown-body summary h1 .anchor, .markdown-body summary h2 .anchor, .markdown-body summary h3 .anchor, .markdown-body summary h4 .anchor, .markdown-body summary h5 .anchor, .markdown-body summary h6 .anchor { margin-left: -40px; } .markdown-body summary h1, .markdown-body summary h2 { padding-bottom: 0; border-bottom: 0; } .markdown-body ul.no-list, .markdown-body ol.no-list { padding: 0; list-style-type: none; } .markdown-body ol[type="a s"] { list-style-type: lower-alpha; } .markdown-body ol[type="A s"] { list-style-type: upper-alpha; } .markdown-body ol[type="i s"] { list-style-type: lower-roman; } .markdown-body ol[type="I s"] { list-style-type: upper-roman; } .markdown-body ol[type="1"] { list-style-type: decimal; } .markdown-body div>ol:not([type]) { list-style-type: decimal; } .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-top: 0; margin-bottom: 0; } .markdown-body li>p { margin-top: 1rem; } .markdown-body li+li { margin-top: .25em; } .markdown-body dl { padding: 0; } .markdown-body dl dt { padding: 0; margin-top: 1rem; font-size: 1em; font-style: italic; font-weight: 600; } .markdown-body dl dd { padding: 0 1rem; margin-bottom: 1rem; } .markdown-body table th { font-weight: 600; } .markdown-body table th, .markdown-body table td { padding: 6px 13px; border: 1px solid #3d444d; } .markdown-body table td>:last-child { margin-bottom: 0; } .markdown-body table tr { background-color: #0d1117; border-top: 1px solid #3d444db3; } .markdown-body table tr:nth-child(2n) { background-color: #151b23; } .markdown-body table img { background-color: transparent; } .markdown-body img[align=right] { padding-left: 20px; } .markdown-body img[align=left] { padding-right: 20px; } .markdown-body .emoji { max-width: none; vertical-align: text-top; background-color: transparent; } .markdown-body span.frame { display: block; overflow: hidden; } .markdown-body span.frame>span { display: block; float: left; width: auto; padding: 7px; margin: 13px 0 0; overflow: hidden; border: 1px solid #3d444d; } .markdown-body span.frame span img { display: block; float: left; } .markdown-body span.frame span span { display: block; padding: 5px 0 0; clear: both; color: #f0f6fc; } .markdown-body span.align-center { display: block; overflow: hidden; clear: both; } .markdown-body span.align-center>span { display: block; margin: 13px auto 0; overflow: hidden; text-align: center; } .markdown-body span.align-center span img { margin: 0 auto; text-align: center; } .markdown-body span.align-right { display: block; overflow: hidden; clear: both; } .markdown-body span.align-right>span { display: block; margin: 13px 0 0; overflow: hidden; text-align: right; } .markdown-body span.align-right span img { margin: 0; text-align: right; } .markdown-body span.float-left { display: block; float: left; margin-right: 13px; overflow: hidden; } .markdown-body span.float-left span { margin: 13px 0 0; } .markdown-body span.float-right { display: block; float: right; margin-left: 13px; overflow: hidden; } .markdown-body span.float-right>span { display: block; margin: 13px auto 0; overflow: hidden; text-align: right; } .markdown-body code, .markdown-body tt { padding: .2em .4em; margin: 0; font-size: 85%; white-space: break-spaces; background-color: #656c7633; border-radius: 6px; } .markdown-body code br, .markdown-body tt br { display: none; } .markdown-body del code { text-decoration: inherit; } .markdown-body samp { font-size: 85%; } .markdown-body pre code { font-size: 100%; } .markdown-body pre>code { padding: 0; margin: 0; word-break: normal; white-space: pre; background: transparent; border: 0; } .markdown-body .highlight { margin-bottom: 1rem; } .markdown-body .highlight pre { margin-bottom: 0; word-break: normal; } .markdown-body .highlight pre, .markdown-body pre { padding: 1rem; overflow: auto; font-size: 85%; line-height: 1.45; color: #f0f6fc; background-color: #151b23; border-radius: 6px; } .markdown-body pre code, .markdown-body pre tt { display: inline; max-width: auto; padding: 0; margin: 0; overflow: visible; line-height: inherit; word-wrap: normal; background-color: transparent; border: 0; } .markdown-body .csv-data td, .markdown-body .csv-data th { padding: 5px; overflow: hidden; font-size: 12px; line-height: 1; text-align: left; white-space: nowrap; } .markdown-body .csv-data .blob-num { padding: 10px 0.5rem 9px; text-align: right; background: #0d1117; border: 0; } .markdown-body .csv-data tr { border-top: 0; } .markdown-body .csv-data th { font-weight: 600; background: #151b23; border-top: 0; } .markdown-body [data-footnote-ref]::before { content: "["; } .markdown-body [data-footnote-ref]::after { content: "]"; } .markdown-body .footnotes { font-size: 12px; color: #9198a1; border-top: 1px solid #3d444d; } .markdown-body .footnotes ol { padding-left: 1rem; } .markdown-body .footnotes ol ul { display: inline-block; padding-left: 1rem; margin-top: 1rem; } .markdown-body .footnotes li { position: relative; } .markdown-body .footnotes li:target::before { position: absolute; top: calc(0.5rem*-1); right: calc(0.5rem*-1); bottom: calc(0.5rem*-1); left: calc(1.5rem*-1); pointer-events: none; content: ""; border: 2px solid #1f6feb; border-radius: 6px; } .markdown-body .footnotes li:target { color: #f0f6fc; } .markdown-body .footnotes .data-footnote-backref g-emoji { font-family: monospace; } .markdown-body body:has(:modal) { padding-right: var(--dialog-scrollgutter) !important; } .markdown-body .pl-c { color: #9198a1; } .markdown-body .pl-c1, .markdown-body .pl-s .pl-v { color: #79c0ff; } .markdown-body .pl-e, .markdown-body .pl-en { color: #d2a8ff; } .markdown-body .pl-smi, .markdown-body .pl-s .pl-s1 { color: #f0f6fc; } .markdown-body .pl-ent { color: #7ee787; } .markdown-body .pl-k { color: #ff7b72; } .markdown-body .pl-s, .markdown-body .pl-pds, .markdown-body .pl-s .pl-pse .pl-s1, .markdown-body .pl-sr, .markdown-body .pl-sr .pl-cce, .markdown-body .pl-sr .pl-sre, .markdown-body .pl-sr .pl-sra { color: #a5d6ff; } .markdown-body .pl-v, .markdown-body .pl-smw { color: #ffa657; } .markdown-body .pl-bu { color: #f85149; } .markdown-body .pl-ii { color: #f0f6fc; background-color: #8e1519; } .markdown-body .pl-c2 { color: #f0f6fc; background-color: #b62324; } .markdown-body .pl-sr .pl-cce { font-weight: bold; color: #7ee787; } .markdown-body .pl-ml { color: #f2cc60; } .markdown-body .pl-mh, .markdown-body .pl-mh .pl-en, .markdown-body .pl-ms { font-weight: bold; color: #1f6feb; } .markdown-body .pl-mi { font-style: italic; color: #f0f6fc; } .markdown-body .pl-mb { font-weight: bold; color: #f0f6fc; } .markdown-body .pl-md { color: #ffdcd7; background-color: #67060c; } .markdown-body .pl-mi1 { color: #aff5b4; background-color: #033a16; } .markdown-body .pl-mc { color: #ffdfb6; background-color: #5a1e02; } .markdown-body .pl-mi2 { color: #f0f6fc; background-color: #1158c7; } .markdown-body .pl-mdr { font-weight: bold; color: #d2a8ff; } .markdown-body .pl-ba { color: #9198a1; } .markdown-body .pl-sg { color: #3d444d; } .markdown-body .pl-corl { text-decoration: underline; color: #a5d6ff; } .markdown-body [role=button]:focus:not(:focus-visible), .markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible), .markdown-body button:focus:not(:focus-visible), .markdown-body summary:focus:not(:focus-visible), .markdown-body a:focus:not(:focus-visible) { outline: none; box-shadow: none; } .markdown-body [tabindex="0"]:focus:not(:focus-visible), .markdown-body details-dialog:focus:not(:focus-visible) { outline: none; } .markdown-body g-emoji { display: inline-block; min-width: 1ch; font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; font-size: 1em; font-style: normal !important; font-weight: 400; line-height: 1; vertical-align: -0.075em; } .markdown-body g-emoji img { width: 1em; height: 1em; } .markdown-body .task-list-item { list-style-type: none; } .markdown-body .task-list-item label { font-weight: 400; } .markdown-body .task-list-item.enabled label { cursor: pointer; } .markdown-body .task-list-item+.task-list-item { margin-top: 0.25rem; } .markdown-body .task-list-item .handle { display: none; } .markdown-body .task-list-item-checkbox { margin: 0 .2em .25em -1.4em; vertical-align: middle; } .markdown-body ul:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em .25em .2em; } .markdown-body ol:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em .25em .2em; } .markdown-body .contains-task-list:hover .task-list-item-convert-container, .markdown-body .contains-task-list:focus-within .task-list-item-convert-container { display: block; width: auto; height: 24px; overflow: visible; clip: auto; } .markdown-body ::-webkit-calendar-picker-indicator { filter: invert(50%); } .markdown-body .markdown-alert { padding: 0.5rem 1rem; margin-bottom: 1rem; color: inherit; border-left: .25em solid #3d444d; } .markdown-body .markdown-alert>:first-child { margin-top: 0; } .markdown-body .markdown-alert>:last-child { margin-bottom: 0; } .markdown-body .markdown-alert .markdown-alert-title { display: flex; font-weight: 500; align-items: center; line-height: 1; } .markdown-body .markdown-alert.markdown-alert-note { border-left-color: #1f6feb; } .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title { color: #4493f8; } .markdown-body .markdown-alert.markdown-alert-important { border-left-color: #8957e5; } .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title { color: #ab7df8; } .markdown-body .markdown-alert.markdown-alert-warning { border-left-color: #9e6a03; } .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title { color: #d29922; } .markdown-body .markdown-alert.markdown-alert-tip { border-left-color: #238636; } .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title { color: #3fb950; } .markdown-body .markdown-alert.markdown-alert-caution { border-left-color: #da3633; } .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title { color: #f85149; } .markdown-body>*:first-child>.heading-element:first-child { margin-top: 0 !important; } .markdown-body .highlight pre:has(+.zeroclipboard-container) { min-height: 52px; } ================================================ FILE: public/markdown/github-markdown-light.css ================================================ /* light */ .markdown-body { color-scheme: light; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; color: #1f2328; background-color: #ffffff; font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; font-size: 16px; line-height: 1.5; word-wrap: break-word; } .markdown-body .octicon { display: inline-block; fill: currentColor; vertical-align: text-bottom; } .markdown-body h1:hover .anchor .octicon-link:before, .markdown-body h2:hover .anchor .octicon-link:before, .markdown-body h3:hover .anchor .octicon-link:before, .markdown-body h4:hover .anchor .octicon-link:before, .markdown-body h5:hover .anchor .octicon-link:before, .markdown-body h6:hover .anchor .octicon-link:before { width: 16px; height: 16px; content: ' '; display: inline-block; background-color: currentColor; -webkit-mask-image: url("data:image/svg+xml,"); mask-image: url("data:image/svg+xml,"); } .markdown-body details, .markdown-body figcaption, .markdown-body figure { display: block; } .markdown-body summary { display: list-item; } .markdown-body [hidden] { display: none !important; } .markdown-body a { background-color: transparent; color: #0969da; text-decoration: none; } .markdown-body abbr[title] { border-bottom: none; -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } .markdown-body b, .markdown-body strong { font-weight: 600; } .markdown-body dfn { font-style: italic; } .markdown-body h1 { margin: .67em 0; font-weight: 600; padding-bottom: .3em; font-size: 2em; border-bottom: 1px solid #d1d9e0b3; } .markdown-body mark { background-color: #fff8c5; color: #1f2328; } .markdown-body small { font-size: 90%; } .markdown-body sub, .markdown-body sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } .markdown-body sub { bottom: -0.25em; } .markdown-body sup { top: -0.5em; } .markdown-body img { border-style: none; max-width: 100%; box-sizing: content-box; } .markdown-body code, .markdown-body kbd, .markdown-body pre, .markdown-body samp { font-family: monospace; font-size: 1em; } .markdown-body figure { margin: 1em 2.5rem; } .markdown-body hr { box-sizing: content-box; overflow: hidden; background: transparent; border-bottom: 1px solid #d1d9e0b3; height: .25em; padding: 0; margin: 1.5rem 0; background-color: #d1d9e0; border: 0; } .markdown-body input { font: inherit; margin: 0; overflow: visible; font-family: inherit; font-size: inherit; line-height: inherit; } .markdown-body [type=button], .markdown-body [type=reset], .markdown-body [type=submit] { -webkit-appearance: button; appearance: button; } .markdown-body [type=checkbox], .markdown-body [type=radio] { box-sizing: border-box; padding: 0; } .markdown-body [type=number]::-webkit-inner-spin-button, .markdown-body [type=number]::-webkit-outer-spin-button { height: auto; } .markdown-body [type=search]::-webkit-search-cancel-button, .markdown-body [type=search]::-webkit-search-decoration { -webkit-appearance: none; appearance: none; } .markdown-body ::-webkit-input-placeholder { color: inherit; opacity: .54; } .markdown-body ::-webkit-file-upload-button { -webkit-appearance: button; appearance: button; font: inherit; } .markdown-body a:hover { text-decoration: underline; } .markdown-body ::placeholder { color: #59636e; opacity: 1; } .markdown-body hr::before { display: table; content: ""; } .markdown-body hr::after { display: table; clear: both; content: ""; } .markdown-body table { border-spacing: 0; border-collapse: collapse; display: block; width: max-content; max-width: 100%; overflow: auto; font-variant: tabular-nums; } .markdown-body td, .markdown-body th { padding: 0; } .markdown-body details summary { cursor: pointer; } .markdown-body a:focus, .markdown-body [role=button]:focus, .markdown-body input[type=radio]:focus, .markdown-body input[type=checkbox]:focus { outline: 2px solid #0969da; outline-offset: -2px; box-shadow: none; } .markdown-body a:focus:not(:focus-visible), .markdown-body [role=button]:focus:not(:focus-visible), .markdown-body input[type=radio]:focus:not(:focus-visible), .markdown-body input[type=checkbox]:focus:not(:focus-visible) { outline: solid 1px transparent; } .markdown-body a:focus-visible, .markdown-body [role=button]:focus-visible, .markdown-body input[type=radio]:focus-visible, .markdown-body input[type=checkbox]:focus-visible { outline: 2px solid #0969da; outline-offset: -2px; box-shadow: none; } .markdown-body a:not([class]):focus, .markdown-body a:not([class]):focus-visible, .markdown-body input[type=radio]:focus, .markdown-body input[type=radio]:focus-visible, .markdown-body input[type=checkbox]:focus, .markdown-body input[type=checkbox]:focus-visible { outline-offset: 0; } .markdown-body kbd { display: inline-block; padding: 0.25rem; font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; line-height: 10px; color: #1f2328; vertical-align: middle; background-color: #f6f8fa; border: solid 1px #d1d9e0b3; border-bottom-color: #d1d9e0b3; border-radius: 6px; box-shadow: inset 0 -1px 0 #d1d9e0b3; } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { margin-top: 1.5rem; margin-bottom: 1rem; font-weight: 600; line-height: 1.25; } .markdown-body h2 { font-weight: 600; padding-bottom: .3em; font-size: 1.5em; border-bottom: 1px solid #d1d9e0b3; } .markdown-body h3 { font-weight: 600; font-size: 1.25em; } .markdown-body h4 { font-weight: 600; font-size: 1em; } .markdown-body h5 { font-weight: 600; font-size: .875em; } .markdown-body h6 { font-weight: 600; font-size: .85em; color: #59636e; } .markdown-body p { margin-top: 0; margin-bottom: 10px; } .markdown-body blockquote { margin: 0; padding: 0 1em; color: #59636e; border-left: .25em solid #d1d9e0; } .markdown-body ul, .markdown-body ol { margin-top: 0; margin-bottom: 0; padding-left: 2em; } .markdown-body ol ol, .markdown-body ul ol { list-style-type: lower-roman; } .markdown-body ul ul ol, .markdown-body ul ol ol, .markdown-body ol ul ol, .markdown-body ol ol ol { list-style-type: lower-alpha; } .markdown-body dd { margin-left: 0; } .markdown-body tt, .markdown-body code, .markdown-body samp { font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; font-size: 12px; } .markdown-body pre { margin-top: 0; margin-bottom: 0; font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; font-size: 12px; word-wrap: normal; } .markdown-body .octicon { display: inline-block; overflow: visible !important; vertical-align: text-bottom; fill: currentColor; } .markdown-body input::-webkit-outer-spin-button, .markdown-body input::-webkit-inner-spin-button { margin: 0; appearance: none; } .markdown-body .mr-2 { margin-right: 0.5rem !important; } .markdown-body::before { display: table; content: ""; } .markdown-body::after { display: table; clear: both; content: ""; } .markdown-body>*:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !important; } .markdown-body a:not([href]) { color: inherit; text-decoration: none; } .markdown-body .absent { color: #d1242f; } .markdown-body .anchor { float: left; padding-right: 0.25rem; margin-left: -20px; line-height: 1; } .markdown-body .anchor:focus { outline: none; } .markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre, .markdown-body details { margin-top: 0; margin-bottom: 1rem; } .markdown-body blockquote>:first-child { margin-top: 0; } .markdown-body blockquote>:last-child { margin-bottom: 0; } .markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link { color: #1f2328; vertical-align: middle; visibility: hidden; } .markdown-body h1:hover .anchor, .markdown-body h2:hover .anchor, .markdown-body h3:hover .anchor, .markdown-body h4:hover .anchor, .markdown-body h5:hover .anchor, .markdown-body h6:hover .anchor { text-decoration: none; } .markdown-body h1:hover .anchor .octicon-link, .markdown-body h2:hover .anchor .octicon-link, .markdown-body h3:hover .anchor .octicon-link, .markdown-body h4:hover .anchor .octicon-link, .markdown-body h5:hover .anchor .octicon-link, .markdown-body h6:hover .anchor .octicon-link { visibility: visible; } .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code { padding: 0 .2em; font-size: inherit; } .markdown-body summary h1, .markdown-body summary h2, .markdown-body summary h3, .markdown-body summary h4, .markdown-body summary h5, .markdown-body summary h6 { display: inline-block; } .markdown-body summary h1 .anchor, .markdown-body summary h2 .anchor, .markdown-body summary h3 .anchor, .markdown-body summary h4 .anchor, .markdown-body summary h5 .anchor, .markdown-body summary h6 .anchor { margin-left: -40px; } .markdown-body summary h1, .markdown-body summary h2 { padding-bottom: 0; border-bottom: 0; } .markdown-body ul.no-list, .markdown-body ol.no-list { padding: 0; list-style-type: none; } .markdown-body ol[type="a s"] { list-style-type: lower-alpha; } .markdown-body ol[type="A s"] { list-style-type: upper-alpha; } .markdown-body ol[type="i s"] { list-style-type: lower-roman; } .markdown-body ol[type="I s"] { list-style-type: upper-roman; } .markdown-body ol[type="1"] { list-style-type: decimal; } .markdown-body div>ol:not([type]) { list-style-type: decimal; } .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-top: 0; margin-bottom: 0; } .markdown-body li>p { margin-top: 1rem; } .markdown-body li+li { margin-top: .25em; } .markdown-body dl { padding: 0; } .markdown-body dl dt { padding: 0; margin-top: 1rem; font-size: 1em; font-style: italic; font-weight: 600; } .markdown-body dl dd { padding: 0 1rem; margin-bottom: 1rem; } .markdown-body table th { font-weight: 600; } .markdown-body table th, .markdown-body table td { padding: 6px 13px; border: 1px solid #d1d9e0; } .markdown-body table td>:last-child { margin-bottom: 0; } .markdown-body table tr { background-color: #ffffff; border-top: 1px solid #d1d9e0b3; } .markdown-body table tr:nth-child(2n) { background-color: #f6f8fa; } .markdown-body table img { background-color: transparent; } .markdown-body img[align=right] { padding-left: 20px; } .markdown-body img[align=left] { padding-right: 20px; } .markdown-body .emoji { max-width: none; vertical-align: text-top; background-color: transparent; } .markdown-body span.frame { display: block; overflow: hidden; } .markdown-body span.frame>span { display: block; float: left; width: auto; padding: 7px; margin: 13px 0 0; overflow: hidden; border: 1px solid #d1d9e0; } .markdown-body span.frame span img { display: block; float: left; } .markdown-body span.frame span span { display: block; padding: 5px 0 0; clear: both; color: #1f2328; } .markdown-body span.align-center { display: block; overflow: hidden; clear: both; } .markdown-body span.align-center>span { display: block; margin: 13px auto 0; overflow: hidden; text-align: center; } .markdown-body span.align-center span img { margin: 0 auto; text-align: center; } .markdown-body span.align-right { display: block; overflow: hidden; clear: both; } .markdown-body span.align-right>span { display: block; margin: 13px 0 0; overflow: hidden; text-align: right; } .markdown-body span.align-right span img { margin: 0; text-align: right; } .markdown-body span.float-left { display: block; float: left; margin-right: 13px; overflow: hidden; } .markdown-body span.float-left span { margin: 13px 0 0; } .markdown-body span.float-right { display: block; float: right; margin-left: 13px; overflow: hidden; } .markdown-body span.float-right>span { display: block; margin: 13px auto 0; overflow: hidden; text-align: right; } .markdown-body code, .markdown-body tt { padding: .2em .4em; margin: 0; font-size: 85%; white-space: break-spaces; background-color: #818b981f; border-radius: 6px; } .markdown-body code br, .markdown-body tt br { display: none; } .markdown-body del code { text-decoration: inherit; } .markdown-body samp { font-size: 85%; } .markdown-body pre code { font-size: 100%; } .markdown-body pre>code { padding: 0; margin: 0; word-break: normal; white-space: pre; background: transparent; border: 0; } .markdown-body .highlight { margin-bottom: 1rem; } .markdown-body .highlight pre { margin-bottom: 0; word-break: normal; } .markdown-body .highlight pre, .markdown-body pre { padding: 1rem; overflow: auto; font-size: 85%; line-height: 1.45; color: #1f2328; background-color: #f6f8fa; border-radius: 6px; } .markdown-body pre code, .markdown-body pre tt { display: inline; max-width: auto; padding: 0; margin: 0; overflow: visible; line-height: inherit; word-wrap: normal; background-color: transparent; border: 0; } .markdown-body .csv-data td, .markdown-body .csv-data th { padding: 5px; overflow: hidden; font-size: 12px; line-height: 1; text-align: left; white-space: nowrap; } .markdown-body .csv-data .blob-num { padding: 10px 0.5rem 9px; text-align: right; background: #ffffff; border: 0; } .markdown-body .csv-data tr { border-top: 0; } .markdown-body .csv-data th { font-weight: 600; background: #f6f8fa; border-top: 0; } .markdown-body [data-footnote-ref]::before { content: "["; } .markdown-body [data-footnote-ref]::after { content: "]"; } .markdown-body .footnotes { font-size: 12px; color: #59636e; border-top: 1px solid #d1d9e0; } .markdown-body .footnotes ol { padding-left: 1rem; } .markdown-body .footnotes ol ul { display: inline-block; padding-left: 1rem; margin-top: 1rem; } .markdown-body .footnotes li { position: relative; } .markdown-body .footnotes li:target::before { position: absolute; top: calc(0.5rem*-1); right: calc(0.5rem*-1); bottom: calc(0.5rem*-1); left: calc(1.5rem*-1); pointer-events: none; content: ""; border: 2px solid #0969da; border-radius: 6px; } .markdown-body .footnotes li:target { color: #1f2328; } .markdown-body .footnotes .data-footnote-backref g-emoji { font-family: monospace; } .markdown-body body:has(:modal) { padding-right: var(--dialog-scrollgutter) !important; } .markdown-body .pl-c { color: #59636e; } .markdown-body .pl-c1, .markdown-body .pl-s .pl-v { color: #0550ae; } .markdown-body .pl-e, .markdown-body .pl-en { color: #6639ba; } .markdown-body .pl-smi, .markdown-body .pl-s .pl-s1 { color: #1f2328; } .markdown-body .pl-ent { color: #0550ae; } .markdown-body .pl-k { color: #cf222e; } .markdown-body .pl-s, .markdown-body .pl-pds, .markdown-body .pl-s .pl-pse .pl-s1, .markdown-body .pl-sr, .markdown-body .pl-sr .pl-cce, .markdown-body .pl-sr .pl-sre, .markdown-body .pl-sr .pl-sra { color: #0a3069; } .markdown-body .pl-v, .markdown-body .pl-smw { color: #953800; } .markdown-body .pl-bu { color: #82071e; } .markdown-body .pl-ii { color: #f6f8fa; background-color: #82071e; } .markdown-body .pl-c2 { color: #f6f8fa; background-color: #cf222e; } .markdown-body .pl-sr .pl-cce { font-weight: bold; color: #116329; } .markdown-body .pl-ml { color: #3b2300; } .markdown-body .pl-mh, .markdown-body .pl-mh .pl-en, .markdown-body .pl-ms { font-weight: bold; color: #0550ae; } .markdown-body .pl-mi { font-style: italic; color: #1f2328; } .markdown-body .pl-mb { font-weight: bold; color: #1f2328; } .markdown-body .pl-md { color: #82071e; background-color: #ffebe9; } .markdown-body .pl-mi1 { color: #116329; background-color: #dafbe1; } .markdown-body .pl-mc { color: #953800; background-color: #ffd8b5; } .markdown-body .pl-mi2 { color: #d1d9e0; background-color: #0550ae; } .markdown-body .pl-mdr { font-weight: bold; color: #8250df; } .markdown-body .pl-ba { color: #59636e; } .markdown-body .pl-sg { color: #818b98; } .markdown-body .pl-corl { text-decoration: underline; color: #0a3069; } .markdown-body [role=button]:focus:not(:focus-visible), .markdown-body [role=tabpanel][tabindex="0"]:focus:not(:focus-visible), .markdown-body button:focus:not(:focus-visible), .markdown-body summary:focus:not(:focus-visible), .markdown-body a:focus:not(:focus-visible) { outline: none; box-shadow: none; } .markdown-body [tabindex="0"]:focus:not(:focus-visible), .markdown-body details-dialog:focus:not(:focus-visible) { outline: none; } .markdown-body g-emoji { display: inline-block; min-width: 1ch; font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; font-size: 1em; font-style: normal !important; font-weight: 400; line-height: 1; vertical-align: -0.075em; } .markdown-body g-emoji img { width: 1em; height: 1em; } .markdown-body .task-list-item { list-style-type: none; } .markdown-body .task-list-item label { font-weight: 400; } .markdown-body .task-list-item.enabled label { cursor: pointer; } .markdown-body .task-list-item+.task-list-item { margin-top: 0.25rem; } .markdown-body .task-list-item .handle { display: none; } .markdown-body .task-list-item-checkbox { margin: 0 .2em .25em -1.4em; vertical-align: middle; } .markdown-body ul:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em .25em .2em; } .markdown-body ol:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em .25em .2em; } .markdown-body .contains-task-list:hover .task-list-item-convert-container, .markdown-body .contains-task-list:focus-within .task-list-item-convert-container { display: block; width: auto; height: 24px; overflow: visible; clip: auto; } .markdown-body ::-webkit-calendar-picker-indicator { filter: invert(50%); } .markdown-body .markdown-alert { padding: 0.5rem 1rem; margin-bottom: 1rem; color: inherit; border-left: .25em solid #d1d9e0; } .markdown-body .markdown-alert>:first-child { margin-top: 0; } .markdown-body .markdown-alert>:last-child { margin-bottom: 0; } .markdown-body .markdown-alert .markdown-alert-title { display: flex; font-weight: 500; align-items: center; line-height: 1; } .markdown-body .markdown-alert.markdown-alert-note { border-left-color: #0969da; } .markdown-body .markdown-alert.markdown-alert-note .markdown-alert-title { color: #0969da; } .markdown-body .markdown-alert.markdown-alert-important { border-left-color: #8250df; } .markdown-body .markdown-alert.markdown-alert-important .markdown-alert-title { color: #8250df; } .markdown-body .markdown-alert.markdown-alert-warning { border-left-color: #9a6700; } .markdown-body .markdown-alert.markdown-alert-warning .markdown-alert-title { color: #9a6700; } .markdown-body .markdown-alert.markdown-alert-tip { border-left-color: #1a7f37; } .markdown-body .markdown-alert.markdown-alert-tip .markdown-alert-title { color: #1a7f37; } .markdown-body .markdown-alert.markdown-alert-caution { border-left-color: #cf222e; } .markdown-body .markdown-alert.markdown-alert-caution .markdown-alert-title { color: #d1242f; } .markdown-body>*:first-child>.heading-element:first-child { margin-top: 0 !important; } .markdown-body .highlight pre:has(+.zeroclipboard-container) { min-height: 52px; } ================================================ FILE: scripts/sync-version.sh ================================================ #!/bin/bash # 同步版本号脚本 # 从 tauri.conf.json 读取版本号并更新 iOS Info.plist # 获取当前版本号 VERSION=$(node -p "require('./src-tauri/tauri.conf.json').version") echo "同步版本号: $VERSION" # 更新 iOS Info.plist PLIST_PATH="src-tauri/gen/apple/note-gen_iOS/Info.plist" if [ -f "$PLIST_PATH" ]; then # 更新版本号 - 使用更精确的匹配模式 sed -i '' '/CFBundleShortVersionString/,//s/.*<\/string>/'$VERSION'<\/string>/' "$PLIST_PATH" sed -i '' '/CFBundleVersion/,//s/.*<\/string>/'$VERSION'<\/string>/' "$PLIST_PATH" echo "iOS 版本号已更新为: $VERSION" else echo "Info.plist 文件不存在,请先运行构建命令" fi ================================================ FILE: src/app/core/index.d.ts ================================================ declare module "note-gen/screenshot" { export interface ScreenshotImage { name: string; path: string; width: number; height: number; x: number; y: number; z: number; } } ================================================ FILE: src/app/core/layout.tsx ================================================ 'use client' import { ThemeProvider } from "@/components/theme-provider" import useSettingStore from "@/stores/setting" import { useEffect, useState } from "react"; import { initAllDatabases } from "@/db" import dayjs from "dayjs" import zh from "dayjs/locale/zh-cn"; import en from "dayjs/locale/en"; import { useI18n } from "@/hooks/useI18n" import useVectorStore from "@/stores/vector" import useImageStore from "@/stores/imageHosting" import useShortcutStore from "@/stores/shortcut" import useUpdateStore from "@/stores/update" import initQuickRecordText from "@/lib/shortcut/quick-record-text" import { useRouter, usePathname } from "next/navigation" import initShowWindow from "@/lib/shortcut/show-window" import { initMcp } from "@/lib/mcp/init" import { SearchDialog } from "@/components/search-dialog" import { ActivityDrawer } from "@/components/activity/activity-drawer" import { reportAppStart } from "@/lib/event-report" import { TitleBar } from "@/components/title-bar" import { Store } from '@tauri-apps/plugin-store' import { TextSizeProvider } from "@/contexts/text-size-context" import { SyncConfirmDialog } from "@/components/sync-confirm-dialog" import { applyThemeColors } from "@/lib/theme-utils" import emitter from "@/lib/emitter" export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { const { initSettingData, uiScale, customThemeColors } = useSettingStore() const { initMainHosting } = useImageStore() const { currentLocale } = useI18n() const { initShortcut } = useShortcutStore() const { initVectorDb } = useVectorStore() const { initUpdateStore, checkForUpdates } = useUpdateStore() const router = useRouter() const pathname = usePathname() const [searchOpen, setSearchOpen] = useState(false) const [activityOpen, setActivityOpen] = useState(false) // 重定向旧路径到新的 /core/main useEffect(() => { async function redirectOldPaths() { if (pathname === '/core/article' || pathname === '/core/record') { const store = await Store.load('store.json') await store.set('currentPage', '/core/main') await store.save() router.replace('/core/main') } } redirectOldPaths() }, [pathname, router]) useEffect(() => { let cancelled = false const initializeApp = async () => { try { initSettingData() initMainHosting() // 先完成数据库和默认工作区初始化,避免首次启动时其他逻辑抢先读取空目录或未建表数据库。 await initAllDatabases() if (cancelled) return initShortcut() await initVectorDb() if (cancelled) return initQuickRecordText() initShowWindow() initMcp() reportAppStart() await initUpdateStore() if (cancelled) return checkForUpdates() } catch (error) { console.error('Failed to initialize app core:', error) } } void initializeApp() return () => { cancelled = true } }, []) // 应用界面缩放 useEffect(() => { if (uiScale && uiScale !== 100) { document.documentElement.style.fontSize = `${uiScale}%` } }, [uiScale]) // 应用自定义主题颜色 useEffect(() => { applyThemeColors(customThemeColors) }, [customThemeColors]) useEffect(() => { switch (currentLocale) { case 'zh': dayjs.locale(zh); break; case 'en': dayjs.locale(en); break; default: break; } }, [currentLocale]) // 禁用浏览器后退快捷键(Backspace)和添加搜索快捷键(Cmd/Ctrl+F) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { // 搜索快捷键:Cmd+F (macOS) 或 Ctrl+F (Windows/Linux) if ((e.metaKey || e.ctrlKey) && e.key === 'f') { // 检查焦点是否在编辑器内 const target = e.target as HTMLElement const editorElement = document.getElementById('aritcle-md-editor') const isFocusInEditor = editorElement && editorElement.contains(target) // 如果焦点在编辑器内,触发编辑器搜索 if (isFocusInEditor) { e.preventDefault() // 触发编辑器内搜索 emitter.emit('editor-search-trigger' as any) return } // 否则打开全局搜索 e.preventDefault() setSearchOpen(true) return } // 如果按下 Backspace 键,且不在可编辑元素中 if (e.key === 'Backspace') { const target = e.target as HTMLElement const isEditable = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable || target.getAttribute('contenteditable') === 'true' // 如果在可编辑元素中,允许正常删除 if (isEditable) { return } // 否则阻止默认的后退行为 e.preventDefault() } } window.addEventListener('keydown', handleKeyDown) return () => { window.removeEventListener('keydown', handleKeyDown) } }, []) return ( setSearchOpen(true)} onActivityClick={() => setActivityOpen(open => !open)} activityOpen={activityOpen} />
{children}
); } ================================================ FILE: src/app/core/main/chat/agent-execution-status.tsx ================================================ import * as React from "react" import useChatStore from "@/stores/chat" import { AgentPanelWithRag } from "./agent-panel-with-rag" /** * Agent execution status component - displays real-time agent execution state * This component uses AgentPanelWithRag to show both RAG sources and Agent steps together */ export function AgentExecutionStatus() { const { agentState, setAgentState, currentConversationId, setAgentAutoApproveConversationId, setAgentAutoApproveRuntimeSkillId, } = useChatStore() // Handle confirmation const handleConfirm = (scope: 'once' | 'conversation' = 'once') => { if (!agentState.pendingConfirmation) return const confirmationRecord = { toolName: agentState.pendingConfirmation.toolName, params: agentState.pendingConfirmation.params, status: 'confirmed' as const, timestamp: Date.now(), scope, sessionApprovalType: agentState.pendingConfirmation.sessionApprovalType, sessionApprovalSkillId: agentState.pendingConfirmation.sessionApprovalSkillId, } if (scope === 'conversation' && currentConversationId !== null) { setAgentAutoApproveConversationId(currentConversationId) setAgentAutoApproveRuntimeSkillId( agentState.pendingConfirmation.sessionApprovalType === 'runtime-script-skill' ? agentState.pendingConfirmation.sessionApprovalSkillId || null : null ) } // Confirm while keeping isRunning: true, only clear pendingConfirmation setAgentState({ pendingConfirmation: undefined, confirmationHistory: [...agentState.confirmationHistory, confirmationRecord], isRunning: true // Explicitly keep running state }) } const handleCancel = () => { if (!agentState.pendingConfirmation) return const confirmationRecord = { toolName: agentState.pendingConfirmation.toolName, params: agentState.pendingConfirmation.params, status: 'cancelled' as const, timestamp: Date.now() } // Cancel and stop agent execution setAgentState({ pendingConfirmation: undefined, confirmationHistory: [...agentState.confirmationHistory, confirmationRecord], isRunning: false }) } return ( ) } ================================================ FILE: src/app/core/main/chat/agent-history.tsx ================================================ import * as React from "react" import { AgentPlan } from "@/components/ui/agent-plan" interface AgentHistoryProps { historyJson: string } /** * Agent history component - displays saved agent execution history * This component now uses the unified AgentPlan component for consistent styling */ export function AgentHistory({ historyJson }: AgentHistoryProps) { return ( ) } ================================================ FILE: src/app/core/main/chat/agent-panel-with-rag.tsx ================================================ "use client" import * as React from "react" import { AgentPlan } from "@/components/ui/agent-plan" import { FileText, ChevronRight, Database, ExternalLink } from "lucide-react" import { useTranslations } from "next-intl" import { useState } from "react" import useArticleStore from "@/stores/article" interface RagSourceDetail { filepath: string filename: string content: string } interface AgentPanelWithRagProps { // RAG 相关 ragSources?: string[] ragSourceDetails?: RagSourceDetail[] // Agent 历史模式 agentHistoryJson?: string // Agent 实时模式(如果需要) isRunning?: boolean isThinking?: boolean currentThought?: string thoughtHistory?: string[] completedSteps?: Array<{ thought: string action?: { tool: string; params: Record } observation?: string duration?: number }> currentAction?: string currentObservation?: string toolCalls?: Array<{ id: string toolName: string params: Record result?: { success: boolean; message?: string; data?: any; error?: string } status: "pending" | "running" | "success" | "error" timestamp: number }> pendingConfirmation?: { toolName: string params: Record originalContent?: string modifiedContent?: string filePath?: string canApproveForSession?: boolean sessionApprovalType?: "write" | "runtime-script-skill" sessionApprovalSkillId?: string } confirmationHistory?: Array<{ toolName: string params: Record status: "pending" | "confirmed" | "cancelled" timestamp: number scope?: "once" | "conversation" sessionApprovalType?: "write" | "runtime-script-skill" sessionApprovalSkillId?: string }> currentStepStartTime?: number onConfirm?: (scope?: "once" | "conversation") => void onCancel?: () => void } /** * Agent 面板组件 - 将知识库检索和 Agent 执行合并在一起 */ export function AgentPanelWithRag({ ragSources = [], ragSourceDetails = [], agentHistoryJson, isRunning = false, isThinking = false, currentThought = "", thoughtHistory = [], completedSteps = [], currentAction = "", currentObservation = "", toolCalls = [], pendingConfirmation, confirmationHistory = [], currentStepStartTime, onConfirm, onCancel, }: AgentPanelWithRagProps) { const t = useTranslations() const [isRagExpanded, setIsRagExpanded] = useState(false) const [expandedFiles, setExpandedFiles] = useState([]) const { setActiveFilePath, readArticle } = useArticleStore() // 创建文件名到详情的映射 const detailMap = React.useMemo( () => new Map(ragSourceDetails.map((d) => [d.filename, d])), [ragSourceDetails] ) // 打开文件 const handleOpenFile = (e: React.MouseEvent, filepath: string) => { e.stopPropagation() setActiveFilePath(filepath) readArticle(filepath) } // 切换单个文件的展开状态 const toggleFileExpansion = (filename: string) => { setExpandedFiles((prev) => prev.includes(filename) ? prev.filter((f) => f !== filename) : [...prev, filename] ) } // 确定模式:如果有 agentHistoryJson,使用历史模式;否则使用实时模式 const mode: "live" | "history" = agentHistoryJson ? "history" : "live" // 如果既没有 RAG 也没有 Agent 内容,不渲染 const hasRag = ragSources.length > 0 const hasAgent = agentHistoryJson || isRunning || thoughtHistory.length > 0 if (!hasRag && !hasAgent) { return null } return (
    {/* 知识库检索步骤 */} {hasRag && ( <>
  • setIsRagExpanded(!isRagExpanded)} >
    {t("record.chat.ragSources.label", { count: ragSources.length })}
  • {/* 文件列表 */} {isRagExpanded && ragSources.map((source) => { const hasDetail = detailMap.has(source) const detail = detailMap.get(source) const isFileExpanded = expandedFiles.includes(source) return (
  • hasDetail && toggleFileExpansion(source)} >
    {source} {hasDetail && ( )}
    {/* 展开的详情内容 */} {isFileExpanded && hasDetail && detail?.content && (
    引用内容
    {detail?.filepath && ( )}

    {detail.content}

    )}
  • ) })} )} {/* Agent 执行步骤 - 使用 AgentPlan embedded 模式 */} {hasAgent && ( )}
) } ================================================ FILE: src/app/core/main/chat/chat-clipboard.tsx ================================================ 'use client' import { useState, useEffect } from 'react'; import { BaseDirectory, copyFile, exists, mkdir, readFile } from '@tauri-apps/plugin-fs'; import useTagStore from "@/stores/tag"; import useSettingStore from "@/stores/setting"; import useMarkStore from "@/stores/mark"; import { v4 as uuid } from 'uuid' import ocr from "@/lib/ocr"; import { fetchAiDesc, fetchAiDescByImage } from "@/lib/ai/description"; import { insertMark, Mark } from "@/db/marks"; import { CheckCircle, Highlighter, ImagePlus, LoaderCircle } from "lucide-react"; import { Chat } from "@/db/chats"; import { LocalImage } from '@/components/local-image'; import MessageControl from './message-control'; import useChatStore from '@/stores/chat'; import { Button } from '@/components/ui/button'; import { useTranslations } from 'next-intl'; import { uploadImage } from '@/lib/imageHosting'; export function ChatClipboard({chat}: { chat: Chat }) { const [loading, setLoading] = useState(false) const [type] = useState<'image' | 'text'>(chat.image ? 'image' : 'text') const [countdown, setCountdown] = useState(5) // 5 seconds countdown const [isCountingDown, setIsCountingDown] = useState(!chat.inserted) // Start countdown if not recorded const { currentTagId, fetchTags, getCurrentTag } = useTagStore() const { primaryModel, primaryImageMethod, enableImageRecognition } = useSettingStore() const { fetchMarks, addQueue, setQueue, removeQueue } = useMarkStore() const { updateInsert, deleteChat } = useChatStore() const t = useTranslations('record.queue') useEffect(() => { if (chat.inserted) { setIsCountingDown(false); return; } const timer = setTimeout(() => { if (!chat.inserted) { deleteChat(chat.id); } }, 5000); return () => clearTimeout(timer); }, [chat.id, chat.inserted, deleteChat]); useEffect(() => { if (!isCountingDown) return; if (countdown <= 0) return; const interval = setInterval(() => { setCountdown(prev => prev - 1); }, 1000); return () => clearInterval(interval); }, [countdown, isCountingDown]); useEffect(() => { if (chat.inserted) { setIsCountingDown(false); } }, [chat.inserted]); async function handleInset() { setLoading(true) const queueId = uuid() // 获取文件后缀 addQueue({ queueId, tagId: currentTagId!, progress: '保存图片', type: 'image', startTime: Date.now() }) const isImageFolderExists = await exists('image', { baseDir: BaseDirectory.AppData}) if (!isImageFolderExists) { await mkdir('image', { baseDir: BaseDirectory.AppData}) } if (!chat.image) return const fromPath = chat.image.slice(1) const toPath = `image/${queueId}.png` await copyFile(fromPath, toPath, { fromPathBaseDir: BaseDirectory.AppData, toPathBaseDir: BaseDirectory.AppData}) let content = '' let desc = '' // Skip image recognition if disabled if (!enableImageRecognition) { setQueue(queueId, { progress: t('save') }); content = '' desc = '' } else if (primaryImageMethod === 'vlm') { // 使用 VLM 识别图片 setQueue(queueId, { progress: t('ai') }); const file = await readFile(toPath, { baseDir: BaseDirectory.AppData }) const base64 = `data:image/png;base64,${Buffer.from(file).toString('base64')}` content = await fetchAiDescByImage(base64) || 'VLM Error' desc = content } else { // 使用 OCR 识别图片 setQueue(queueId, { progress: t('ocr') }); content = await ocr(toPath) setQueue(queueId, { progress: t('ai') }); if (primaryModel) { desc = await fetchAiDesc(content).then(res => res ? res : content) || content } else { desc = content } } const mark: Partial = { tagId: currentTagId, type: 'image', content, url: `${queueId}.png`, desc, } setQueue(queueId, { progress: t('upload') }); const fileData = await readFile(toPath, { baseDir: BaseDirectory.AppData }) const blob = new Blob([new Uint8Array(fileData)], { type: 'image/png' }) const file = new File([blob], `${queueId}.png`, { type: 'image/png' }) // 上传图片 const url = await uploadImage(file) if (url) { mark.url = url } removeQueue(queueId) await updateInsert(chat.id) setLoading(false) await insertMark(mark) await fetchMarks() await fetchTags() getCurrentTag() } async function handleTextInset() { await updateInsert(chat.id) const mark: Partial = { tagId: currentTagId, type: 'text', content: chat.content, desc: '', } insertMark(mark) fetchMarks() fetchTags() getCurrentTag() } return ( type === 'image' && chat.image ?

{t('detected')} {isCountingDown && ( {countdown}s )}

{ loading ? : ( chat.inserted? :
) }
:

{t('detected')} {isCountingDown && ( {countdown}s )}

{chat.content}

{ chat.inserted ? :
}
) } ================================================ FILE: src/app/core/main/chat/chat-content.tsx ================================================ import React from 'react' import useChatStore from '@/stores/chat' import useTagStore from '@/stores/tag' import { ArrowDownToLine, X, Loader2, QuoteIcon } from 'lucide-react' import { useCallback, useEffect, useMemo, useState } from 'react' import { Chat } from '@/db/chats' import ChatPreview from './chat-preview' import './chat.css' import { NoteOutput } from './message-control/note-output' import { MarkText } from './message-control/mark-text' import { ChatClipboard } from './chat-clipboard' import MessageControl from './message-control' import ChatEmpty from './chat-empty' import { useTranslations } from 'next-intl' import ChatThinking from './chat-thinking' import { Separator } from '@/components/ui/separator' import { Button } from '@/components/ui/button' import { McpToolCallCard } from './mcp-tool-call' import { AgentExecutionStatus } from './agent-execution-status' import { AgentPanelWithRag } from './agent-panel-with-rag' import { ChatImages } from "./chat-images" import { useIsMobile } from '@/hooks/use-mobile' const BOTTOM_THRESHOLD = 24 const USER_SCROLL_GRACE_MS = 300 const ChatContent = React.memo(function ChatContent() { const { chats, init, agentState, loading } = useChatStore() const { currentTagId } = useTagStore() const [isOnBottom, setIsOnBottom] = useState(true) const [autoScrollEnabled, setAutoScrollEnabled] = useState(true) const wrapperRef = React.useRef(null) const contentRef = React.useRef(null) const bottomAnchorRef = React.useRef(null) const programmaticScrollRef = React.useRef(false) const autoScrollEnabledRef = React.useRef(true) const delayedScrollTimeoutRef = React.useRef | null>(null) const lastUserScrollAtRef = React.useRef(0) const isNearBottom = useCallback((element: Element) => { return element.scrollHeight - element.scrollTop - element.clientHeight <= BOTTOM_THRESHOLD }, []) const handleScroll = useCallback(() => { const md = wrapperRef.current if (!md) return const onBottom = isNearBottom(md) setIsOnBottom(onBottom) if (programmaticScrollRef.current) { if (onBottom) { programmaticScrollRef.current = false } return } const isLikelyUserScroll = Date.now() - lastUserScrollAtRef.current < USER_SCROLL_GRACE_MS // 只有用户主动离开底部时才关闭自动滚动 if (onBottom) { setAutoScrollEnabled(true) } else if (isLikelyUserScroll) { setAutoScrollEnabled(false) } }, [isNearBottom]) const markUserScrollIntent = useCallback(() => { lastUserScrollAtRef.current = Date.now() }, []) const performAutoScroll = useCallback(() => { programmaticScrollRef.current = true bottomAnchorRef.current?.scrollIntoView({ block: 'end' }) setIsOnBottom(true) requestAnimationFrame(() => { setTimeout(() => { programmaticScrollRef.current = false const md = wrapperRef.current if (md) { setIsOnBottom(isNearBottom(md)) } }, 0) }) if (delayedScrollTimeoutRef.current) { clearTimeout(delayedScrollTimeoutRef.current) } delayedScrollTimeoutRef.current = setTimeout(() => { if (!autoScrollEnabledRef.current) return programmaticScrollRef.current = true bottomAnchorRef.current?.scrollIntoView({ block: 'end' }) setIsOnBottom(true) requestAnimationFrame(() => { setTimeout(() => { programmaticScrollRef.current = false const md = wrapperRef.current if (md) { setIsOnBottom(isNearBottom(md)) } }, 0) }) }, 500) }, [isNearBottom]) // 手动滚动到底部并启用自动滚动 const handleScrollToBottom = useCallback(() => { performAutoScroll() setAutoScrollEnabled(true) }, [performAutoScroll]) useEffect(() => { const md = wrapperRef.current if (!md) return const handleTouchStart = () => markUserScrollIntent() const handleTouchMove = () => markUserScrollIntent() const handleWheel = () => markUserScrollIntent() const handlePointerDown = () => markUserScrollIntent() md.addEventListener('scroll', handleScroll) md.addEventListener('touchstart', handleTouchStart, { passive: true }) md.addEventListener('touchmove', handleTouchMove, { passive: true }) md.addEventListener('wheel', handleWheel, { passive: true }) md.addEventListener('pointerdown', handlePointerDown, { passive: true }) return () => { md.removeEventListener('scroll', handleScroll) md.removeEventListener('touchstart', handleTouchStart) md.removeEventListener('touchmove', handleTouchMove) md.removeEventListener('wheel', handleWheel) md.removeEventListener('pointerdown', handlePointerDown) } }, [handleScroll, markUserScrollIntent]) useEffect(() => { init(currentTagId) }, [currentTagId, init]) useEffect(() => { autoScrollEnabledRef.current = autoScrollEnabled }, [autoScrollEnabled]) useEffect(() => { const md = wrapperRef.current const content = contentRef.current if (!md || !content) return const syncScrollState = () => { const onBottom = isNearBottom(md) if (autoScrollEnabled) { performAutoScroll() return } setIsOnBottom(onBottom) } const observer = new ResizeObserver(syncScrollState) const mutationObserver = new MutationObserver(() => { syncScrollState() }) observer.observe(content) mutationObserver.observe(content, { childList: true, subtree: true, characterData: true, }) return () => { observer.disconnect() mutationObserver.disconnect() } }, [autoScrollEnabled, isNearBottom, performAutoScroll]) // 监听消息变化,仅在启用自动滚动时才滚动 useEffect(() => { if (autoScrollEnabled) { performAutoScroll() } }, [chats, autoScrollEnabled, performAutoScroll]) // Agent 执行时,仅在启用自动滚动时才滚动到底部 useEffect(() => { if (autoScrollEnabled && agentState.isRunning) { performAutoScroll() } }, [agentState.currentThought, agentState.thoughtHistory, agentState.pendingConfirmation, agentState.isRunning, autoScrollEnabled, performAutoScroll]) // Loading 状态变化时,仅在启用自动滚动时才滚动到底部 useEffect(() => { if (autoScrollEnabled && loading) { performAutoScroll() } }, [loading, autoScrollEnabled, performAutoScroll]) useEffect(() => { return () => { if (delayedScrollTimeoutRef.current) { clearTimeout(delayedScrollTimeoutRef.current) } } }, []) // 判断是否应该显示 loading:loading=true 且最后一个 AI 消息还没有内容 const shouldShowLoading = useMemo(() => { if (!loading) return false if (agentState.isRunning) return false const lastChat = chats[chats.length - 1] // 如果最后一个消息是 system 角色且有内容或思考内容,说明 AI 已经开始输出了 if (lastChat?.role === 'system' && (lastChat.content || lastChat.thinking)) { return false } return true }, [loading, agentState.isRunning, chats]) return
{ chats.length ? chats.map((chat) => { return }) : } {/* Loading 指示器 - 服务器等待时显示 */} {shouldShowLoading && (
正在思考...
)}
{ !isOnBottom && }
}) ChatContent.displayName = 'ChatContent' const MessageWrapper = React.memo(function MessageWrapper({ chat, children }: { chat: Chat, children: React.ReactNode }) { const { deleteChat } = useChatStore() const [showDelete, setShowDelete] = useState(false) const isMobile = useIsMobile() const handleDelete = useCallback(() => { deleteChat(chat.id) }, [chat.id, deleteChat]) const shouldShowDelete = showDelete // 用户消息:右对齐,带边框和背景 if (chat.role === 'user') { return (
{ if (!isMobile) setShowDelete(true) }} onMouseLeave={() => { if (!isMobile) setShowDelete(false) }} onClick={() => { if (isMobile) setShowDelete((prev) => !prev) }} >
{children}
{shouldShowDelete && ( )}
) } // AI 消息:左对齐,无边框,无图标 return (
{children}
) }) MessageWrapper.displayName = 'MessageWrapper' const Message = React.memo(function Message({ chat }: { chat: Chat }) { const t = useTranslations() const { deleteChat, getMcpToolCallsByChatId, loading, agentState } = useChatStore() const content = chat.content const isActiveAgentMessage = chat.role === 'system' && agentState.activeChatId === chat.id const isLiveAgentVisible = isActiveAgentMessage && (agentState.isRunning || agentState.isFinalAnswerMode) const handleRemoveClearContext = useCallback(() => { deleteChat(chat.id) }, [chat.id, deleteChat]) // 解析 RAG 来源 const ragSources = useMemo(() => { if (!chat.ragSources) return [] try { return JSON.parse(chat.ragSources) as string[] } catch { return [] } }, [chat.ragSources]) // 解析 RAG 来源详情 const ragSourceDetails = useMemo(() => { if (!chat.ragSourceDetails) return [] try { return JSON.parse(chat.ragSourceDetails) as Array<{ filepath: string filename: string content: string }> } catch { return [] } }, [chat.ragSourceDetails]) // 获取该消息关联的 MCP 工具调用 const mcpToolCalls = useMemo(() => getMcpToolCallsByChatId(chat.id), [chat.id, getMcpToolCallsByChatId]) // 解析图片数组 const images = useMemo(() => { if (!chat.images) return [] try { return JSON.parse(chat.images) as string[] } catch { return [] } }, [chat.images]) // 解析引用数据 const quoteData = useMemo(() => { if (!chat.quoteData) return null try { return JSON.parse(chat.quoteData) as { quote: string fullContent: string fileName: string startLine: number endLine: number from: number to: number articlePath: string } } catch { return null } }, [chat.quoteData]) switch (chat.type) { case 'clear': return

{t('record.chat.input.clearContext.tooltip')}

case 'clipboard': return case 'note': return {

{t('record.chat.content.organize')}

{
}
}
default: // 检查 AI 消息是否有实际内容(没有内容时不渲染) const hasContent = chat.role === 'system' && ( !!content || !!chat.thinking || (chat.agentHistory && chat.agentHistory.length > 0) || ragSources.length > 0 || ragSourceDetails.length > 0 || mcpToolCalls.length > 0 || isLiveAgentVisible ) // 用户消息或有内容的 AI 消息才渲染 if (chat.role === 'system' && !hasContent) { return null } return {chat.role === 'system' ? ( // AI 消息:所有内容放在一个容器中
{/* 合并的 RAG 和 Agent 面板 - 只在有 agentHistory 时显示(历史模式) */} {/* 实时执行时,RAG 和 Agent 步骤在 AgentExecutionStatusWrapper 中统一显示 */} {chat.agentHistory && ( )} {isLiveAgentVisible && (
{!agentState.isFinalAnswerMode && (agentState.isRunning || agentState.completedSteps?.length > 0 || agentState.thoughtHistory?.length > 0) && ( )} {agentState.isFinalAnswerMode && agentState.finalAnswerContent && ( )}
)} {/* MCP 工具调用展示 */} {mcpToolCalls.length > 0 && (
{mcpToolCalls.map(toolCall => ( ))}
)}
) : ( // 用户消息
{/* 显示用户消息中的图片 */} {images.length > 0 && } {/* 显示用户消息中的引用 */} {quoteData && (
{quoteData.startLine !== -1 && quoteData.endLine !== -1 ? ( quoteData.startLine === quoteData.endLine ? ( t('record.chat.quote.lineSingle', { fileName: quoteData.fileName, line: quoteData.startLine }) ) : ( t('record.chat.quote.lineRange', { fileName: quoteData.fileName, startLine: quoteData.startLine, endLine: quoteData.endLine }) ) ) : ( t('record.chat.quote.noLine', { fileName: quoteData.fileName }) )}
{quoteData.fullContent}
)} {content && (
{content}
)}
)}
} }) Message.displayName = 'Message' export default ChatContent ================================================ FILE: src/app/core/main/chat/chat-empty.tsx ================================================ 'use client' import { useTranslations } from 'next-intl' import useChatStore from '@/stores/chat' import { useMemo, useState, useEffect } from 'react' import { Trash2, FileEdit, FileText, Lightbulb, ArrowRight, MessageCircle } from 'lucide-react' import { Button } from '@/components/ui/button' import emitter from '@/lib/emitter' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import 'dayjs/locale/zh-cn' import 'dayjs/locale/en' import useSettingStore from '@/stores/setting' import { QuickPrompt } from '@/lib/ai/placeholder' // 初始化 dayjs 插件 dayjs.extend(relativeTime) // 格式化相对时间 function formatRelativeTime(timestamp: number, locale: string): string { const dayjsLocale = locale === 'en' ? 'en' : 'zh-cn' return dayjs(timestamp).locale(dayjsLocale).fromNow() } export default function ChatEmpty() { const t = useTranslations('record.chat.empty') const { language } = useSettingStore() const { conversations, currentConversationId, switchConversation, deleteConversation } = useChatStore() const [aiPrompts, setAiPrompts] = useState([]) // 快速 prompt 模板 - 默认模板 const defaultQuickPrompts = useMemo(() => [ { id: 1, icon: , text: t('quickPrompts.writeNote') || '帮我写一篇笔记' }, { id: 2, icon: , text: t('quickPrompts.summarize') || '帮我总结这段内容' }, { id: 3, icon: , text: t('quickPrompts.brainstorm') || '帮我头脑风暴一些想法' }, ], [t]) // 监听来自 chat-input 的 AI 提示词生成事件 useEffect(() => { const handleAiPromptsGenerated = (prompts: QuickPrompt[]) => { if (prompts.length >= 3) { setAiPrompts(prompts) } } emitter.on('ai-prompts-generated', handleAiPromptsGenerated) return () => { emitter.off('ai-prompts-generated', handleAiPromptsGenerated) } }, []) // 使用 AI 生成的提示词或默认提示词 const quickPrompts = useMemo(() => { // 如果 AI 成功生成了至少3条提示词,使用 AI 生成的 if (aiPrompts.length >= 3) { return aiPrompts.slice(0, 3).map((prompt, index) => ({ id: `ai-${index}`, icon: , text: prompt.text })) } // 否则使用默认提示词 return defaultQuickPrompts }, [aiPrompts, defaultQuickPrompts]) const handleQuickPrompt = (prompt: string) => { // 将文本插入到输入框 emitter.emit('quick-prompt-insert', prompt) } // 获取最近 3 条会话(排除当前会话和空会话) const recentConversations = useMemo(() => { return conversations .filter(c => c.id !== currentConversationId && c.messageCount > 0) .sort((a, b) => b.updatedAt - a.updatedAt) .slice(0, 3) }, [conversations, currentConversationId]) const handleSwitchConversation = async (id: number) => { await switchConversation(id) } const handleDelete = async (id: number) => { await deleteConversation(id) } return (
{/* Dashed background pattern - only visible when empty */}
{/* Gradient fade overlay on edges */}
{/* Header */}

{t('title')}

{t('subtitle')}

{/* Quick Prompts */}

{t('quickPrompts.title') || '快速开始'}

{quickPrompts.map((prompt) => (
handleQuickPrompt(prompt.text)} className="w-full bg-primary-foreground px-4 h-10 rounded-lg border hover:border-primary/50 transition-colors text-left group cursor-pointer flex items-center" >
{prompt.icon} {prompt.text}
))}
{/* Recent Conversations */} {recentConversations.length > 0 && (

{t('recentConversations')}

{recentConversations.map(conv => (
handleSwitchConversation(conv.id)} className="w-full px-1 h-5 rounded-lg transition-colors text-left group cursor-pointer flex items-center" >
{conv.title}
{/* 时间戳 - 悬停时隐藏 */} {formatRelativeTime(conv.updatedAt, language)} {/* 删除按钮 - 悬停时显示 */}
))}
)}
) } ================================================ FILE: src/app/core/main/chat/chat-footer.tsx ================================================ "use client" import { BotMessageSquare, BotOff, Drama } from "lucide-react" import usePromptStore from "@/stores/prompt" import useSettingStore from "@/stores/setting" import { useTranslations } from "next-intl" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" export function ChatFooter() { const t = useTranslations('record.chat.header') const { currentPrompt } = usePromptStore() const { primaryModel, aiModelList } = useSettingStore() // 查找当前选中的模型 const findSelectedModel = () => { if (!primaryModel || !aiModelList) return null for (const config of aiModelList) { // 检查新的 models 数组结构 if (config.models && config.models.length > 0) { const targetModel = config.models.find(model => model.id === primaryModel) if (targetModel) { return { model: targetModel.model, configTitle: config.title } } } else { // 向后兼容:处理旧的单模型结构 if (config.key === primaryModel) { return { model: config.model, configTitle: config.title } } } } return null } const selectedModel = findSelectedModel() return (
{currentPrompt?.title}

{currentPrompt?.title || '-'}

{selectedModel ? ( <> {selectedModel.model} ({selectedModel.configTitle}) ) : ( <> {t('noModel')} )}

{selectedModel ? `${selectedModel.model} (${selectedModel.configTitle})` : t('noModel')}

) } ================================================ FILE: src/app/core/main/chat/chat-header.tsx ================================================ "use client" import { useState, useMemo } from 'react' import { MessageSquarePlus, ChevronDown, Search, Trash2 } from "lucide-react" import { TooltipButton } from "@/components/tooltip-button" import useChatStore from "@/stores/chat" import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { useTranslations } from 'next-intl' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import 'dayjs/locale/zh-cn' import 'dayjs/locale/en' import useSettingStore from '@/stores/setting' dayjs.extend(relativeTime) function formatRelativeTime(timestamp: number, locale: string): string { const dayjsLocale = locale === 'en' ? 'en' : 'zh-cn' return dayjs(timestamp).locale(dayjsLocale).fromNow() } export function ChatHeader() { const { startNewConversation, conversations, currentConversationId, switchConversation, deleteConversation, loading } = useChatStore() const { language } = useSettingStore() const t = useTranslations() const tEmpty = useTranslations('record.chat.empty') const [showHistoryDropdown, setShowHistoryDropdown] = useState(false) const [searchQuery, setSearchQuery] = useState('') // 没有消息或正在加载时禁用新对话按钮 const hasCurrentMessages = conversations.some(c => c.id === currentConversationId && c.messageCount > 0) const isDisabled = !hasCurrentMessages || loading // 过滤并排序会话(排除空会话) const filteredConversations = useMemo(() => { return conversations .filter(c => c.messageCount > 0) .filter(c => c.title.toLowerCase().includes(searchQuery.toLowerCase())) .sort((a, b) => { if (a.isPinned && !b.isPinned) return -1 if (!a.isPinned && b.isPinned) return 1 return b.updatedAt - a.updatedAt }) }, [conversations, searchQuery]) // 当前会话标题(如果有消息的话) const currentConversation = conversations.find(c => c.id === currentConversationId) const dropdownTitle = currentConversation && currentConversation.messageCount > 0 ? currentConversation.title : tEmpty('conversationHistory') return (
{/* 左侧:历史对话下拉 */}
setSearchQuery(e.target.value)} className="pl-8 h-8 text-sm" />
{filteredConversations.length === 0 ? (
{searchQuery ? tEmpty('noMatchingConversations') : tEmpty('noConversationHistory')}
) : (
{filteredConversations.map(conv => (
switchConversation(conv.id)} >
{conv.title}
{formatRelativeTime(conv.updatedAt, language)}
))}
)}
{/* 右侧:新建对话 */} } tooltipText={t('record.chat.input.newChat')} side="bottom" onClick={() => startNewConversation()} disabled={isDisabled} />
) } ================================================ FILE: src/app/core/main/chat/chat-images.tsx ================================================ "use client" import Image from "next/image" import { useState } from "react" import { Dialog, DialogContent } from "@/components/ui/dialog" interface ChatImagesProps { images: string[] } export function ChatImages({ images }: ChatImagesProps) { const [selectedImage, setSelectedImage] = useState(null) if (!images || images.length === 0) return null return ( <>
{images.map((imageUrl, index) => (
setSelectedImage(imageUrl)} > {`Image
))}
{selectedImage && ( setSelectedImage(null)}>
Full size image
)} ) } ================================================ FILE: src/app/core/main/chat/chat-input.tsx ================================================ "use client" import * as React from "react" import { useEffect, useMemo, useRef, useState, useCallback } from "react" import useSettingStore from "@/stores/setting" import { Textarea } from "@/components/ui/textarea" import useChatStore from "@/stores/chat" import useMarkStore from "@/stores/mark" import useArticleStore from "@/stores/article" import { fetchAiQuickPrompts } from "@/lib/ai/placeholder" import { useTranslations } from 'next-intl' import { useLocalStorage } from 'react-use'; import { ModelSelect } from "./model-select" import { getWorkspacePath } from "@/lib/workspace" import { PromptSelect } from "./prompt-select" import { ChatSend } from "./chat-send" import { LinkedFileDisplay } from "./file-link" import { LinkedResource, MarkdownFile, LinkedFolder } from "@/lib/files" import { McpButton } from "./mcp-button" import { RagSwitch } from "./rag-switch" import { ClipboardMonitor } from "./clipboard-monitor" import emitter from "@/lib/emitter" import { ChatToolsDrawer } from "@/app/mobile/chat/components/chat-tools-drawer" import { useIsMobile } from '@/hooks/use-mobile' import { ImageAttachments, ImageAttachment } from "./image-attachments" import { ImageIcon } from "lucide-react" import { TooltipButton } from "@/components/tooltip-button" import { isMobileDevice } from '@/lib/check' import { QuoteDisplay } from "./quote-display" import type { PendingQuote } from "@/stores/chat" import { convertFileSrc } from "@tauri-apps/api/core" import { readTextFile, writeFile, BaseDirectory, exists } from "@tauri-apps/plugin-fs" import { ShineBorder } from "@/components/ui/shine-border" import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, DragEndEvent, } from '@dnd-kit/core' import { arrayMove, SortableContext, horizontalListSortingStrategy, useSortable, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { buildTypingFrames } from './onboarding-typing' // 可排序的工具栏项组件 - 定义在外部以避免每次 ChatInput re-render 时重新创建 interface SortableToolbarItemProps { id: string } const SortableToolbarItem = React.memo(function SortableToolbarItem({ id }: SortableToolbarItemProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id }) const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, } // 渲染对应的工具栏组件 const renderToolbarItem = () => { switch (id) { case 'modelSelect': return case 'promptSelect': return case 'mcpButton': return case 'ragSwitch': return case 'clipboardMonitor': return default: return null } } return (
{renderToolbarItem()}
) }) SortableToolbarItem.displayName = 'SortableToolbarItem' export const ChatInput = React.memo(function ChatInput() { const [text, setText] = useState("") const { primaryModel, chatToolbarConfigPc, setChatToolbarConfigPc } = useSettingStore() const { chats, loading, setLinkedResource: setChatLinkedResource, setLinkedResourcePreview, onboardingPromptDraft, setOnboardingPromptDraft, pendingQuote, setPendingQuote, clearPendingQuote, } = useChatStore() const { marks, trashState } = useMarkStore() const { activeFilePath } = useArticleStore() const [isComposing, setIsComposing] = useState(false) const [placeholder, setPlaceholder] = useState('') const t = useTranslations() const [inputHistory, setInputHistory] = useLocalStorage('chat-input-history', []) const [historyIndex, setHistoryIndex] = useState(-1) const [tempInput, setTempInput] = useState('') const [linkedResource, setLinkedResource] = useState(null) const [attachedImages, setAttachedImages] = useState([]) const chatSendRef = useRef(null) const isMobile = useIsMobile() const textareaRef = useRef(null) const placeholderTimerRef = useRef(null) const imageInputRef = useRef(null) const isMobileDevice_ = isMobileDevice() const onboardingAgentPromptArmedRef = useRef(false) const onboardingTypingTimerRefs = useRef([]) const applyTypedText = useCallback((value: string) => { setText(value) const textarea = textareaRef.current if (!textarea) { return } window.requestAnimationFrame(() => { textarea.style.height = 'auto' const newHeight = Math.min(textarea.scrollHeight, 240) textarea.style.height = `${newHeight}px` }) }, []) // 拖拽传感器配置(仅桌面端) const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 8, // 移动8px后才开始拖拽,避免误触 }, }) ) // 添加输入到历史记录 function addToHistory(input: string) { if (!input.trim()) return const newHistory = [input, ...(inputHistory || []).filter(item => item !== input)] // 限制历史记录数量为50条 const limitedHistory = newHistory.slice(0, 50) setInputHistory(limitedHistory) } // 处理历史记录导航 function navigateHistory(direction: 'up' | 'down', currentText: string) { if (!inputHistory || inputHistory.length === 0) return let newIndex: number if (direction === 'up') { // 保存当前输入内容(第一次向上时) if (historyIndex === -1) { setTempInput(currentText) } newIndex = historyIndex + 1 if (newIndex >= inputHistory.length) { newIndex = inputHistory.length - 1 } } else { newIndex = historyIndex - 1 if (newIndex < -1) { newIndex = -1 } } setHistoryIndex(newIndex) if (newIndex === -1) { // 恢复到原本输入的内容 setText(tempInput) } else { setText(inputHistory[newIndex]) } } // 移除关联文件 function removeLinkedFile() { setLinkedResource(null) setChatLinkedResource(null) } function removeImage(id: string) { setAttachedImages(prev => prev.filter(img => img.id !== id)) } function removeQuote() { clearPendingQuote() } async function handleSelectLocalImages() { try { // 移动端使用 HTML5 file input if (isMobileDevice_) { imageInputRef.current?.click() return } // PC端使用 Tauri dialog const { open } = await import('@tauri-apps/plugin-dialog') const selected = await open({ multiple: true, filters: [{ name: 'Images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg'] }] }) if (selected && Array.isArray(selected)) { const newImages: ImageAttachment[] = selected.map((path) => ({ id: `local-${Date.now()}-${Math.random()}`, url: convertFileSrc(path), name: path.split('/').pop() || path, source: 'file' as const })) setAttachedImages(prev => [...prev, ...newImages]) } } catch (error) { console.error('Failed to select files:', error) } } // 移动端图片选择,交给系统决定从相册还是相机获取 async function handleSelectFromGallery() { if (isMobileDevice_) { if (imageInputRef.current) { imageInputRef.current.removeAttribute('capture') imageInputRef.current.click() } } } // 处理移动端文件选择 async function handleImageInputChange(event: React.ChangeEvent) { try { const files = event.target.files if (!files || files.length === 0) return const newImages: ImageAttachment[] = [] for (let i = 0; i < files.length; i++) { const file = files[i] const url = URL.createObjectURL(file) newImages.push({ id: `local-${Date.now()}-${Math.random()}`, url, name: file.name, source: 'file' as const }) } setAttachedImages(prev => [...prev, ...newImages]) // 重置 input event.target.value = '' } catch (error) { console.error('Error in handleImageInputChange:', error) } } async function handlePaste(e: React.ClipboardEvent) { const items = e.clipboardData?.items if (!items) return const imageItems = Array.from(items).filter(item => item.type.startsWith('image/')) if (imageItems.length === 0) return e.preventDefault() const newImages: ImageAttachment[] = [] for (const item of imageItems) { const blob = item.getAsFile() if (!blob) continue try { const arrayBuffer = await blob.arrayBuffer() const uint8Array = new Uint8Array(arrayBuffer) const fileName = `paste-${Date.now()}-${Math.random().toString(36).substring(7)}.png` const filePath = `screenshot/${fileName}` await writeFile(filePath, uint8Array, { baseDir: BaseDirectory.AppData }) const fullPath = await (async () => { const { appDataDir, join } = await import('@tauri-apps/api/path') const appData = await appDataDir() return await join(appData, filePath) })() newImages.push({ id: `paste-${Date.now()}-${Math.random()}`, url: convertFileSrc(fullPath), name: fileName, source: 'paste' }) } catch (error) { console.error('Failed to save pasted image:', error) } } if (newImages.length > 0) { setAttachedImages(prev => [...prev, ...newImages]) } } // 处理发送后的清理工作 function handleSent() { if (onboardingAgentPromptArmedRef.current) { onboardingAgentPromptArmedRef.current = false emitter.emit('onboarding-step-complete', { step: 'ai-polish' }) } addToHistory(text) setText('') setHistoryIndex(-1) setAttachedImages([]) clearPendingQuote() const textarea = document.querySelector('textarea') if (textarea) { textarea.style.height = 'auto' } } // 获取输入框占位符 async function genInputPlaceholder() { if (!primaryModel) return if (trashState) return const lastClearIndex = chats.findLastIndex(item => item.type === 'clear') const chatsAfterClear = chats.slice(lastClearIndex + 1) const request_content = ` ${chatsAfterClear.slice(0, 5).map(item => item.content?.slice(0, 60)).join(';\n\n')} `.trim() // 使用 fetchAiQuickPrompts 获取4条提示词 const prompts = await fetchAiQuickPrompts(request_content) // 发送事件给 chat-empty 组件,显示前3条 if (prompts.length >= 3) { emitter.emit('ai-prompts-generated', prompts) } // 取第4条作为 placeholder if (prompts.length >= 4 && prompts[3]?.text) { setPlaceholder(prompts[3].text + ' [Tab]') } } // 防抖的 placeholder 生成函数,延迟 1.5 秒执行,只执行最后一次 const debouncedGenPlaceholder = useCallback(() => { // 清除之前的定时器 if (placeholderTimerRef.current) { clearTimeout(placeholderTimerRef.current) } // 设置新的定时器 placeholderTimerRef.current = setTimeout(() => { genInputPlaceholder() }, 1500) // 1.5秒延迟 }, [primaryModel, marks, chats, trashState, t]) // 插入占位符 function insertPlaceholder() { if (placeholder.includes('[Tab]')) { setText(placeholder.replace('[Tab]', '')) setPlaceholder('') } } // 处理拖拽结束(底部工具栏) const handleDragEnd = useCallback((event: DragEndEvent) => { const { active, over } = event if (over && active.id !== over.id) { const enabledItems = chatToolbarConfigPc.filter(item => item.enabled) const oldIndex = enabledItems.findIndex((item) => item.id === active.id) const newIndex = enabledItems.findIndex((item) => item.id === over.id) const reorderedItems = arrayMove(enabledItems, oldIndex, newIndex) const allItems = [...chatToolbarConfigPc] reorderedItems.forEach((item, index) => { const globalIndex = allItems.findIndex(i => i.id === item.id) if (globalIndex !== -1) { allItems[globalIndex] = { ...item, order: enabledItems[0].order + index } } }) setChatToolbarConfigPc(allItems) } }, [chatToolbarConfigPc, setChatToolbarConfigPc]) // 使用 useMemo 优化工具栏项过滤 - 显示底部工具栏(排除 newChat) const bottomToolbarItems = useMemo(() => { return chatToolbarConfigPc .filter(item => item.enabled && item.id !== 'newChat') .sort((a, b) => a.order - b.order) }, [chatToolbarConfigPc]) useEffect(() => { // 如果有 marks,生成 AI 提示词作为 placeholder if (marks.length > 0) { genInputPlaceholder() } else { setPlaceholder(t('record.chat.input.placeholder.default')) } }, [primaryModel, marks, t]) useEffect(() => { emitter.on('revertChat', (event: unknown) => { setText(event as string) }) emitter.on('fileSelected', (event: unknown) => { setLinkedResource(event as MarkdownFile) setChatLinkedResource(event as MarkdownFile) }) emitter.on('folderSelected', (event: unknown) => { setLinkedResource(event as LinkedFolder) setChatLinkedResource(event as LinkedFolder) }) emitter.on('insert-quote', (event: unknown) => { const data = event as PendingQuote setPendingQuote(data) // 延迟聚焦到输入框 setTimeout(() => { textareaRef.current?.focus() }, 50) // 触发防抖的 placeholder 重新生成 debouncedGenPlaceholder() }) emitter.on('quick-prompt-insert', (prompt: string) => { setText(prompt) textareaRef.current?.focus() }) emitter.on('ai-placeholder-generated', (event: unknown) => { const promptText = event as string if (promptText) { setPlaceholder(promptText) } }) return () => { onboardingTypingTimerRefs.current.forEach((timerId) => window.clearTimeout(timerId)) onboardingTypingTimerRefs.current = [] emitter.off('revertChat') emitter.off('fileSelected') emitter.off('folderSelected') emitter.off('insert-quote') emitter.off('quick-prompt-insert') emitter.off('ai-placeholder-generated') } }, [debouncedGenPlaceholder, setPendingQuote]) useEffect(() => { if (!onboardingPromptDraft) { return } onboardingAgentPromptArmedRef.current = true onboardingTypingTimerRefs.current.forEach((timerId) => window.clearTimeout(timerId)) onboardingTypingTimerRefs.current = [] setText('') setTimeout(() => { textareaRef.current?.focus() }, 50) const frames = buildTypingFrames(onboardingPromptDraft, 2) frames.forEach((frame, index) => { const timerId = window.setTimeout(() => { applyTypedText(frame) if (index === frames.length - 1) { onboardingTypingTimerRefs.current = [] setOnboardingPromptDraft(null) } }, 160 + index * 42) onboardingTypingTimerRefs.current.push(timerId) }) }, [applyTypedText, onboardingPromptDraft, setOnboardingPromptDraft]) // 生成文件的行号预览(用于 AI 对话) async function generateFilePreview(filePath: string, isCustom: boolean): Promise { try { // 检查文件是否存在 const fileExists = isCustom ? await exists(filePath) : await exists(filePath, { baseDir: BaseDirectory.AppData }) if (!fileExists) { return `文件 ${filePath.split('/').pop() || filePath} 不存在或已被删除` } let content: string if (isCustom) { content = await readTextFile(filePath) } else { content = await readTextFile(filePath, { baseDir: BaseDirectory.AppData }) } const lines = content.split('\n') const previewLines = lines.slice(0, 100).map((line, index) => { const lineNum = index + 1 const preview = line.length > 60 ? line.slice(0, 60) + '...' : line return `${String(lineNum).padStart(4)} | ${preview}` }) const totalLines = lines.length const truncatedNote = totalLines > 100 ? `\n... (共 ${totalLines} 行,后 ${totalLines - 100} 行省略)` : '' return `已关联文件:${filePath.split('/').pop() || filePath} 你可以使用 replace_editor_content 工具通过行号修改内容。 行号预览: \`\`\` ${previewLines.join('\n')} \`\`\`${truncatedNote} 使用示例: - 修改第 4-5 行:replace_editor_content({startLine: 4, endLine: 5, replaceContent: "新内容"}) - 替换第 10 行的特定内容:replace_editor_content({startLine: 10, endLine: 10, replaceContent: "新内容"}) ` } catch (error) { console.error('生成文件预览失败:', error) return `已关联文件:${filePath.split('/').pop() || filePath} (无法读取文件内容)` } } // 自动关联当前打开的 markdown 文件或文件夹 useEffect(() => { async function linkCurrentResource() { if (!activeFilePath) { setLinkedResource(null) setChatLinkedResource(null) setLinkedResourcePreview(null) return } const workspace = await getWorkspacePath() // 检查是否是支持的文件类型(包括 markdown、代码文件等) if (activeFilePath.match(/\.(md|txt|markdown|py|js|ts|jsx|tsx|css|scss|less|html|xml|json|yaml|yml|sh|bash|java|c|cpp|h|go|rs|sql|rb|php|vue|svelte|astro|toml|ini|conf|cfg|gitignore|env|example|template)$/i)) { // 文件关联逻辑 const fileName = activeFilePath.split('/').pop() || activeFilePath // 构建完整路径 let fullPath: string if (workspace.isCustom) { const pathParts = activeFilePath.split('/') fullPath = workspace.path + '/' + pathParts.join('/') } else { fullPath = activeFilePath } const resource = { name: fileName, path: fullPath, relativePath: activeFilePath } setLinkedResource(resource) setChatLinkedResource(resource) // 生成并设置文件预览 const preview = await generateFilePreview(fullPath, workspace.isCustom) setLinkedResourcePreview(preview) } else if (!activeFilePath.includes('.')) { // 文件夹关联逻辑 - 只有当路径不包含 . 时才可能是文件夹 const folderName = activeFilePath.split('/').pop() || activeFilePath // 构建完整路径 let fullPath: string if (workspace.isCustom) { const pathParts = activeFilePath.split('/') fullPath = workspace.path + '/' + pathParts.join('/') } else { fullPath = activeFilePath } // 计算文件夹中的文件数量和索引状态 const { collectMarkdownFiles } = await import('@/lib/files') const files = await collectMarkdownFiles(activeFilePath) const { vectorIndexedFiles } = useArticleStore.getState() const indexedCount = files.filter(f => vectorIndexedFiles.has(f.path) ).length // 只有在有索引文件时才关联文件夹 if (indexedCount > 0) { const resource = { name: folderName, path: fullPath, relativePath: activeFilePath, fileCount: files.length, indexedCount: indexedCount } setLinkedResource(resource) setChatLinkedResource(resource) // 文件夹不生成行号预览 setLinkedResourcePreview(null) } else { // 没有索引文件,清除关联 setLinkedResource(null) setChatLinkedResource(null) setLinkedResourcePreview(null) } } else { // 不支持的文件类型(如 .docx, .pdf 等),不进行关联 setLinkedResource(null) setChatLinkedResource(null) setLinkedResourcePreview(null) } } linkCurrentResource() }, [activeFilePath]) // 当关联文件变化时,触发防抖的 placeholder 重新生成 useEffect(() => { if (linkedResource) { debouncedGenPlaceholder() } }, [linkedResource, debouncedGenPlaceholder]) return (