diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 58fa9743a5..d4dfc5b570 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -66,12 +66,20 @@ runs: if: ${{ inputs.os == 'linux' }} shell: ${{ inputs.shell }} run: | - sudo apt-get update && sudo apt-get install rpm flatpak-builder elfutils + sudo apt-get update && sudo apt-get install rpm flatpak-builder elfutils libfuse2 flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo FLATPAK_ARCH=$(if [[ ${{ inputs.arch }} = 'arm64' ]]; then echo 'aarch64'; else echo 'x86_64'; fi) FLATPAK_VERSION='24.08' flatpak install --user --no-deps --arch $FLATPAK_ARCH --assumeyes runtime/org.freedesktop.Platform/$FLATPAK_ARCH/$FLATPAK_VERSION runtime/org.freedesktop.Sdk/$FLATPAK_ARCH/$FLATPAK_VERSION org.electronjs.Electron2.BaseApp/$FLATPAK_ARCH/$FLATPAK_VERSION + - name: Install appimagetool + if: ${{ inputs.os == 'linux' }} + shell: ${{ inputs.shell }} + run: | + APPIMAGETOOL_ARCH=$(if [[ ${{ inputs.arch }} = 'arm64' ]]; then echo 'aarch64'; else echo 'x86_64'; fi) + wget -q "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${APPIMAGETOOL_ARCH}.AppImage" -O /usr/local/bin/appimagetool + chmod +x /usr/local/bin/appimagetool + - name: Update build info shell: ${{ inputs.shell }} run: pnpm run chore:update-build-info @@ -90,6 +98,14 @@ runs: TARGET_ARCH: ${{ inputs.arch }} run: pnpm run --filter desktop electron-forge:make --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }} + - name: Build AppImage + if: ${{ inputs.os == 'linux' }} + shell: ${{ inputs.shell }} + env: + TRILIUM_ARTIFACT_NAME_HINT: TriliumNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }} + APPIMAGE_EXTRACT_AND_RUN: "1" + run: bash apps/desktop/scripts/build-appimage.sh ${{ inputs.arch }} + # Add DMG signing step - name: Sign DMG if: inputs.os == 'macos' diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 0000000000..b739b56514 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,44 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize, ready_for_review, reopened] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' + plugins: 'code-review@claude-code-plugins' + prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}' + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000000..1051552ba1 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,50 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://code.claude.com/docs/en/cli-reference for available options + # claude_args: '--allowed-tools Bash(gh pr *)' + diff --git a/.nvmrc b/.nvmrc index 045200741c..eefb690f4a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.14.1 \ No newline at end of file +24.15.0 \ No newline at end of file diff --git a/apps/build-docs/package.json b/apps/build-docs/package.json index 631578d9ec..cae84da510 100644 --- a/apps/build-docs/package.json +++ b/apps/build-docs/package.json @@ -16,7 +16,7 @@ "license": "AGPL-3.0-only", "packageManager": "pnpm@10.33.0", "devDependencies": { - "@redocly/cli": "2.26.0", + "@redocly/cli": "2.28.0", "archiver": "7.0.1", "fs-extra": "11.3.4", "js-yaml": "4.1.1", diff --git a/apps/client/package.json b/apps/client/package.json index 0978d1b745..8f0026fbf9 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -66,7 +66,7 @@ "mind-elixir": "5.10.0", "panzoom": "9.4.4", "preact": "10.29.1", - "react-i18next": "17.0.2", + "react-i18next": "17.0.3", "react-window": "2.2.7", "reveal.js": "6.0.1", "rrule": "2.8.1", diff --git a/apps/client/src/entities/fattribute.ts b/apps/client/src/entities/fattribute.ts index 07a2b22c4f..bdccead31d 100644 --- a/apps/client/src/entities/fattribute.ts +++ b/apps/client/src/entities/fattribute.ts @@ -66,7 +66,15 @@ class FAttribute { } get isAutoLink() { - return this.type === "relation" && ["internalLink", "imageLink", "relationMapLink", "includeNoteLink"].includes(this.name); + if (this.type === "relation") { + return ["internalLink", "imageLink", "relationMapLink", "includeNoteLink"].includes(this.name); + } + + if (this.type === "label") { + return this.name === "internalBookmark"; + } + + return false; } get toString() { diff --git a/apps/client/src/print.css b/apps/client/src/print.css index d0123c810e..25a61e5bf4 100644 --- a/apps/client/src/print.css +++ b/apps/client/src/print.css @@ -2,7 +2,6 @@ :root { --print-font-size: 11pt; - --ck-content-color-image-caption-background: transparent !important; } @page { @@ -11,9 +10,12 @@ html, body { + --print-font-family: var(--detail-font-family, sans-serif); + width: 100%; height: 100%; color: black; + font-family: var(--print-font-family); } .note-list-widget.full-height, @@ -26,6 +28,12 @@ body { } body[data-note-type="text"] .ck-content { + --ck-content-font-family: var(--print-font-family); + --ck-content-font-size: var(--print-font-size); + --ck-content-font-color: black; + --ck-content-line-height: 1.5; + --ck-content-color-image-caption-background: transparent; + font-size: var(--print-font-size); text-align: justify; } @@ -154,4 +162,4 @@ span[style] { .page-break::after { display: none !important; } -/* #endregion */ \ No newline at end of file +/* #endregion */ diff --git a/apps/client/src/print.tsx b/apps/client/src/print.tsx index c943413c49..2a7f25161a 100644 --- a/apps/client/src/print.tsx +++ b/apps/client/src/print.tsx @@ -31,6 +31,13 @@ async function main() { if (!noteId) return; await import("./print.css"); + + // Load the user's font preferences so that --detail-font-family is available. + const fontLink = document.createElement("link"); + fontLink.rel = "stylesheet"; + fontLink.href = "api/fonts"; + document.head.appendChild(fontLink); + const note = await froca.getNote(noteId); const bodyWrapper = document.createElement("div"); @@ -105,6 +112,9 @@ function SingleNoteRenderer({ note, onReady }: RendererProps) { // Check custom CSS. await loadCustomCss(note); + + // Wait for all fonts (including those from custom CSS) to finish loading. + await document.fonts.ready; } load().then(() => requestAnimationFrame(() => onReady({ @@ -130,6 +140,7 @@ function CollectionRenderer({ note, onReady, onProgressChanged }: RendererProps) media="print" onReady={async (data: PrintReport) => { await loadCustomCss(note); + await document.fonts.ready; onReady(data); }} onProgressChanged={onProgressChanged} diff --git a/apps/client/src/services/attribute_renderer.ts b/apps/client/src/services/attribute_renderer.ts index 01d6337367..c93620b3b2 100644 --- a/apps/client/src/services/attribute_renderer.ts +++ b/apps/client/src/services/attribute_renderer.ts @@ -7,6 +7,10 @@ async function renderAttribute(attribute: FAttribute, renderIsInheritable: boole const isInheritable = renderIsInheritable && attribute.isInheritable ? `(inheritable)` : ""; const $attr = $(""); + if (attribute.isAutoLink) { + return $attr; + } + if (attribute.type === "label") { $attr.append(document.createTextNode(`#${attribute.name}${isInheritable}`)); @@ -15,9 +19,6 @@ async function renderAttribute(attribute: FAttribute, renderIsInheritable: boole $attr.append(document.createTextNode(formatValue(attribute.value))); } } else if (attribute.type === "relation") { - if (attribute.isAutoLink) { - return $attr; - } // when the relation has just been created, then it might not have a value if (attribute.value) { diff --git a/apps/client/src/services/link.ts b/apps/client/src/services/link.ts index 3405161dd5..1e375a994a 100644 --- a/apps/client/src/services/link.ts +++ b/apps/client/src/services/link.ts @@ -60,6 +60,8 @@ export interface ViewScope { */ tocPreviousVisible?: boolean; tocCollapsedHeadings?: Set; + /** When set, scrolls to a bookmark anchor within the note after navigation. */ + bookmark?: string; } interface CreateLinkOptions { @@ -244,7 +246,7 @@ export function parseNavigationStateFromUrl(url: string | undefined) { hoistedNoteId = value; } else if (name === "searchString") { searchString = value; // supports triggering search from URL, e.g. #?searchString=blabla - } else if (["viewMode", "attachmentId"].includes(name)) { + } else if (["viewMode", "attachmentId", "bookmark"].includes(name)) { (viewScope as any)[name] = value; } else if (name === "popup") { openInPopup = true; @@ -432,6 +434,13 @@ async function loadReferenceLinkTitle($el: JQuery, href: string | n const title = await getReferenceLinkTitle(href); $el.text(title); + if (viewScope?.bookmark) { + $el.append($("").append( + $("").addClass("bx bx-bookmark"), + document.createTextNode(viewScope.bookmark) + )); + } + if (note) { const icon = await getLinkIcon(noteId, viewScope.viewMode); @@ -457,8 +466,8 @@ async function getReferenceLinkTitle(href: string) { return attachment ? attachment.title : "[missing attachment]"; } - return note.title; + return note.title; } function getReferenceLinkTitleSync(href: string) { @@ -481,8 +490,12 @@ function getReferenceLinkTitleSync(href: string) { return attachment ? attachment.title : "[missing attachment]"; } - return note.title; + if (viewScope?.bookmark) { + return `${note.title} - ${viewScope.bookmark}`; + } + + return note.title; } if (glob.device !== "print") { diff --git a/apps/client/src/stylesheets/theme-next/notes/text.css b/apps/client/src/stylesheets/theme-next/notes/text.css index 5e58895ef5..8832d9a9cf 100644 --- a/apps/client/src/stylesheets/theme-next/notes/text.css +++ b/apps/client/src/stylesheets/theme-next/notes/text.css @@ -714,6 +714,15 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child { text-decoration: underline; } +.ck-content a.reference-link small { + margin-left: 0.25em; + opacity: 0.5; + + >span { + font-size: 0.7em; + } +} + /* * Read-only text content */ diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index e284c16b78..79cf207780 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -41,6 +41,8 @@ "link_title_mirrors": "link title mirrors the note's current title", "link_title_arbitrary": "link title can be changed arbitrarily", "link_title": "Link title", + "anchor": "Anchor (optional)", + "anchor_none": "None (link to note)", "button_add_link": "Add link" }, "branch_prefix": { @@ -860,6 +862,9 @@ "no_inherited_attributes": "No inherited attributes.", "none": "none" }, + "auto_link_attribute_list": { + "title": "System Attributes" + }, "note_info_widget": { "note_id": "Note ID", "created": "Created", diff --git a/apps/client/src/translations/ja/translation.json b/apps/client/src/translations/ja/translation.json index cdbe639287..2c99b6e57c 100644 --- a/apps/client/src/translations/ja/translation.json +++ b/apps/client/src/translations/ja/translation.json @@ -615,7 +615,8 @@ "collections": "コレクション", "ai-chat": "AI チャット", "spreadsheet": "スプレッドシート", - "llm-chat": "AI チャット" + "llm-chat": "AI チャット", + "markdown": "Markdown" }, "edited_notes": { "no_edited_notes_found": "この日の編集されたノートはまだありません...", @@ -2479,5 +2480,10 @@ }, "launcher_button_context_menu": { "remove_from_launch_bar": "ランチャーバーから削除" + }, + "display_mode": { + "source": "ソースビュー", + "split": "分割ビュー", + "preview": "プレビュー" } } diff --git a/apps/client/src/translations/tw/translation.json b/apps/client/src/translations/tw/translation.json index cc0497127e..09b044c264 100644 --- a/apps/client/src/translations/tw/translation.json +++ b/apps/client/src/translations/tw/translation.json @@ -89,13 +89,21 @@ }, "delete_notes": { "delete_all_clones_description": "同時刪除所有克隆(可以在最近修改中撤消)", - "erase_notes_description": "通常(軟)刪除僅標記筆記為已刪除,可以在一段時間內透過最近修改對話方塊撤消。勾選此選項將立即擦除筆記,無法撤銷。", + "erase_notes_description": "立即刪除筆記,而非執行軟刪除。此操作無法撤銷,且會強制重新載入應用程式。", "erase_notes_warning": "永久擦除筆記(無法撤銷),包括所有克隆。這將強制應用程式重新載入。", - "notes_to_be_deleted": "將刪除以下筆記 ({{notesCount}})", + "notes_to_be_deleted": "待刪除筆記 ({{notesCount}})", "no_note_to_delete": "沒有筆記將被刪除(僅克隆)。", - "broken_relations_to_be_deleted": "將刪除以下關聯並斷開連接 ({{ relationCount}})", + "broken_relations_to_be_deleted": "斷開的關聯 ({{ relationCount}})", "cancel": "取消", - "close": "關閉" + "close": "關閉", + "title": "刪除筆記", + "clones_label": "克隆", + "delete_clones_description_one": "同時刪除 {{count}} 個其他克隆。此操作可在最近修改中撤銷。", + "erase_notes_label": "永久擦除", + "table_note_with_relation": "有關聯的筆記", + "table_relation": "關聯", + "table_points_to": "指向 (已刪除)", + "delete": "刪除" }, "export": { "export_note_title": "匯出筆記", @@ -206,7 +214,8 @@ "box_size_small": "小型(顯示大約 10 行)", "box_size_medium": "中型 (顯示大約30行)", "box_size_full": "完整顯示(完整文字框)", - "button_include": "內嵌筆記" + "button_include": "內嵌筆記", + "box_size_expandable": "可展開(預設為摺疊狀態)" }, "info": { "modalTitle": "資訊消息", @@ -1430,7 +1439,7 @@ "expand-subtree": "展開子階層", "collapse-subtree": "收摺子階層", "sort-by": "排序方式…", - "recent-changes-in-subtree": "子階層中的最近更改", + "recent-changes-in-subtree": "子階層中的最近修改", "convert-to-attachment": "轉換為附件", "copy-note-path-to-clipboard": "複製筆記路徑至剪貼簿", "protect-subtree": "保護子階層", @@ -2334,5 +2343,14 @@ "history": "對話歷史", "recent_chats": "最近的對話", "no_chats": "無先前的對話記錄" + }, + "revisions": { + "note_revisions": "筆記歷史版本", + "delete_all_revisions": "刪除此筆記的所有歷史版本", + "delete_all_button": "刪除所有歷史版本", + "help_title": "關於筆記歷史版本的說明", + "confirm_delete_all": "您要刪除此筆記的所有歷史版本嗎?", + "no_revisions": "尚無此筆記的歷史版本...", + "restore_button": "還原" } } diff --git a/apps/client/src/types-fancytree.d.ts b/apps/client/src/types-fancytree.d.ts index a8a151b55d..67130be1d2 100644 --- a/apps/client/src/types-fancytree.d.ts +++ b/apps/client/src/types-fancytree.d.ts @@ -269,6 +269,8 @@ declare namespace Fancytree { lazy: boolean; /** Alternative description used as hover banner */ tooltip: string; + /** `
  • ` element wrapping this node. `null` if the node has not been rendered yet. */ + li: HTMLLIElement | null; /** Outer element of single nodes */ span: HTMLElement; /** Outer element of single nodes for table extension */ diff --git a/apps/client/src/widgets/dialogs/add_link.tsx b/apps/client/src/widgets/dialogs/add_link.tsx index 4bb1d1711c..2206bd9dd1 100644 --- a/apps/client/src/widgets/dialogs/add_link.tsx +++ b/apps/client/src/widgets/dialogs/add_link.tsx @@ -5,6 +5,7 @@ import FormRadioGroup from "../react/FormRadioGroup"; import NoteAutocomplete from "../react/NoteAutocomplete"; import { useRef, useState, useEffect } from "preact/hooks"; import tree from "../../services/tree"; +import froca from "../../services/froca"; import note_autocomplete, { Suggestion } from "../../services/note_autocomplete"; import { logError } from "../../services/ws"; import FormGroup from "../react/FormGroup.js"; @@ -24,6 +25,9 @@ export default function AddLinkDialog() { const [ linkTitle, setLinkTitle ] = useState(""); const [ linkType, setLinkType ] = useState(); const [ suggestion, setSuggestion ] = useState(null); + const [ bookmarks, setBookmarks ] = useState([]); + const [ selectedBookmark, setSelectedBookmark ] = useState(""); + const [ noteTitle, setNoteTitle ] = useState(""); const [ shown, setShown ] = useState(false); const hasSubmittedRef = useRef(false); @@ -41,26 +45,34 @@ export default function AddLinkDialog() { }, [ opts ]); async function setDefaultLinkTitle(noteId: string) { - const noteTitle = await tree.getNoteTitle(noteId); - setLinkTitle(noteTitle); - } - - function resetExternalLink() { - if (linkType === "external-link") { - setLinkType("reference-link"); - } + const title = await tree.getNoteTitle(noteId); + setNoteTitle(title); + setLinkTitle(title); } useEffect(() => { + const resetExternalLink = () => + setLinkType((prev) => prev === "external-link" ? "reference-link" : prev); + if (!suggestion) { resetExternalLink(); + setBookmarks([]); + setSelectedBookmark(""); return; } + let cancelled = false; + if (suggestion.notePath) { const noteId = tree.getNoteIdFromUrl(suggestion.notePath); if (noteId) { setDefaultLinkTitle(noteId); + froca.getNote(noteId).then((note) => { + if (cancelled) return; + const bkms = note?.getLabels("internalBookmark").map((l) => l.value) ?? []; + setBookmarks(bkms); + setSelectedBookmark(""); + }); } resetExternalLink(); } @@ -69,8 +81,18 @@ export default function AddLinkDialog() { setLinkTitle(suggestion.externalLink); setLinkType("external-link"); } + + return () => { cancelled = true; }; }, [suggestion]); + useEffect(() => { + if (selectedBookmark) { + setLinkTitle(`${noteTitle} - ${selectedBookmark}`); + } else { + setLinkTitle(noteTitle); + } + }, [selectedBookmark, noteTitle]); + function onShown() { const $autocompleteEl = refToJQuerySelector(autocompleteRef); if (!opts?.text) { @@ -114,8 +136,11 @@ export default function AddLinkDialog() { hasSubmittedRef.current = false; if (suggestion.notePath) { - // Handle note link - opts.addLink(suggestion.notePath, linkType === "reference-link" ? null : linkTitle); + // Handle note link, optionally with a bookmark anchor + const path = selectedBookmark + ? `${suggestion.notePath}?bookmark=${encodeURIComponent(selectedBookmark)}` + : suggestion.notePath; + opts.addLink(path, linkType === "reference-link" ? null : linkTitle); } else if (suggestion.externalLink) { // Handle external link opts.addLink(suggestion.externalLink, linkTitle, true); @@ -123,6 +148,9 @@ export default function AddLinkDialog() { } setSuggestion(null); + setBookmarks([]); + setSelectedBookmark(""); + setNoteTitle(""); setShown(false); }} show={shown} @@ -138,6 +166,21 @@ export default function AddLinkDialog() { /> + {bookmarks.length > 0 && ( + + + + )} + {!opts?.hasSelection && (
    {(linkType !== "external-link") && ( diff --git a/apps/client/src/widgets/dialogs/note_type_chooser.tsx b/apps/client/src/widgets/dialogs/note_type_chooser.tsx index efb44f48c9..225d61c001 100644 --- a/apps/client/src/widgets/dialogs/note_type_chooser.tsx +++ b/apps/client/src/widgets/dialogs/note_type_chooser.tsx @@ -3,13 +3,14 @@ import { t } from "../../services/i18n"; import FormGroup from "../react/FormGroup"; import NoteAutocomplete from "../react/NoteAutocomplete"; import FormList, { FormListHeader, FormListItem } from "../react/FormList"; -import { useEffect, useState } from "preact/hooks"; +import { useEffect, useRef, useState } from "preact/hooks"; import note_types from "../../services/note_types"; import { MenuCommandItem, MenuItem } from "../../menus/context_menu"; import { TreeCommandNames } from "../../menus/tree_context_menu"; import { Suggestion } from "../../services/note_autocomplete"; import SimpleBadge from "../react/Badge"; import { useTriliumEvent } from "../react/hooks"; +import { refToJQuerySelector } from "../react/react_utils"; export interface ChooseNoteTypeResponse { success: boolean; @@ -30,6 +31,8 @@ export default function NoteTypeChooserDialogComponent() { const [ shown, setShown ] = useState(false); const [ parentNote, setParentNote ] = useState(); const [ noteTypes, setNoteTypes ] = useState[]>([]); + const modalRef = useRef(null); + const autocompleteRef = useRef(null); useTriliumEvent("chooseNoteType", ({ callback }) => { setCallback(() => callback); @@ -68,11 +71,17 @@ export default function NoteTypeChooserDialogComponent() { return ( { + refToJQuerySelector(autocompleteRef) + .trigger("focus") + .trigger("select"); + }} onHidden={() => { callback?.({ success: false }); setShown(false); @@ -82,6 +91,7 @@ export default function NoteTypeChooserDialogComponent() { > div { diff --git a/apps/client/src/widgets/layout/StatusBar.tsx b/apps/client/src/widgets/layout/StatusBar.tsx index 077c59ef4f..50657867cd 100644 --- a/apps/client/src/widgets/layout/StatusBar.tsx +++ b/apps/client/src/widgets/layout/StatusBar.tsx @@ -26,6 +26,7 @@ import LinkButton from "../react/LinkButton"; import { ParentComponent } from "../react/react_utils"; import { ContentLanguagesModal, NoteTypeCodeNoteList, NoteTypeOptionsModal, useLanguageSwitcher, useMimeTypes } from "../ribbon/BasicPropertiesTab"; import AttributeEditor, { AttributeEditorImperativeHandlers } from "../ribbon/components/AttributeEditor"; +import AutoLinkAttributesTab from "../ribbon/AutoLinkAttributesTab"; import InheritedAttributesTab from "../ribbon/InheritedAttributesTab"; import { NoteSizeWidget, useNoteMetadata } from "../ribbon/NoteInfoTab"; import { NotePathsWidget, useSortedNotePaths } from "../ribbon/NotePathsTab"; @@ -401,6 +402,11 @@ function AttributesPane({ note, noteContext, attributesShown, setAttributesShown {t("inherited_attribute_list.title")} + {glob.isDev &&
    + {t("auto_link_attribute_list.title")} + +
    } + may have been recreated by a lazy reload (e.g. via + // `getNodeFromPath` → `parentNode.load(true)` after an import into root). + this.toggleHiddenNode(this.noteContext.hoistedNoteId !== "root"); return; } @@ -1568,8 +1571,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { toggleHiddenNode(show: boolean) { const hiddenNode = this.getNodesByNoteId("_hidden")[0]; - // TODO: Check how .li exists here. - $((hiddenNode as any).li).toggleClass("hidden-node-is-hidden", !show); + if (hiddenNode?.li) { + $(hiddenNode.li).toggleClass("hidden-node-is-hidden", !show); + } } async frocaReloadedEvent() { diff --git a/apps/client/src/widgets/ribbon/AutoLinkAttributesTab.tsx b/apps/client/src/widgets/ribbon/AutoLinkAttributesTab.tsx new file mode 100644 index 0000000000..1d54edbfb6 --- /dev/null +++ b/apps/client/src/widgets/ribbon/AutoLinkAttributesTab.tsx @@ -0,0 +1,69 @@ +import { useEffect, useState } from "preact/hooks"; + +import FAttribute from "../../entities/fattribute"; +import attributes from "../../services/attributes"; +import froca from "../../services/froca"; +import { useTriliumEvent } from "../react/hooks"; +import { joinElements } from "../react/react_utils"; +import { TabContext } from "./ribbon-interface"; + +type AutoLinkAttributesTabArgs = Pick; + +export default function AutoLinkAttributesTab({ note, componentId }: AutoLinkAttributesTabArgs) { + const [autoLinkAttributes, setAutoLinkAttributes] = useState(); + + function refresh() { + if (!note) return; + const attrs = note.getAttributes().filter((attr) => attr.isAutoLink && attr.noteId === note.noteId); + setAutoLinkAttributes(attrs); + } + + useEffect(refresh, [note]); + useTriliumEvent("entitiesReloaded", ({ loadResults }) => { + if (loadResults.getAttributeRows(componentId).find((attr) => attributes.isAffecting(attr, note))) { + refresh(); + } + }); + + if (!autoLinkAttributes?.length) { + return null; + } + + return ( +
    +
    + {joinElements(autoLinkAttributes.map((attribute) => ( + + )), " ")} +
    +
    + ); +} + +function AutoLinkAttribute({ attribute }: { attribute: FAttribute }) { + const [html, setHtml] = useState(""); + + useEffect(() => { + renderAutoLink(attribute).then(setHtml); + }, [attribute]); + + return ; +} + +async function renderAutoLink(attribute: FAttribute) { + if (attribute.type === "label") { + return `#${escapeHtml(attribute.name)}=${escapeHtml(attribute.value)}`; + } + + const note = await froca.getNote(attribute.value); + if (!note) return ""; + + const link = `${escapeHtml(note.title)}`; + return `~${escapeHtml(attribute.name)}=${link}`; +} + +function escapeHtml(text: string) { + const el = document.createElement("span"); + el.textContent = text; + return el.innerHTML; +} diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx index 8cacc40e25..26d021168b 100644 --- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx +++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx @@ -61,6 +61,17 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext onContentChange(newContent) { contentRef.current = newContent; watchdogRef.current?.editor?.setData(newContent); + + // Scroll to bookmark anchor if navigated with ?bookmark=... + const viewScope = noteContext?.viewScope; + if (viewScope?.bookmark) { + requestAnimationFrame(() => { + const el = watchdogRef.current?.editor?.editing.view.getDomRoot() + ?.querySelector(`[id="${CSS.escape(viewScope.bookmark!)}"]`); + el?.scrollIntoView({ behavior: "smooth", block: "center" }); + viewScope.bookmark = undefined; + }); + } }, dataSaved(savedData) { // Store back the saved data in order to retrieve it in case the CKEditor crashes. @@ -263,6 +274,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext // We are not using CKEditor's built-in watch dog content, instead we are using the data we store regularly in the spaced update (see `dataSaved`). editor.setData(contentRef.current); parentComponent?.triggerEvent("textEditorRefreshed", { ntxId, editor }); + }} />} diff --git a/apps/client/src/widgets/type_widgets/text/ReadOnlyText.tsx b/apps/client/src/widgets/type_widgets/text/ReadOnlyText.tsx index da7e08ebab..a58b21de54 100644 --- a/apps/client/src/widgets/type_widgets/text/ReadOnlyText.tsx +++ b/apps/client/src/widgets/type_widgets/text/ReadOnlyText.tsx @@ -6,7 +6,7 @@ import "@triliumnext/ckeditor5"; import clsx from "clsx"; import { Ref } from "preact"; -import { useEffect, useLayoutEffect, useMemo } from "preact/hooks"; +import { useEffect, useLayoutEffect, useMemo, useRef as usePreactRef } from "preact/hooks"; import appContext from "../../../components/app_context"; import FNote from "../../../entities/fnote"; @@ -24,6 +24,17 @@ import { loadIncludedNote, refreshIncludedNote, setupImageOpening } from "./util export default function ReadOnlyText({ note, noteContext, ntxId }: TypeWidgetProps) { const blob = useNoteBlob(note); const { isRtl } = useNoteLanguage(note); + const readOnlyContentRef = usePreactRef(null); + + // Scroll to bookmark anchor if navigated with ?bookmark=... + useEffect(() => { + const viewScope = noteContext?.viewScope; + if (!viewScope?.bookmark || !readOnlyContentRef.current) return; + + const el = readOnlyContentRef.current.querySelector(`[id="${CSS.escape(viewScope.bookmark)}"]`); + el?.scrollIntoView({ behavior: "smooth", block: "center" }); + viewScope.bookmark = undefined; + }, [blob]); return ( <> @@ -31,6 +42,7 @@ export default function ReadOnlyText({ note, noteContext, ntxId }: TypeWidgetPro html={blob?.content ?? ""} ntxId={ntxId} dir={isRtl ? "rtl" : "ltr"} + contentRef={readOnlyContentRef} /> diff --git a/apps/client/src/widgets/type_widgets/text/config.ts b/apps/client/src/widgets/type_widgets/text/config.ts index e4812156e4..c54dbc09c2 100644 --- a/apps/client/src/widgets/type_widgets/text/config.ts +++ b/apps/client/src/widgets/type_widgets/text/config.ts @@ -133,6 +133,15 @@ export async function buildConfig(opts: BuildEditorOptions): Promise NUL 2>&1 IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL :POWERSHELL -powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; ./trilium.exe" +powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; Set-Item -Path Env:TRILIUM_ELECTRON_DATA_DIR -Value './trilium-electron-data'; Set-Item -Path Env:ELECTRON_NO_ATTACH_CONSOLE -Value '1'; ./trilium.exe" GOTO END :BATCH @@ -17,6 +17,8 @@ chcp 65001 SET DIR=%~dp0 SET DIR=%DIR:~0,-1% SET TRILIUM_DATA_DIR=%DIR%\trilium-data +SET TRILIUM_ELECTRON_DATA_DIR=%DIR%\trilium-electron-data +SET ELECTRON_NO_ATTACH_CONSOLE=1 cd "%DIR%" start trilium.exe GOTO END diff --git a/apps/desktop/electron-forge/trilium-portable.sh b/apps/desktop/electron-forge/trilium-portable.sh index 1f69a09a18..36a60b7cff 100644 --- a/apps/desktop/electron-forge/trilium-portable.sh +++ b/apps/desktop/electron-forge/trilium-portable.sh @@ -2,6 +2,7 @@ DIR=`dirname "$0"` export TRILIUM_DATA_DIR="$DIR/trilium-data" +export TRILIUM_ELECTRON_DATA_DIR="$DIR/trilium-electron-data" exec "$DIR/trilium" diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 17bdae3dd4..ce34d3627a 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -11,16 +11,16 @@ "url": "https://triliumnotes.org" }, "scripts": { - "dev": "cross-env TRILIUM_PORT=37742 TRILIUM_DATA_DIR=data tsx ../../scripts/electron-start.mts src/main.ts", + "dev": "cross-env TRILIUM_PORT=37742 TRILIUM_DATA_DIR=data TRILIUM_ELECTRON_DATA_DIR=data-electron-37742 tsx ../../scripts/electron-start.mts src/main.ts", "start-no-dir": "cross-env TRILIUM_PORT=37743 tsx ../../scripts/electron-start.mts src/main.ts", "build": "tsx scripts/build.ts", - "start-prod": "pnpm build && cross-env TRILIUM_DATA_DIR=data TRILIUM_PORT=37841 ELECTRON_IS_DEV=0 electron dist", + "start-prod": "pnpm build && cross-env TRILIUM_DATA_DIR=data TRILIUM_ELECTRON_DATA_DIR=data-electron-37841 TRILIUM_PORT=37841 ELECTRON_IS_DEV=0 electron dist", "start-prod-no-dir": "pnpm build && cross-env TRILIUM_PORT=37841 ELECTRON_IS_DEV=0 electron dist", "electron-forge:make": "pnpm build && electron-forge make dist", "electron-forge:make-flatpak": "pnpm build && DEBUG=* electron-forge make dist --targets=@electron-forge/maker-flatpak", "electron-forge:package": "pnpm build && electron-forge package dist", "electron-forge:start": "pnpm build && electron-forge start dist", - "e2e": "pnpm build && cross-env TRILIUM_INTEGRATION_TEST=memory-no-store TRILIUM_PORT=8082 TRILIUM_DATA_DIR=data-e2e ELECTRON_IS_DEV=0 playwright test" + "e2e": "pnpm build && cross-env TRILIUM_INTEGRATION_TEST=memory-no-store TRILIUM_PORT=8082 TRILIUM_DATA_DIR=data-e2e TRILIUM_ELECTRON_DATA_DIR=data-e2e-electron-8082 ELECTRON_IS_DEV=0 playwright test" }, "dependencies": { "@electron/remote": "2.1.3", diff --git a/apps/desktop/scripts/build-appimage.sh b/apps/desktop/scripts/build-appimage.sh new file mode 100755 index 0000000000..ec728470a9 --- /dev/null +++ b/apps/desktop/scripts/build-appimage.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Build an AppImage from the packaged Electron app. +# +# Usage: ./build-appimage.sh [arch] +# arch: x64 or arm64 (default: x64) +# +# Prerequisites: +# - The Electron app must already be packaged via `electron-forge make` or `electron-forge package` +# - appimagetool must be available in PATH +# +# Environment variables: +# TRILIUM_ARTIFACT_NAME_HINT: If set, used as the base name for the output file + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DESKTOP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +FORGE_DIR="$DESKTOP_DIR/electron-forge" + +ARCH="${1:-x64}" +EXECUTABLE_NAME="trilium" +PRODUCT_NAME="Trilium Notes" + +# Map architecture names +case "$ARCH" in + x64) APPIMAGE_ARCH="x86_64" ;; + arm64) APPIMAGE_ARCH="aarch64" ;; + *) echo "Unsupported architecture: $ARCH"; exit 1 ;; +esac + +# Find the packaged app directory +PACKAGED_DIR="$DESKTOP_DIR/dist/out/$PRODUCT_NAME-linux-$ARCH" +if [ ! -d "$PACKAGED_DIR" ]; then + echo "Error: Packaged app not found at $PACKAGED_DIR" + echo "Run 'electron-forge make' or 'electron-forge package' first." + exit 1 +fi + +echo "Building AppImage from: $PACKAGED_DIR" + +# Create AppDir structure +APPDIR="$DESKTOP_DIR/dist/out/$PRODUCT_NAME.AppDir" +rm -rf "$APPDIR" +mkdir -p "$APPDIR" + +# Copy the packaged app contents into the AppDir +cp -a "$PACKAGED_DIR"/. "$APPDIR/" + +# Create the AppRun entry point +cat > "$APPDIR/AppRun" << 'APPRUN_EOF' +#!/bin/bash +HERE="$(dirname "$(readlink -f "$0")")" +exec "$HERE/trilium" "$@" +APPRUN_EOF +chmod +x "$APPDIR/AppRun" + +# Create the .desktop file +cat > "$APPDIR/$EXECUTABLE_NAME.desktop" << DESKTOP_EOF +[Desktop Entry] +Name=$PRODUCT_NAME +Comment=Build your personal knowledge base with Trilium Notes +GenericName=Note Taking Application +Exec=$EXECUTABLE_NAME %U +Icon=$EXECUTABLE_NAME +Type=Application +StartupNotify=true +StartupWMClass=$PRODUCT_NAME +Categories=Office;Utility; +DESKTOP_EOF + +# Copy the icon (AppImage expects it at the root of AppDir) +if [ -f "$FORGE_DIR/app-icon/png/256x256.png" ]; then + cp "$FORGE_DIR/app-icon/png/256x256.png" "$APPDIR/$EXECUTABLE_NAME.png" +elif [ -f "$APPDIR/icon.png" ]; then + cp "$APPDIR/icon.png" "$APPDIR/$EXECUTABLE_NAME.png" +else + echo "Warning: No icon found" +fi + +# Determine output filename +UPLOAD_DIR="$DESKTOP_DIR/upload" +mkdir -p "$UPLOAD_DIR" + +if [ -n "${TRILIUM_ARTIFACT_NAME_HINT:-}" ]; then + OUTPUT_NAME="${TRILIUM_ARTIFACT_NAME_HINT//\//-}.AppImage" +else + VERSION=$(node -e "console.log(require('$DESKTOP_DIR/package.json').version)") + OUTPUT_NAME="TriliumNotes-v${VERSION}-linux-${ARCH}.AppImage" +fi + +OUTPUT_PATH="$UPLOAD_DIR/$OUTPUT_NAME" + +# Build the AppImage +echo "Creating AppImage: $OUTPUT_PATH" +ARCH="$APPIMAGE_ARCH" appimagetool "$APPDIR" "$OUTPUT_PATH" + +# Clean up the AppDir +rm -rf "$APPDIR" + +echo "AppImage created successfully: $OUTPUT_PATH" diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 3617c4c9f4..508e7be7e7 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -10,7 +10,7 @@ import electronDebug from "electron-debug"; import electronDl from "electron-dl"; import { PRODUCT_NAME } from "./app-info"; import port from "@triliumnext/server/src/services/port.js"; -import { join } from "path"; +import { join, resolve } from "path"; import { deferred, LOCALES } from "../../../packages/commons/src"; async function main() { @@ -101,10 +101,16 @@ async function main() { /** * Returns a unique user data directory for Electron so that single instance locks between legitimately different instances such as different port or data directory can still act independently, but we are focusing the main window otherwise. + * + * When running in portable mode, set TRILIUM_ELECTRON_DATA_DIR (e.g. via the trilium-portable script) + * so that no Electron files are written to the system's roaming profile (e.g. %APPDATA% on Windows). */ function getUserData() { - const name = `${app.getName()}-${port}`; - return join(app.getPath("appData"), name); + if (process.env.TRILIUM_ELECTRON_DATA_DIR) { + return resolve(process.env.TRILIUM_ELECTRON_DATA_DIR); + } + + return join(app.getPath("appData"), `${app.getName()}-${port}`); } async function onReady() { diff --git a/apps/server/package.json b/apps/server/package.json index 6cefc7f673..0e5e75acf8 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -32,9 +32,9 @@ "dependencies": { "@ai-sdk/anthropic": "3.0.69", "@ai-sdk/google": "3.0.63", - "@ai-sdk/openai": "3.0.52", + "@ai-sdk/openai": "3.0.53", "@modelcontextprotocol/sdk": "^1.12.1", - "ai": "6.0.159", + "ai": "6.0.161", "better-sqlite3": "12.9.0", "html-to-text": "9.0.5", "js-yaml": "4.1.1", diff --git a/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json b/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json index 9997e61c67..05880adefa 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json +++ b/apps/server/src/assets/doc_notes/en/User Guide/!!!meta.json @@ -1 +1 @@ -[{"id":"_help_BOCnjTMBCoxW","title":"Feature Highlights","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Feature Highlights"},{"name":"iconClass","value":"bx bx-star","type":"label"}]},{"id":"_help_Otzi9La2YAUX","title":"Installation & Setup","type":"book","attributes":[{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_poXkQfguuA0U","title":"Desktop Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation"},{"name":"iconClass","value":"bx bx-desktop","type":"label"}],"children":[{"id":"_help_nRqcgfTb97uV","title":"Using the desktop application as a server","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application "},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_Rp0q8bSP6Ayl","title":"System Requirements","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements"},{"name":"iconClass","value":"bx bx-chip","type":"label"}]},{"id":"_help_Un4wj2Mak2Ky","title":"Nix flake","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]}]},{"id":"_help_WOcw2SLH6tbX","title":"Server Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation"},{"name":"iconClass","value":"bx bx-server","type":"label"}],"children":[{"id":"_help_Dgg7bR3b6K9j","title":"1. Installing the server","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_3tW6mORuTHnB","title":"Packaged version for Linux","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_rWX5eY045zbE","title":"Using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker"},{"name":"iconClass","value":"bx bxl-docker","type":"label"}]},{"id":"_help_moVgBcoxE3EK","title":"On NixOS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_J1Bb6lVlwU5T","title":"Manually","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]},{"id":"_help_DCmT6e7clMoP","title":"Using Kubernetes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes"},{"name":"iconClass","value":"bx bxl-kubernetes","type":"label"}]},{"id":"_help_klCWNks3ReaQ","title":"Multiple server instances","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances"},{"name":"iconClass","value":"bx bxs-user-account","type":"label"}]}]},{"id":"_help_vcjrb3VVYPZI","title":"2. Reverse proxy","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_ud6MShXL4WpO","title":"Nginx","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_fDLvzOx29Pfg","title":"Apache using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_LLzSMXACKhUs","title":"Trusted proxy","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_5ERVJb9s4FRD","title":"Traefik","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_l2VkvOwUNfZj","title":"HTTPS (TLS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS)"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_0hzsNCP31IAB","title":"Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Authentication"},{"name":"iconClass","value":"bx bx-user","type":"label"}]},{"id":"_help_7DAiwaf8Z7Rz","title":"Multi-Factor Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication"},{"name":"iconClass","value":"bx bx-stopwatch","type":"label"}]},{"id":"_help_Un4wj2Mak2Ky","title":"Nix flake","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_yeEaYqosGLSh","title":"Third-party cloud hosting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting"},{"name":"iconClass","value":"bx bx-cloud","type":"label"}]},{"id":"_help_iGTnKjubbXkA","title":"System Requirements","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/System Requirements"},{"name":"iconClass","value":"bx bx-chip","type":"label"}]}]},{"id":"_help_cbkrhQjrkKrh","title":"Synchronization","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Synchronization"},{"name":"iconClass","value":"bx bx-sync","type":"label"}]},{"id":"_help_RDslemsQ6gCp","title":"Mobile Frontend","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Mobile Frontend"},{"name":"iconClass","value":"bx bx-mobile-alt","type":"label"}]},{"id":"_help_MtPxeAWVAzMg","title":"Web Clipper","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Web Clipper"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_n1lujUxCwipy","title":"Upgrading TriliumNext","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Upgrading TriliumNext"},{"name":"iconClass","value":"bx bx-up-arrow-alt","type":"label"}]},{"id":"_help_ODY7qQn5m2FT","title":"Backup","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Backup"},{"name":"iconClass","value":"bx bx-hdd","type":"label"}]},{"id":"_help_tAassRL4RSQL","title":"Data directory","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Data directory"},{"name":"iconClass","value":"bx bx-folder-open","type":"label"}]}]},{"id":"_help_gh7bpGYxajRS","title":"Basic Concepts and Features","type":"book","attributes":[{"name":"iconClass","value":"bx bx-help-circle","type":"label"}],"children":[{"id":"_help_Vc8PjrjAGuOp","title":"UI Elements","type":"book","attributes":[{"name":"iconClass","value":"bx bx-window-alt","type":"label"}],"children":[{"id":"_help_x0JgW8UqGXvq","title":"Vertical and horizontal layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Vertical and horizontal layout"},{"name":"iconClass","value":"bx bxs-layout","type":"label"}]},{"id":"_help_x3i7MxGccDuM","title":"Global menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Global menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_oPVyFC7WL2Lp","title":"Note Tree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree"},{"name":"iconClass","value":"bx bxs-tree-alt","type":"label"}],"children":[{"id":"_help_YtSN43OrfzaA","title":"Note tree contextual menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_yTjUdsOi4CIE","title":"Multiple selection","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Multiple selection"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_DvdZhoQZY9Yd","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_wyaGBBQrl4i3","title":"Hiding the subtree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]}]},{"id":"_help_BlN9DFI679QC","title":"Ribbon","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon"},{"name":"iconClass","value":"bx bx-dots-horizontal","type":"label"}]},{"id":"_help_3seOhtN8uLIY","title":"Tabs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs"},{"name":"iconClass","value":"bx bx-dock-top","type":"label"}]},{"id":"_help_xYmIYSP6wE3F","title":"Launch Bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar"},{"name":"iconClass","value":"bx bx-sidebar","type":"label"}]},{"id":"_help_8YBEPzcpUgxw","title":"Note buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons"},{"name":"iconClass","value":"bx bx-dots-vertical-rounded","type":"label"}]},{"id":"_help_4TIF1oA4VQRO","title":"Options","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Options"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]},{"id":"_help_luNhaphA37EO","title":"Split View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View"},{"name":"iconClass","value":"bx bx-dock-right","type":"label"}]},{"id":"_help_XpOYSgsLkTJy","title":"Floating buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Floating buttons"},{"name":"iconClass","value":"bx bx-rectangle","type":"label"}]},{"id":"_help_RnaPdbciOfeq","title":"Right Sidebar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar"},{"name":"iconClass","value":"bx bxs-dock-right","type":"label"}]},{"id":"_help_r5JGHN99bVKn","title":"Recent Changes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_ny318J39E5Z0","title":"Zoom","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom"},{"name":"iconClass","value":"bx bx-zoom-in","type":"label"}]},{"id":"_help_lgKX7r3aL30x","title":"Note Tooltip","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip"},{"name":"iconClass","value":"bx bx-message-detail","type":"label"}]},{"id":"_help_IjZS7iK5EXtb","title":"New Layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout"},{"name":"iconClass","value":"bx bx-layout","type":"label"}],"children":[{"id":"_help_I6p2a06hdnL6","title":"Breadcrumb","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb"},{"name":"iconClass","value":"bx bx-chevron-right","type":"label"}]},{"id":"_help_AlJ73vBCjWDw","title":"Status bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar"},{"name":"iconClass","value":"bx bx-dock-bottom","type":"label"}]}]},{"id":"_help_SL5f1Auq7sVN","title":"Note types with split view","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view"},{"name":"iconClass","value":"bx bx-card","type":"label"}]}]},{"id":"_help_BFs8mudNFgCS","title":"Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes"},{"name":"iconClass","value":"bx bx-notepad","type":"label"}],"children":[{"id":"_help_p9kXRFAkwN4o","title":"Note Icons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Icons"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_0vhv7lsOLy82","title":"Attachments","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Attachments"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_IakOLONlIfGI","title":"Cloning Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes"},{"name":"iconClass","value":"bx bx-duplicate","type":"label"}],"children":[{"id":"_help_TBwsyfadTA18","title":"Branch prefix","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes/Branch prefix"},{"name":"iconClass","value":"bx bx-rename","type":"label"}]}]},{"id":"_help_bwg0e8ewQMak","title":"Protected Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Protected Notes"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_MKmLg5x6xkor","title":"Archived Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Archived Notes"},{"name":"iconClass","value":"bx bx-box","type":"label"}]},{"id":"_help_vZWERwf8U3nx","title":"Note Revisions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Revisions"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_aGlEvb9hyDhS","title":"Sorting Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes"},{"name":"iconClass","value":"bx bx-sort-up","type":"label"}]},{"id":"_help_NRnIZmSMc5sj","title":"Printing & Exporting as PDF","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF"},{"name":"iconClass","value":"bx bx-printer","type":"label"}]},{"id":"_help_CoFPLs3dRlXc","title":"Read-Only Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_0ESUbbAxVnoK","title":"Note List","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]}]},{"id":"_help_wArbEsdSae6g","title":"Navigation","type":"book","attributes":[{"name":"iconClass","value":"bx bx-navigation","type":"label"}],"children":[{"id":"_help_kBrnXNG3Hplm","title":"Tree Concepts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Tree Concepts"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}]},{"id":"_help_MMiBEQljMQh2","title":"Note Navigation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Navigation"},{"name":"iconClass","value":"bx bxs-navigation","type":"label"}]},{"id":"_help_Ms1nauBra7gq","title":"Quick search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_F1r9QtzQLZqm","title":"Jump to...","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Jump to"},{"name":"iconClass","value":"bx bx-send","type":"label"}]},{"id":"_help_eIg8jdvaoNNd","title":"Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_u3YFHC9tQlpm","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmarks","type":"label"}]},{"id":"_help_OR8WJ7Iz9K4U","title":"Note Hoisting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Hoisting"},{"name":"iconClass","value":"bx bxs-chevrons-up","type":"label"}]},{"id":"_help_ZjLYv08Rp3qC","title":"Quick edit","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit"},{"name":"iconClass","value":"bx bx-edit","type":"label"}]},{"id":"_help_9sRHySam5fXb","title":"Workspaces","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Workspaces"},{"name":"iconClass","value":"bx bx-door-open","type":"label"}]},{"id":"_help_xWtq5NUHOwql","title":"Similar Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Similar Notes"},{"name":"iconClass","value":"bx bx-bar-chart","type":"label"}]},{"id":"_help_McngOG2jbUWX","title":"Search in note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search in note"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]}]},{"id":"_help_A9Oc6YKKc65v","title":"Keyboard Shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_Wy267RK4M69c","title":"Themes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes"},{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_VbjZvtUek0Ln","title":"Theme Gallery","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]},{"id":"_help_gOKqSJgXLcIj","title":"Icon Packs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_mHbBMPDPkVV5","title":"Import & Export","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export"},{"name":"iconClass","value":"bx bx-import","type":"label"}],"children":[{"id":"_help_Oau6X9rCuegd","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}],"children":[{"id":"_help_rJ9grSgoExl9","title":"Supported syntax","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown/Supported syntax"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]}]},{"id":"_help_syuSEKf2rUGr","title":"Evernote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote"},{"name":"iconClass","value":"bx bx-window-open","type":"label"}],"children":[{"id":"_help_dj3j8dG4th4l","title":"Process internal links by title","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GnhlmrATVqcH","title":"OneNote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/OneNote"},{"name":"iconClass","value":"bx bx-window-open","type":"label"}]}]},{"id":"_help_rC3pL2aptaRE","title":"Zen mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Zen mode"},{"name":"iconClass","value":"bx bxs-yin-yang","type":"label"}]},{"id":"_help_YzMcWlCVeW09","title":"Active content","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Active content"},{"name":"iconClass","value":"bx bxs-widget","type":"label"}]}]},{"id":"_help_s3YCWHBfmYuM","title":"Quick Start","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Quick Start"},{"name":"iconClass","value":"bx bx-run","type":"label"}]},{"id":"_help_i6dbnitykE5D","title":"FAQ","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/FAQ"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_KSZ04uQ2D1St","title":"Note Types","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types"},{"name":"iconClass","value":"bx bx-edit","type":"label"}],"children":[{"id":"_help_iPIMuisry3hd","title":"Text","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text"},{"name":"iconClass","value":"bx bx-note","type":"label"}],"children":[{"id":"_help_NwBbFdNZ9h7O","title":"Block quotes & admonitions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Block quotes & admonitions"},{"name":"iconClass","value":"bx bx-info-circle","type":"label"}]},{"id":"_help_oSuaNgyyKnhu","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmark","type":"label"}]},{"id":"_help_veGu4faJErEM","title":"Content language & Right-to-left support","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Content language & Right-to-le"},{"name":"iconClass","value":"bx bx-align-right","type":"label"}]},{"id":"_help_2x0ZAX9ePtzV","title":"Cut to subnote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Cut to subnote"},{"name":"iconClass","value":"bx bx-cut","type":"label"}]},{"id":"_help_UYuUB1ZekNQU","title":"Developer-specific formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_QxEyIjRBizuC","title":"Code blocks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks"},{"name":"iconClass","value":"bx bx-code","type":"label"}]}]},{"id":"_help_AgjCISero73a","title":"Footnotes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Footnotes"},{"name":"iconClass","value":"bx bx-bracket","type":"label"}]},{"id":"_help_nRhnJkTT8cPs","title":"Formatting toolbar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Formatting toolbar"},{"name":"iconClass","value":"bx bx-text","type":"label"}]},{"id":"_help_Gr6xFaF6ioJ5","title":"General formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/General formatting"},{"name":"iconClass","value":"bx bx-bold","type":"label"}]},{"id":"_help_AxshuNRegLAv","title":"Highlights list","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Highlights list"},{"name":"iconClass","value":"bx bx-highlight","type":"label"}]},{"id":"_help_mT0HEkOsz6i1","title":"Images","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images"},{"name":"iconClass","value":"bx bx-image-alt","type":"label"}],"children":[{"id":"_help_0Ofbk1aSuVRu","title":"Image references","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images/Image references"},{"name":"iconClass","value":"bx bxs-file-image","type":"label"}]}]},{"id":"_help_nBAXQFj20hS1","title":"Include Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Include Note"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_CohkqWQC1iBv","title":"Insert buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Insert buttons"},{"name":"iconClass","value":"bx bx-plus","type":"label"}]},{"id":"_help_oiVPnW8QfnvS","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_QEAPj01N5f7w","title":"Links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links"},{"name":"iconClass","value":"bx bx-link-alt","type":"label"}],"children":[{"id":"_help_3IDVtesTQ8ds","title":"External links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links/External links"},{"name":"iconClass","value":"bx bx-link-external","type":"label"}]},{"id":"_help_hrZ1D00cLbal","title":"Internal (reference) links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links/Internal (reference) links"},{"name":"iconClass","value":"bx bx-link","type":"label"}]}]},{"id":"_help_S6Xx8QIWTV66","title":"Lists","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Lists"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_QrtTYPmdd1qq","title":"Markdown-like formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Markdown-like formatting"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]},{"id":"_help_YfYAtQBcfo5V","title":"Math Equations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Math Equations"},{"name":"iconClass","value":"bx bx-math","type":"label"}]},{"id":"_help_dEHYtoWWi8ct","title":"Other features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Other features"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_gLt3vA97tMcp","title":"Premium features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features"},{"name":"iconClass","value":"bx bx-star","type":"label"}],"children":[{"id":"_help_ZlN4nump6EbW","title":"Slash Commands","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Slash Commands"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_pwc194wlRzcH","title":"Text Snippets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Text Snippets"},{"name":"iconClass","value":"bx bx-align-left","type":"label"}]},{"id":"_help_5wZallV2Qo1t","title":"Format Painter","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Format Painter"},{"name":"iconClass","value":"bx bxs-paint-roll","type":"label"}]}]},{"id":"_help_oBo3iHIZnbG2","title":"Spell Check","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Spell Check"},{"name":"iconClass","value":"bx bx-check-double","type":"label"}]},{"id":"_help_BFvAtE74rbP6","title":"Table of contents","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Table of contents"},{"name":"iconClass","value":"bx bx-heading","type":"label"}]},{"id":"_help_NdowYOC1GFKS","title":"Tables","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Tables"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_6f9hih2hXXZk","title":"Code","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Code"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_m523cpzocqaD","title":"Saved Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Saved Search"},{"name":"iconClass","value":"bx bx-file-find","type":"label"}]},{"id":"_help_iRwzGnHPzonm","title":"Relation Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Relation Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_bdUJEHsAPYQR","title":"Note Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Note Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_HcABDtFCkbFN","title":"Render Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Render Note"},{"name":"iconClass","value":"bx bx-extension","type":"label"}]},{"id":"_help_s1aBHPd79XYj","title":"Mermaid Diagrams","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams"},{"name":"iconClass","value":"bx bx-selection","type":"label"}],"children":[{"id":"_help_RH6yLjjWJHof","title":"ELK layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams/ELK layout"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_WWgeUaBb7UfC","title":"Syntax reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://mermaid.js.org/intro/syntax-reference.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_grjYqerjn243","title":"Canvas","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Canvas"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_1vHRoWCEjj0L","title":"Web View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Web View"},{"name":"iconClass","value":"bx bx-globe-alt","type":"label"}]},{"id":"_help_gBbsAeiuUxI5","title":"Mind Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mind Map"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_W8vYD3Q1zjCR","title":"File","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File"},{"name":"iconClass","value":"bx bx-file-blank","type":"label"}],"children":[{"id":"_help_XJGJrpu7F9sh","title":"PDFs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File/PDFs"},{"name":"iconClass","value":"bx bxs-file-pdf","type":"label"}]},{"id":"_help_AjqEeiDUOzj4","title":"Videos","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File/Videos"},{"name":"iconClass","value":"bx bx-video","type":"label"}]}]},{"id":"_help_GWHEkY4I4OE3","title":"Spreadsheets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Spreadsheets"},{"name":"iconClass","value":"bx bx-table","type":"label"}]},{"id":"_help_6RM1Q7ppFVoj","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]}]},{"id":"_help_GTwFsgaA0lCt","title":"Collections","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections"},{"name":"iconClass","value":"bx bx-book","type":"label"}],"children":[{"id":"_help_xWbu3jpNWapp","title":"Calendar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Calendar"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_2FvYrpmOXm29","title":"Table","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Table"},{"name":"iconClass","value":"bx bx-table","type":"label"}]},{"id":"_help_CtBQqbwXDx1w","title":"Kanban Board","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Kanban Board"},{"name":"iconClass","value":"bx bx-columns","type":"label"}]},{"id":"_help_81SGnPGMk7Xc","title":"Geo Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Geo Map"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]},{"id":"_help_zP3PMqaG71Ct","title":"Presentation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Presentation"},{"name":"iconClass","value":"bx bx-slideshow","type":"label"}]},{"id":"_help_8QqnMzx393bx","title":"Grid View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Grid View"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_mULW0Q3VojwY","title":"List View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/List View"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_CssoWBu8I7jF","title":"Collection Properties","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Collection Properties"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]}]},{"id":"_help_BgmBlOIl72jZ","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting"},{"name":"iconClass","value":"bx bx-bug","type":"label"}],"children":[{"id":"_help_wy8So3yZZlH9","title":"Reporting issues","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Reporting issues"},{"name":"iconClass","value":"bx bx-bug-alt","type":"label"}]},{"id":"_help_x59R8J8KV5Bp","title":"Anonymized Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Anonymized Database"},{"name":"iconClass","value":"bx bx-low-vision","type":"label"}]},{"id":"_help_qzNzp9LYQyPT","title":"Error logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs"},{"name":"iconClass","value":"bx bx-comment-error","type":"label"}],"children":[{"id":"_help_bnyigUA2UK7s","title":"Backend (server) logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs/Backend (server) logs"},{"name":"iconClass","value":"bx bx-server","type":"label"}]},{"id":"_help_9yEHzMyFirZR","title":"Frontend logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs/Frontend logs"},{"name":"iconClass","value":"bx bx-window-alt","type":"label"}]}]},{"id":"_help_vdlYGAcpXAgc","title":"Synchronization fails with 504 Gateway Timeout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Synchronization fails with 504"},{"name":"iconClass","value":"bx bx-error","type":"label"}]},{"id":"_help_s8alTXmpFR61","title":"Refreshing the application","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Refreshing the application"},{"name":"iconClass","value":"bx bx-refresh","type":"label"}]}]},{"id":"_help_pKK96zzmvBGf","title":"Theme development","type":"book","attributes":[{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_7NfNr5pZpVKV","title":"Creating a custom theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating a custom theme"},{"name":"iconClass","value":"bx bxs-color","type":"label"}]},{"id":"_help_WFGzWeUK6arS","title":"Customize the Next theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Customize the Next theme"},{"name":"iconClass","value":"bx bx-news","type":"label"}]},{"id":"_help_WN5z4M8ASACJ","title":"Reference","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Reference"},{"name":"iconClass","value":"bx bx-book-open","type":"label"}]},{"id":"_help_AlhDUqhENtH7","title":"Custom app-wide CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Custom app-wide CSS"},{"name":"iconClass","value":"bx bxs-file-css","type":"label"}]},{"id":"_help_g1mlRoU8CsqC","title":"Creating an icon pack","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating an icon pack"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_tC7s2alapj8V","title":"Advanced Usage","type":"book","attributes":[{"name":"iconClass","value":"bx bx-rocket","type":"label"}],"children":[{"id":"_help_zEY4DaJG4YT5","title":"Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes"},{"name":"iconClass","value":"bx bx-list-check","type":"label"}],"children":[{"id":"_help_HI6GBBIduIgv","title":"Labels","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Labels"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_Cq5X6iKQop6R","title":"Relations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Relations"},{"name":"iconClass","value":"bx bx-transfer","type":"label"}]},{"id":"_help_bwZpz2ajCEwO","title":"Attribute Inheritance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Attribute Inheritance"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_OFXdgB2nNk1F","title":"Promoted Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_KC1HB96bqqHX","title":"Templates","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Templates"},{"name":"iconClass","value":"bx bx-copy","type":"label"}]},{"id":"_help_BCkXAVs63Ttv","title":"Note Map (Link map, Tree map)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map)"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_R9pX4DGra2Vt","title":"Sharing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing"},{"name":"iconClass","value":"bx bx-share-alt","type":"label"}],"children":[{"id":"_help_Qjt68inQ2bRj","title":"Serving directly the content of a note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Serving directly the content o"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_ycBFjKrrwE9p","title":"Exporting static HTML for web publishing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Exporting static HTML for web "},{"name":"iconClass","value":"bx bxs-file-html","type":"label"}]},{"id":"_help_sLIJ6f1dkJYW","title":"Reverse proxy configuration","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Reverse proxy configuration"},{"name":"iconClass","value":"bx bx-world","type":"label"}]}]},{"id":"_help_5668rwcirq1t","title":"Advanced Showcases","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_l0tKav7yLHGF","title":"Day Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Day Notes"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_R7abl2fc6Mxi","title":"Weight Tracker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Weight Tracker"},{"name":"iconClass","value":"bx bx-line-chart","type":"label"}]},{"id":"_help_xYjQUYhpbUEW","title":"Task Manager","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager"},{"name":"iconClass","value":"bx bx-calendar-check","type":"label"}]}]},{"id":"_help_J5Ex1ZrMbyJ6","title":"Custom Request Handler","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Request Handler"},{"name":"iconClass","value":"bx bx-globe","type":"label"}]},{"id":"_help_d3fAXQ2diepH","title":"Custom Resource Providers","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Resource Providers"},{"name":"iconClass","value":"bx bxs-file-plus","type":"label"}]},{"id":"_help_pgxEVkzLl1OP","title":"ETAPI (REST API)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/ETAPI (REST API)"},{"name":"iconClass","value":"bx bx-extension","type":"label"}],"children":[{"id":"_help_9qPsTWBorUhQ","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/rest-api/etapi/"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_47ZrP6FNuoG8","title":"Default Note Title","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Default Note Title"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_wX4HbRucYSDD","title":"Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database"},{"name":"iconClass","value":"bx bx-data","type":"label"}],"children":[{"id":"_help_oyIAJ9PvvwHX","title":"Manually altering the database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database"},{"name":"iconClass","value":"bx bxs-edit","type":"label"}],"children":[{"id":"_help_YKWqdJhzi2VY","title":"SQL Console","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console"},{"name":"iconClass","value":"bx bx-data","type":"label"}]}]},{"id":"_help_6tZeKvSHEUiB","title":"Demo Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Demo Notes"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_Gzjqa934BdH4","title":"Configuration (config.ini or environment variables)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or e"},{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_c5xB8m4g2IY6","title":"Trilium instance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Trilium instance"},{"name":"iconClass","value":"bx bx-windows","type":"label"}]},{"id":"_help_LWtBjFej3wX3","title":"Cross-Origin Resource Sharing (CORS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Cross-Origin Resource Sharing "},{"name":"iconClass","value":"bx bx-lock","type":"label"}]}]},{"id":"_help_ivYnonVFBxbQ","title":"Bulk Actions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Bulk Actions"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_4FahAwuGTAwC","title":"Note source","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note source"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_1YeN2MzFUluU","title":"Technologies used","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}],"children":[{"id":"_help_MI26XDLSAlCD","title":"CKEditor","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/CKEditor"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_N4IDkixaDG9C","title":"MindElixir","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/MindElixir"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_H0mM1lTxF9JI","title":"Excalidraw","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Excalidraw"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_MQHyy2dIFgxS","title":"Leaflet","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Leaflet"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]}]},{"id":"_help_m1lbrzyKDaRB","title":"Note ID","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note ID"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_0vTSyvhPTAOz","title":"Internal API","type":"book","attributes":[{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_z8O2VG4ZZJD7","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/rest-api/internal/"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_2mUhVmZK8RF3","title":"Hidden Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Hidden Notes"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]},{"id":"_help_uYF7pmepw27K","title":"Metrics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Metrics"},{"name":"iconClass","value":"bx bxs-data","type":"label"}],"children":[{"id":"_help_bOP3TB56fL1V","title":"grafana-dashboard.json","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_64ZTlUPgEPtW","title":"Safe mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Safe mode"},{"name":"iconClass","value":"bx bxs-virus-block","type":"label"}]},{"id":"_help_HAIOFBoYIIdO","title":"Nightly release","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Nightly release"},{"name":"iconClass","value":"bx bx-moon","type":"label"}]},{"id":"_help_ZmT9ln8XJX2o","title":"Read-only database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Read-only database"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]}]},{"id":"_help_GBBMSlVSOIGP","title":"AI","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI"},{"name":"iconClass","value":"bx bx-bot","type":"label"}]},{"id":"_help_CdNpE2pqjmI6","title":"Scripting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting"},{"name":"iconClass","value":"bx bxs-file-js","type":"label"}],"children":[{"id":"_help_yIhgI5H7A2Sm","title":"Frontend Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics"},{"name":"iconClass","value":"bx bx-window","type":"label"}],"children":[{"id":"_help_MgibgPcfeuGz","title":"Custom Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets"},{"name":"iconClass","value":"bx bxs-widget","type":"label"}],"children":[{"id":"_help_SynTBQiBsdYJ","title":"Widget Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Widget Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GhurYZjh8e1V","title":"Note context aware widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_M8IppdwVHSjG","title":"Right pane widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_YNxAqkI5Kg1M","title":"Word count widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_VqGQnnPGnqAU","title":"CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/CSS"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_gMkgcLJ6jBkg","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Troubleshooting"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_es8OU2GuguFU","title":"Examples","type":"book","attributes":[{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_TjLYAo3JMO8X","title":"\"New Task\" launcher button","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button"},{"name":"iconClass","value":"bx bx-task","type":"label"}]},{"id":"_help_7kZPMD0uFwkH","title":"Downloading responses from Google Forms","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_DL92EjAaXT26","title":"Using promoted attributes to configure scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_4Gn3psZKsfSm","title":"Launch Bar Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets"},{"name":"iconClass","value":"bx bx-dock-left","type":"label"}],"children":[{"id":"_help_IPArqVfDQ4We","title":"Note Title Widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_gcI7RPbaNSh3","title":"Analog Watch","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_KLsqhjaqh1QW","title":"Preact","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact"},{"name":"iconClass","value":"bx bxl-react","type":"label"}],"children":[{"id":"_help_Bqde6BvPo05g","title":"Component libraries","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries"},{"name":"iconClass","value":"bx bxs-component","type":"label"}]},{"id":"_help_ykYtbM9k3a7B","title":"Hooks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_Sg9GrCtyftZf","title":"CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS"},{"name":"iconClass","value":"bx bxs-file-css","type":"label"}]},{"id":"_help_RSssb9S3xgSr","title":"Built-in components","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_i9B4IW7b6V6z","title":"Widget showcase","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]}]},{"id":"_help_SPirpZypehBG","title":"Backend scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts"},{"name":"iconClass","value":"bx bx-server","type":"label"}],"children":[{"id":"_help_fZ2IGYFXjkEy","title":"Server-side imports","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts/Server-side imports"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GPERMystNGTB","title":"Events","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts/Events"},{"name":"iconClass","value":"bx bx-rss","type":"label"}]}]},{"id":"_help_wqXwKJl6VpNk","title":"Common concepts","type":"book","attributes":[{"name":"iconClass","value":"bx bxl-nodejs","type":"label"}],"children":[{"id":"_help_hA834UaHhSNn","title":"Script bundles","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Common concepts/Script bundles"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_GLks18SNjxmC","title":"Script API","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API"},{"name":"iconClass","value":"bx bx-code-curly","type":"label"}],"children":[{"id":"_help_Q2z6av6JZVWm","title":"Frontend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/frontend"},{"name":"iconClass","value":"bx bx-folder","type":"label"}],"enforceAttributes":true,"children":[{"id":"_help_habiZ3HU8Kw8","title":"FNote","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/frontend/interfaces/FNote.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_MEtfsqa5VwNi","title":"Backend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/backend"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true},{"id":"_help_ApVHZ8JY5ofC","title":"Day.js","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API/Day.js"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]}]},{"id":"_help_vElnKeDNPSVl","title":"Logging","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Logging"},{"name":"iconClass","value":"bx bx-terminal","type":"label"}]},{"id":"_help_cNpC0ITcfX0N","title":"Breaking changes","type":"book","attributes":[{"name":"iconClass","value":"bx bx-up-arrow-alt","type":"label"}],"children":[{"id":"_help_fqAK6opjUagR","title":"v0.103.0: Removal of axios","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.103.0 Removal of axios"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_pAJ0jWz16xFm","title":"v0.103.0: `cheerio` is now deprecated","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.103.0 `cheerio` is now depr"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_72dxvnbnkDFY","title":"v0.102.0: Upgrade to jQuery 4.0.0","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.102.0 Upgrade to jQuery.0.0"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_Fm0j45KqyHpU","title":"Miscellaneous","type":"book","attributes":[{"name":"iconClass","value":"bx bx-info-circle","type":"label"}],"children":[{"id":"_help_WFbFXrgnDyyU","title":"Privacy Policy","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/Privacy Policy"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_NcsmUYZRWEW4","title":"Patterns of personal knowledge","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/Patterns of personal knowledge"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_d1Ap6Pg6IjaJ","title":"License","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/License"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}] \ No newline at end of file +[{"id":"_help_BOCnjTMBCoxW","title":"Feature Highlights","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Feature Highlights"},{"name":"iconClass","value":"bx bx-star","type":"label"}]},{"id":"_help_Otzi9La2YAUX","title":"Installation & Setup","type":"book","attributes":[{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_poXkQfguuA0U","title":"Desktop Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation"},{"name":"iconClass","value":"bx bx-desktop","type":"label"}],"children":[{"id":"_help_nRqcgfTb97uV","title":"Using the desktop application as a server","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/Using the desktop application "},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_Rp0q8bSP6Ayl","title":"System Requirements","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/System Requirements"},{"name":"iconClass","value":"bx bx-chip","type":"label"}]},{"id":"_help_Un4wj2Mak2Ky","title":"Nix flake","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Desktop Installation/Nix flake"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]}]},{"id":"_help_WOcw2SLH6tbX","title":"Server Installation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation"},{"name":"iconClass","value":"bx bx-server","type":"label"}],"children":[{"id":"_help_Dgg7bR3b6K9j","title":"1. Installing the server","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_3tW6mORuTHnB","title":"Packaged version for Linux","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Packaged version for Linux"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_rWX5eY045zbE","title":"Using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Docker"},{"name":"iconClass","value":"bx bxl-docker","type":"label"}]},{"id":"_help_moVgBcoxE3EK","title":"On NixOS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/On NixOS"},{"name":"iconClass","value":"bx bxl-tux","type":"label"}]},{"id":"_help_J1Bb6lVlwU5T","title":"Manually","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Manually"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]},{"id":"_help_DCmT6e7clMoP","title":"Using Kubernetes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Using Kubernetes"},{"name":"iconClass","value":"bx bxl-kubernetes","type":"label"}]},{"id":"_help_klCWNks3ReaQ","title":"Multiple server instances","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/1. Installing the server/Multiple server instances"},{"name":"iconClass","value":"bx bxs-user-account","type":"label"}]}]},{"id":"_help_vcjrb3VVYPZI","title":"2. Reverse proxy","type":"book","attributes":[{"name":"iconClass","value":"bx bx-folder","type":"label"}],"children":[{"id":"_help_ud6MShXL4WpO","title":"Nginx","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Nginx"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_fDLvzOx29Pfg","title":"Apache using Docker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Apache using Docker"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_LLzSMXACKhUs","title":"Trusted proxy","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Trusted proxy"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_5ERVJb9s4FRD","title":"Traefik","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/2. Reverse proxy/Traefik"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_l2VkvOwUNfZj","title":"HTTPS (TLS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/HTTPS (TLS)"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_0hzsNCP31IAB","title":"Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Authentication"},{"name":"iconClass","value":"bx bx-user","type":"label"}]},{"id":"_help_7DAiwaf8Z7Rz","title":"Multi-Factor Authentication","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Multi-Factor Authentication"},{"name":"iconClass","value":"bx bx-stopwatch","type":"label"}]},{"id":"_help_Un4wj2Mak2Ky","title":"Nix flake","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Nix flake.clone"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_yeEaYqosGLSh","title":"Third-party cloud hosting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/Third-party cloud hosting"},{"name":"iconClass","value":"bx bx-cloud","type":"label"}]},{"id":"_help_iGTnKjubbXkA","title":"System Requirements","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Server Installation/System Requirements"},{"name":"iconClass","value":"bx bx-chip","type":"label"}]}]},{"id":"_help_cbkrhQjrkKrh","title":"Synchronization","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Synchronization"},{"name":"iconClass","value":"bx bx-sync","type":"label"}]},{"id":"_help_RDslemsQ6gCp","title":"Mobile Frontend","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Mobile Frontend"},{"name":"iconClass","value":"bx bx-mobile-alt","type":"label"}]},{"id":"_help_MtPxeAWVAzMg","title":"Web Clipper","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Web Clipper"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_n1lujUxCwipy","title":"Upgrading TriliumNext","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Upgrading TriliumNext"},{"name":"iconClass","value":"bx bx-up-arrow-alt","type":"label"}]},{"id":"_help_ODY7qQn5m2FT","title":"Backup","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Backup"},{"name":"iconClass","value":"bx bx-hdd","type":"label"}]},{"id":"_help_tAassRL4RSQL","title":"Data directory","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Installation & Setup/Data directory"},{"name":"iconClass","value":"bx bx-folder-open","type":"label"}]}]},{"id":"_help_gh7bpGYxajRS","title":"Basic Concepts and Features","type":"book","attributes":[{"name":"iconClass","value":"bx bx-help-circle","type":"label"}],"children":[{"id":"_help_Vc8PjrjAGuOp","title":"UI Elements","type":"book","attributes":[{"name":"iconClass","value":"bx bx-window-alt","type":"label"}],"children":[{"id":"_help_x0JgW8UqGXvq","title":"Vertical and horizontal layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Vertical and horizontal layout"},{"name":"iconClass","value":"bx bxs-layout","type":"label"}]},{"id":"_help_x3i7MxGccDuM","title":"Global menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Global menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_oPVyFC7WL2Lp","title":"Note Tree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree"},{"name":"iconClass","value":"bx bxs-tree-alt","type":"label"}],"children":[{"id":"_help_YtSN43OrfzaA","title":"Note tree contextual menu","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Note tree contextual menu"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_yTjUdsOi4CIE","title":"Multiple selection","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Multiple selection"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_DvdZhoQZY9Yd","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_wyaGBBQrl4i3","title":"Hiding the subtree","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tree/Hiding the subtree"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]}]},{"id":"_help_BlN9DFI679QC","title":"Ribbon","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Ribbon"},{"name":"iconClass","value":"bx bx-dots-horizontal","type":"label"}]},{"id":"_help_3seOhtN8uLIY","title":"Tabs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Tabs"},{"name":"iconClass","value":"bx bx-dock-top","type":"label"}]},{"id":"_help_xYmIYSP6wE3F","title":"Launch Bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Launch Bar"},{"name":"iconClass","value":"bx bx-sidebar","type":"label"}]},{"id":"_help_8YBEPzcpUgxw","title":"Note buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note buttons"},{"name":"iconClass","value":"bx bx-dots-vertical-rounded","type":"label"}]},{"id":"_help_4TIF1oA4VQRO","title":"Options","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Options"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]},{"id":"_help_luNhaphA37EO","title":"Split View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Split View"},{"name":"iconClass","value":"bx bx-dock-right","type":"label"}]},{"id":"_help_XpOYSgsLkTJy","title":"Floating buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Floating buttons"},{"name":"iconClass","value":"bx bx-rectangle","type":"label"}]},{"id":"_help_RnaPdbciOfeq","title":"Right Sidebar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Right Sidebar"},{"name":"iconClass","value":"bx bxs-dock-right","type":"label"}]},{"id":"_help_r5JGHN99bVKn","title":"Recent Changes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Recent Changes"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_ny318J39E5Z0","title":"Zoom","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Zoom"},{"name":"iconClass","value":"bx bx-zoom-in","type":"label"}]},{"id":"_help_lgKX7r3aL30x","title":"Note Tooltip","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note Tooltip"},{"name":"iconClass","value":"bx bx-message-detail","type":"label"}]},{"id":"_help_IjZS7iK5EXtb","title":"New Layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout"},{"name":"iconClass","value":"bx bx-layout","type":"label"}],"children":[{"id":"_help_I6p2a06hdnL6","title":"Breadcrumb","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Breadcrumb"},{"name":"iconClass","value":"bx bx-chevron-right","type":"label"}]},{"id":"_help_AlJ73vBCjWDw","title":"Status bar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/New Layout/Status bar"},{"name":"iconClass","value":"bx bx-dock-bottom","type":"label"}]}]},{"id":"_help_SL5f1Auq7sVN","title":"Note types with split view","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view"},{"name":"iconClass","value":"bx bx-card","type":"label"}]}]},{"id":"_help_BFs8mudNFgCS","title":"Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes"},{"name":"iconClass","value":"bx bx-notepad","type":"label"}],"children":[{"id":"_help_p9kXRFAkwN4o","title":"Note Icons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Icons"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_0vhv7lsOLy82","title":"Attachments","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Attachments"},{"name":"iconClass","value":"bx bx-paperclip","type":"label"}]},{"id":"_help_IakOLONlIfGI","title":"Cloning Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes"},{"name":"iconClass","value":"bx bx-duplicate","type":"label"}],"children":[{"id":"_help_TBwsyfadTA18","title":"Branch prefix","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Cloning Notes/Branch prefix"},{"name":"iconClass","value":"bx bx-rename","type":"label"}]}]},{"id":"_help_bwg0e8ewQMak","title":"Protected Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Protected Notes"},{"name":"iconClass","value":"bx bx-lock-alt","type":"label"}]},{"id":"_help_MKmLg5x6xkor","title":"Archived Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Archived Notes"},{"name":"iconClass","value":"bx bx-box","type":"label"}]},{"id":"_help_vZWERwf8U3nx","title":"Note Revisions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note Revisions"},{"name":"iconClass","value":"bx bx-history","type":"label"}]},{"id":"_help_aGlEvb9hyDhS","title":"Sorting Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Sorting Notes"},{"name":"iconClass","value":"bx bx-sort-up","type":"label"}]},{"id":"_help_NRnIZmSMc5sj","title":"Printing & Exporting as PDF","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF"},{"name":"iconClass","value":"bx bx-printer","type":"label"}]},{"id":"_help_CoFPLs3dRlXc","title":"Read-Only Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Read-Only Notes"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_0ESUbbAxVnoK","title":"Note List","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Notes/Note List"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]}]},{"id":"_help_wArbEsdSae6g","title":"Navigation","type":"book","attributes":[{"name":"iconClass","value":"bx bx-navigation","type":"label"}],"children":[{"id":"_help_kBrnXNG3Hplm","title":"Tree Concepts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Tree Concepts"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}]},{"id":"_help_MMiBEQljMQh2","title":"Note Navigation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Navigation"},{"name":"iconClass","value":"bx bxs-navigation","type":"label"}]},{"id":"_help_Ms1nauBra7gq","title":"Quick search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_F1r9QtzQLZqm","title":"Jump to...","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Jump to"},{"name":"iconClass","value":"bx bx-send","type":"label"}]},{"id":"_help_eIg8jdvaoNNd","title":"Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]},{"id":"_help_u3YFHC9tQlpm","title":"Bookmarks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Bookmarks"},{"name":"iconClass","value":"bx bx-bookmarks","type":"label"}]},{"id":"_help_OR8WJ7Iz9K4U","title":"Note Hoisting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Note Hoisting"},{"name":"iconClass","value":"bx bxs-chevrons-up","type":"label"}]},{"id":"_help_ZjLYv08Rp3qC","title":"Quick edit","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Quick edit"},{"name":"iconClass","value":"bx bx-edit","type":"label"}]},{"id":"_help_9sRHySam5fXb","title":"Workspaces","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Workspaces"},{"name":"iconClass","value":"bx bx-door-open","type":"label"}]},{"id":"_help_xWtq5NUHOwql","title":"Similar Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Similar Notes"},{"name":"iconClass","value":"bx bx-bar-chart","type":"label"}]},{"id":"_help_McngOG2jbUWX","title":"Search in note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Navigation/Search in note"},{"name":"iconClass","value":"bx bx-search-alt-2","type":"label"}]}]},{"id":"_help_A9Oc6YKKc65v","title":"Keyboard Shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Keyboard Shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_Wy267RK4M69c","title":"Themes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes"},{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_VbjZvtUek0Ln","title":"Theme Gallery","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Theme Gallery"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]},{"id":"_help_gOKqSJgXLcIj","title":"Icon Packs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Themes/Icon Packs"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_mHbBMPDPkVV5","title":"Import & Export","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export"},{"name":"iconClass","value":"bx bx-import","type":"label"}],"children":[{"id":"_help_Oau6X9rCuegd","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}],"children":[{"id":"_help_rJ9grSgoExl9","title":"Supported syntax","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Markdown/Supported syntax"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}]}]},{"id":"_help_syuSEKf2rUGr","title":"Evernote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/Evernote"},{"name":"iconClass","value":"bx bx-window-open","type":"label"}],"children":[{"id":"_help_dj3j8dG4th4l","title":"Process internal links by title","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_GnhlmrATVqcH","title":"OneNote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Import & Export/OneNote"},{"name":"iconClass","value":"bx bx-window-open","type":"label"}]}]},{"id":"_help_rC3pL2aptaRE","title":"Zen mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Zen mode"},{"name":"iconClass","value":"bx bxs-yin-yang","type":"label"}]},{"id":"_help_YzMcWlCVeW09","title":"Active content","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Basic Concepts and Features/Active content"},{"name":"iconClass","value":"bx bxs-widget","type":"label"}]}]},{"id":"_help_s3YCWHBfmYuM","title":"Quick Start","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Quick Start"},{"name":"iconClass","value":"bx bx-run","type":"label"}]},{"id":"_help_i6dbnitykE5D","title":"FAQ","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/FAQ"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_KSZ04uQ2D1St","title":"Note Types","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types"},{"name":"iconClass","value":"bx bx-edit","type":"label"}],"children":[{"id":"_help_iPIMuisry3hd","title":"Text","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text"},{"name":"iconClass","value":"bx bx-note","type":"label"}],"children":[{"id":"_help_oSuaNgyyKnhu","title":"Anchors","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Anchors"},{"name":"iconClass","value":"bx bx-bookmark","type":"label"}]},{"id":"_help_NwBbFdNZ9h7O","title":"Block quotes & admonitions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Block quotes & admonitions"},{"name":"iconClass","value":"bx bx-info-circle","type":"label"}]},{"id":"_help_veGu4faJErEM","title":"Content language & Right-to-left support","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Content language & Right-to-le"},{"name":"iconClass","value":"bx bx-align-right","type":"label"}]},{"id":"_help_2x0ZAX9ePtzV","title":"Cut to subnote","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Cut to subnote"},{"name":"iconClass","value":"bx bx-cut","type":"label"}]},{"id":"_help_UYuUB1ZekNQU","title":"Developer-specific formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting"},{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_QxEyIjRBizuC","title":"Code blocks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Developer-specific formatting/Code blocks"},{"name":"iconClass","value":"bx bx-code","type":"label"}]}]},{"id":"_help_AgjCISero73a","title":"Footnotes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Footnotes"},{"name":"iconClass","value":"bx bx-bracket","type":"label"}]},{"id":"_help_nRhnJkTT8cPs","title":"Formatting toolbar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Formatting toolbar"},{"name":"iconClass","value":"bx bx-text","type":"label"}]},{"id":"_help_Gr6xFaF6ioJ5","title":"General formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/General formatting"},{"name":"iconClass","value":"bx bx-bold","type":"label"}]},{"id":"_help_AxshuNRegLAv","title":"Highlights list","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Highlights list"},{"name":"iconClass","value":"bx bx-highlight","type":"label"}]},{"id":"_help_mT0HEkOsz6i1","title":"Images","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images"},{"name":"iconClass","value":"bx bx-image-alt","type":"label"}],"children":[{"id":"_help_0Ofbk1aSuVRu","title":"Image references","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Images/Image references"},{"name":"iconClass","value":"bx bxs-file-image","type":"label"}]}]},{"id":"_help_nBAXQFj20hS1","title":"Include Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Include Note"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_CohkqWQC1iBv","title":"Insert buttons","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Insert buttons"},{"name":"iconClass","value":"bx bx-plus","type":"label"}]},{"id":"_help_oiVPnW8QfnvS","title":"Keyboard shortcuts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Keyboard shortcuts"},{"name":"iconClass","value":"bx bxs-keyboard","type":"label"}]},{"id":"_help_QEAPj01N5f7w","title":"Links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links"},{"name":"iconClass","value":"bx bx-link-alt","type":"label"}],"children":[{"id":"_help_3IDVtesTQ8ds","title":"External links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links/External links"},{"name":"iconClass","value":"bx bx-link-external","type":"label"}]},{"id":"_help_hrZ1D00cLbal","title":"Internal (reference) links","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Links/Internal (reference) links"},{"name":"iconClass","value":"bx bx-link","type":"label"}]}]},{"id":"_help_S6Xx8QIWTV66","title":"Lists","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Lists"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_QrtTYPmdd1qq","title":"Markdown-like formatting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Markdown-like formatting"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]},{"id":"_help_YfYAtQBcfo5V","title":"Math Equations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Math Equations"},{"name":"iconClass","value":"bx bx-math","type":"label"}]},{"id":"_help_dEHYtoWWi8ct","title":"Other features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Other features"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_gLt3vA97tMcp","title":"Premium features","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features"},{"name":"iconClass","value":"bx bx-star","type":"label"}],"children":[{"id":"_help_ZlN4nump6EbW","title":"Slash Commands","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Slash Commands"},{"name":"iconClass","value":"bx bx-menu","type":"label"}]},{"id":"_help_pwc194wlRzcH","title":"Text Snippets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Text Snippets"},{"name":"iconClass","value":"bx bx-align-left","type":"label"}]},{"id":"_help_5wZallV2Qo1t","title":"Format Painter","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Premium features/Format Painter"},{"name":"iconClass","value":"bx bxs-paint-roll","type":"label"}]}]},{"id":"_help_oBo3iHIZnbG2","title":"Spell Check","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Spell Check"},{"name":"iconClass","value":"bx bx-check-double","type":"label"}]},{"id":"_help_BFvAtE74rbP6","title":"Table of contents","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Table of contents"},{"name":"iconClass","value":"bx bx-heading","type":"label"}]},{"id":"_help_NdowYOC1GFKS","title":"Tables","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Text/Tables"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_6f9hih2hXXZk","title":"Code","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Code"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_m523cpzocqaD","title":"Saved Search","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Saved Search"},{"name":"iconClass","value":"bx bx-file-find","type":"label"}]},{"id":"_help_iRwzGnHPzonm","title":"Relation Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Relation Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_bdUJEHsAPYQR","title":"Note Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Note Map"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_HcABDtFCkbFN","title":"Render Note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Render Note"},{"name":"iconClass","value":"bx bx-extension","type":"label"}]},{"id":"_help_s1aBHPd79XYj","title":"Mermaid Diagrams","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams"},{"name":"iconClass","value":"bx bx-selection","type":"label"}],"children":[{"id":"_help_RH6yLjjWJHof","title":"ELK layout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mermaid Diagrams/ELK layout"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_WWgeUaBb7UfC","title":"Syntax reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://mermaid.js.org/intro/syntax-reference.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_grjYqerjn243","title":"Canvas","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Canvas"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_1vHRoWCEjj0L","title":"Web View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Web View"},{"name":"iconClass","value":"bx bx-globe-alt","type":"label"}]},{"id":"_help_gBbsAeiuUxI5","title":"Mind Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Mind Map"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_W8vYD3Q1zjCR","title":"File","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File"},{"name":"iconClass","value":"bx bx-file-blank","type":"label"}],"children":[{"id":"_help_XJGJrpu7F9sh","title":"PDFs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File/PDFs"},{"name":"iconClass","value":"bx bxs-file-pdf","type":"label"}]},{"id":"_help_AjqEeiDUOzj4","title":"Videos","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/File/Videos"},{"name":"iconClass","value":"bx bx-video","type":"label"}]}]},{"id":"_help_GWHEkY4I4OE3","title":"Spreadsheets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Spreadsheets"},{"name":"iconClass","value":"bx bx-table","type":"label"}]},{"id":"_help_6RM1Q7ppFVoj","title":"Markdown","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Note Types/Markdown"},{"name":"iconClass","value":"bx bxl-markdown","type":"label"}]}]},{"id":"_help_GTwFsgaA0lCt","title":"Collections","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections"},{"name":"iconClass","value":"bx bx-book","type":"label"}],"children":[{"id":"_help_xWbu3jpNWapp","title":"Calendar","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Calendar"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_2FvYrpmOXm29","title":"Table","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Table"},{"name":"iconClass","value":"bx bx-table","type":"label"}]},{"id":"_help_CtBQqbwXDx1w","title":"Kanban Board","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Kanban Board"},{"name":"iconClass","value":"bx bx-columns","type":"label"}]},{"id":"_help_81SGnPGMk7Xc","title":"Geo Map","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Geo Map"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]},{"id":"_help_zP3PMqaG71Ct","title":"Presentation","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Presentation"},{"name":"iconClass","value":"bx bx-slideshow","type":"label"}]},{"id":"_help_8QqnMzx393bx","title":"Grid View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Grid View"},{"name":"iconClass","value":"bx bxs-grid","type":"label"}]},{"id":"_help_mULW0Q3VojwY","title":"List View","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/List View"},{"name":"iconClass","value":"bx bx-list-ul","type":"label"}]},{"id":"_help_CssoWBu8I7jF","title":"Collection Properties","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Collections/Collection Properties"},{"name":"iconClass","value":"bx bx-cog","type":"label"}]}]},{"id":"_help_BgmBlOIl72jZ","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting"},{"name":"iconClass","value":"bx bx-bug","type":"label"}],"children":[{"id":"_help_wy8So3yZZlH9","title":"Reporting issues","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Reporting issues"},{"name":"iconClass","value":"bx bx-bug-alt","type":"label"}]},{"id":"_help_x59R8J8KV5Bp","title":"Anonymized Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Anonymized Database"},{"name":"iconClass","value":"bx bx-low-vision","type":"label"}]},{"id":"_help_qzNzp9LYQyPT","title":"Error logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs"},{"name":"iconClass","value":"bx bx-comment-error","type":"label"}],"children":[{"id":"_help_bnyigUA2UK7s","title":"Backend (server) logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs/Backend (server) logs"},{"name":"iconClass","value":"bx bx-server","type":"label"}]},{"id":"_help_9yEHzMyFirZR","title":"Frontend logs","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Error logs/Frontend logs"},{"name":"iconClass","value":"bx bx-window-alt","type":"label"}]}]},{"id":"_help_vdlYGAcpXAgc","title":"Synchronization fails with 504 Gateway Timeout","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Synchronization fails with 504"},{"name":"iconClass","value":"bx bx-error","type":"label"}]},{"id":"_help_s8alTXmpFR61","title":"Refreshing the application","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Troubleshooting/Refreshing the application"},{"name":"iconClass","value":"bx bx-refresh","type":"label"}]}]},{"id":"_help_pKK96zzmvBGf","title":"Theme development","type":"book","attributes":[{"name":"iconClass","value":"bx bx-palette","type":"label"}],"children":[{"id":"_help_7NfNr5pZpVKV","title":"Creating a custom theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating a custom theme"},{"name":"iconClass","value":"bx bxs-color","type":"label"}]},{"id":"_help_WFGzWeUK6arS","title":"Customize the Next theme","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Customize the Next theme"},{"name":"iconClass","value":"bx bx-news","type":"label"}]},{"id":"_help_WN5z4M8ASACJ","title":"Reference","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Reference"},{"name":"iconClass","value":"bx bx-book-open","type":"label"}]},{"id":"_help_AlhDUqhENtH7","title":"Custom app-wide CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Custom app-wide CSS"},{"name":"iconClass","value":"bx bxs-file-css","type":"label"}]},{"id":"_help_g1mlRoU8CsqC","title":"Creating an icon pack","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Theme development/Creating an icon pack"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_tC7s2alapj8V","title":"Advanced Usage","type":"book","attributes":[{"name":"iconClass","value":"bx bx-rocket","type":"label"}],"children":[{"id":"_help_zEY4DaJG4YT5","title":"Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes"},{"name":"iconClass","value":"bx bx-list-check","type":"label"}],"children":[{"id":"_help_HI6GBBIduIgv","title":"Labels","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Labels"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_Cq5X6iKQop6R","title":"Relations","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Relations"},{"name":"iconClass","value":"bx bx-transfer","type":"label"}]},{"id":"_help_bwZpz2ajCEwO","title":"Attribute Inheritance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Attribute Inheritance"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_OFXdgB2nNk1F","title":"Promoted Attributes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Attributes/Promoted Attributes"},{"name":"iconClass","value":"bx bx-table","type":"label"}]}]},{"id":"_help_KC1HB96bqqHX","title":"Templates","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Templates"},{"name":"iconClass","value":"bx bx-copy","type":"label"}]},{"id":"_help_BCkXAVs63Ttv","title":"Note Map (Link map, Tree map)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note Map (Link map, Tree map)"},{"name":"iconClass","value":"bx bxs-network-chart","type":"label"}]},{"id":"_help_R9pX4DGra2Vt","title":"Sharing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing"},{"name":"iconClass","value":"bx bx-share-alt","type":"label"}],"children":[{"id":"_help_Qjt68inQ2bRj","title":"Serving directly the content of a note","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Serving directly the content o"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_ycBFjKrrwE9p","title":"Exporting static HTML for web publishing","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Exporting static HTML for web "},{"name":"iconClass","value":"bx bxs-file-html","type":"label"}]},{"id":"_help_sLIJ6f1dkJYW","title":"Reverse proxy configuration","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Sharing/Reverse proxy configuration"},{"name":"iconClass","value":"bx bx-world","type":"label"}]}]},{"id":"_help_5668rwcirq1t","title":"Advanced Showcases","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_l0tKav7yLHGF","title":"Day Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Day Notes"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]},{"id":"_help_R7abl2fc6Mxi","title":"Weight Tracker","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Weight Tracker"},{"name":"iconClass","value":"bx bx-line-chart","type":"label"}]},{"id":"_help_xYjQUYhpbUEW","title":"Task Manager","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Advanced Showcases/Task Manager"},{"name":"iconClass","value":"bx bx-calendar-check","type":"label"}]}]},{"id":"_help_J5Ex1ZrMbyJ6","title":"Custom Request Handler","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Request Handler"},{"name":"iconClass","value":"bx bx-globe","type":"label"}]},{"id":"_help_d3fAXQ2diepH","title":"Custom Resource Providers","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Custom Resource Providers"},{"name":"iconClass","value":"bx bxs-file-plus","type":"label"}]},{"id":"_help_pgxEVkzLl1OP","title":"ETAPI (REST API)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/ETAPI (REST API)"},{"name":"iconClass","value":"bx bx-extension","type":"label"}],"children":[{"id":"_help_9qPsTWBorUhQ","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/rest-api/etapi/"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_47ZrP6FNuoG8","title":"Default Note Title","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Default Note Title"},{"name":"iconClass","value":"bx bx-edit-alt","type":"label"}]},{"id":"_help_wX4HbRucYSDD","title":"Database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database"},{"name":"iconClass","value":"bx bx-data","type":"label"}],"children":[{"id":"_help_oyIAJ9PvvwHX","title":"Manually altering the database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database"},{"name":"iconClass","value":"bx bxs-edit","type":"label"}],"children":[{"id":"_help_YKWqdJhzi2VY","title":"SQL Console","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Manually altering the database/SQL Console"},{"name":"iconClass","value":"bx bx-data","type":"label"}]}]},{"id":"_help_6tZeKvSHEUiB","title":"Demo Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Database/Demo Notes"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_Gzjqa934BdH4","title":"Configuration (config.ini or environment variables)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or e"},{"name":"iconClass","value":"bx bx-cog","type":"label"}],"children":[{"id":"_help_c5xB8m4g2IY6","title":"Trilium instance","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Trilium instance"},{"name":"iconClass","value":"bx bx-windows","type":"label"}]},{"id":"_help_LWtBjFej3wX3","title":"Cross-Origin Resource Sharing (CORS)","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Configuration (config.ini or environment variables)/Cross-Origin Resource Sharing "},{"name":"iconClass","value":"bx bx-lock","type":"label"}]}]},{"id":"_help_ivYnonVFBxbQ","title":"Bulk Actions","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Bulk Actions"},{"name":"iconClass","value":"bx bx-list-plus","type":"label"}]},{"id":"_help_4FahAwuGTAwC","title":"Note source","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note source"},{"name":"iconClass","value":"bx bx-code","type":"label"}]},{"id":"_help_1YeN2MzFUluU","title":"Technologies used","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used"},{"name":"iconClass","value":"bx bx-pyramid","type":"label"}],"children":[{"id":"_help_MI26XDLSAlCD","title":"CKEditor","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/CKEditor"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_N4IDkixaDG9C","title":"MindElixir","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/MindElixir"},{"name":"iconClass","value":"bx bx-sitemap","type":"label"}]},{"id":"_help_H0mM1lTxF9JI","title":"Excalidraw","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Excalidraw"},{"name":"iconClass","value":"bx bx-pen","type":"label"}]},{"id":"_help_MQHyy2dIFgxS","title":"Leaflet","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Technologies used/Leaflet"},{"name":"iconClass","value":"bx bx-map-alt","type":"label"}]}]},{"id":"_help_m1lbrzyKDaRB","title":"Note ID","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Note ID"},{"name":"iconClass","value":"bx bx-hash","type":"label"}]},{"id":"_help_0vTSyvhPTAOz","title":"Internal API","type":"book","attributes":[{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_z8O2VG4ZZJD7","title":"API Reference","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/rest-api/internal/"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_2mUhVmZK8RF3","title":"Hidden Notes","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Hidden Notes"},{"name":"iconClass","value":"bx bx-hide","type":"label"}]},{"id":"_help_uYF7pmepw27K","title":"Metrics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Metrics"},{"name":"iconClass","value":"bx bxs-data","type":"label"}],"children":[{"id":"_help_bOP3TB56fL1V","title":"grafana-dashboard.json","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_64ZTlUPgEPtW","title":"Safe mode","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Safe mode"},{"name":"iconClass","value":"bx bxs-virus-block","type":"label"}]},{"id":"_help_HAIOFBoYIIdO","title":"Nightly release","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Nightly release"},{"name":"iconClass","value":"bx bx-moon","type":"label"}]},{"id":"_help_ZmT9ln8XJX2o","title":"Read-only database","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Advanced Usage/Read-only database"},{"name":"iconClass","value":"bx bx-book-reader","type":"label"}]}]},{"id":"_help_GBBMSlVSOIGP","title":"AI","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/AI"},{"name":"iconClass","value":"bx bx-bot","type":"label"}]},{"id":"_help_CdNpE2pqjmI6","title":"Scripting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting"},{"name":"iconClass","value":"bx bxs-file-js","type":"label"}],"children":[{"id":"_help_yIhgI5H7A2Sm","title":"Frontend Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics"},{"name":"iconClass","value":"bx bx-window","type":"label"}],"children":[{"id":"_help_MgibgPcfeuGz","title":"Custom Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets"},{"name":"iconClass","value":"bx bxs-widget","type":"label"}],"children":[{"id":"_help_SynTBQiBsdYJ","title":"Widget Basics","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Widget Basics"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GhurYZjh8e1V","title":"Note context aware widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Note context aware widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_M8IppdwVHSjG","title":"Right pane widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Right pane widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_YNxAqkI5Kg1M","title":"Word count widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Word count widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_VqGQnnPGnqAU","title":"CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/CSS"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_gMkgcLJ6jBkg","title":"Troubleshooting","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Custom Widgets/Troubleshooting"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_es8OU2GuguFU","title":"Examples","type":"book","attributes":[{"name":"iconClass","value":"bx bx-code-alt","type":"label"}],"children":[{"id":"_help_TjLYAo3JMO8X","title":"\"New Task\" launcher button","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/New Task launcher button"},{"name":"iconClass","value":"bx bx-task","type":"label"}]},{"id":"_help_7kZPMD0uFwkH","title":"Downloading responses from Google Forms","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/Downloading responses from Goo"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_DL92EjAaXT26","title":"Using promoted attributes to configure scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Examples/Using promoted attributes to c"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_4Gn3psZKsfSm","title":"Launch Bar Widgets","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets"},{"name":"iconClass","value":"bx bx-dock-left","type":"label"}],"children":[{"id":"_help_IPArqVfDQ4We","title":"Note Title Widget","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Note Title Widget"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_gcI7RPbaNSh3","title":"Analog Watch","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Launch Bar Widgets/Analog Watch"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]},{"id":"_help_KLsqhjaqh1QW","title":"Preact","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact"},{"name":"iconClass","value":"bx bxl-react","type":"label"}],"children":[{"id":"_help_Bqde6BvPo05g","title":"Component libraries","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Component libraries"},{"name":"iconClass","value":"bx bxs-component","type":"label"}]},{"id":"_help_ykYtbM9k3a7B","title":"Hooks","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Hooks"},{"name":"iconClass","value":"bx bx-question-mark","type":"label"}]},{"id":"_help_Sg9GrCtyftZf","title":"CSS","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/CSS"},{"name":"iconClass","value":"bx bxs-file-css","type":"label"}]},{"id":"_help_RSssb9S3xgSr","title":"Built-in components","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Frontend Basics/Preact/Built-in components"},{"name":"iconClass","value":"bx bxs-component","type":"label"}],"children":[{"id":"_help_i9B4IW7b6V6z","title":"Widget showcase","type":"doc","attributes":[{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]}]},{"id":"_help_SPirpZypehBG","title":"Backend scripts","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts"},{"name":"iconClass","value":"bx bx-server","type":"label"}],"children":[{"id":"_help_fZ2IGYFXjkEy","title":"Server-side imports","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts/Server-side imports"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_GPERMystNGTB","title":"Events","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Backend scripts/Events"},{"name":"iconClass","value":"bx bx-rss","type":"label"}]}]},{"id":"_help_wqXwKJl6VpNk","title":"Common concepts","type":"book","attributes":[{"name":"iconClass","value":"bx bxl-nodejs","type":"label"}],"children":[{"id":"_help_hA834UaHhSNn","title":"Script bundles","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Common concepts/Script bundles"},{"name":"iconClass","value":"bx bx-package","type":"label"}]}]},{"id":"_help_GLks18SNjxmC","title":"Script API","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API"},{"name":"iconClass","value":"bx bx-code-curly","type":"label"}],"children":[{"id":"_help_Q2z6av6JZVWm","title":"Frontend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/frontend"},{"name":"iconClass","value":"bx bx-folder","type":"label"}],"enforceAttributes":true,"children":[{"id":"_help_habiZ3HU8Kw8","title":"FNote","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/frontend/interfaces/FNote.html"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true}]},{"id":"_help_MEtfsqa5VwNi","title":"Backend API","type":"webView","attributes":[{"type":"label","name":"webViewSrc","value":"https://docs.triliumnotes.org/script-api/backend"},{"name":"iconClass","value":"bx bx-file","type":"label"}],"enforceAttributes":true},{"id":"_help_ApVHZ8JY5ofC","title":"Day.js","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Script API/Day.js"},{"name":"iconClass","value":"bx bx-calendar","type":"label"}]}]},{"id":"_help_vElnKeDNPSVl","title":"Logging","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Logging"},{"name":"iconClass","value":"bx bx-terminal","type":"label"}]},{"id":"_help_cNpC0ITcfX0N","title":"Breaking changes","type":"book","attributes":[{"name":"iconClass","value":"bx bx-up-arrow-alt","type":"label"}],"children":[{"id":"_help_fqAK6opjUagR","title":"v0.103.0: Removal of axios","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.103.0 Removal of axios"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_pAJ0jWz16xFm","title":"v0.103.0: `cheerio` is now deprecated","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.103.0 `cheerio` is now depr"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_72dxvnbnkDFY","title":"v0.102.0: Upgrade to jQuery 4.0.0","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Scripting/Breaking changes/v0.102.0 Upgrade to jQuery.0.0"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}]},{"id":"_help_Fm0j45KqyHpU","title":"Miscellaneous","type":"book","attributes":[{"name":"iconClass","value":"bx bx-info-circle","type":"label"}],"children":[{"id":"_help_WFbFXrgnDyyU","title":"Privacy Policy","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/Privacy Policy"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_NcsmUYZRWEW4","title":"Patterns of personal knowledge","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/Patterns of personal knowledge"},{"name":"iconClass","value":"bx bx-file","type":"label"}]},{"id":"_help_d1Ap6Pg6IjaJ","title":"License","type":"doc","attributes":[{"type":"label","name":"docName","value":"User Guide/User Guide/Miscellaneous/License"},{"name":"iconClass","value":"bx bx-file","type":"label"}]}]}] \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html index 3083d72a84..721b20ed26 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html @@ -165,10 +165,16 @@ class="admonition note"> class="reference-link" href="#root/_help_KC1HB96bqqHX">Templates.
  • For example, to change the font of the document from the one defined by - the theme or the user to a serif one:

    body {
    -	--main-font-family: serif !important;
    -    --detail-font-family: var(--main-font-family) !important;
    +    the theme or the user to a serif one:

    body {
    +	--print-font-family: serif;
    +    --print-font-size: 11pt;
     }
    +

    To remark:

    • Multiple CSS notes can be add by using multiple ~printCss relations.
    • diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view.html index 0f3b39ee11..605062dcaa 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/UI Elements/Note types with split view.html @@ -1,8 +1,8 @@ -

      Split view is a feature of Mermaid Diagrams and  +

      Split view is a feature of Mermaid Diagrams and  Markdown notes which displays both the source code on one side + class="reference-link" href="#root/_help_6RM1Q7ppFVoj">Markdown notes which displays both the source code on one side and the preview of the content on the other.

      -

      Mermaid Diagrams also +

      Mermaid Diagrams also allow changing between a horizontal or a vertical split, to accommodate for the various sizes of diagrams.

      Display modes and interaction

      @@ -20,12 +20,12 @@
    • Preview which displays only the rendering of the diagram or text in full screen, especially useful for read-only notes.
    -

    These buttons can be found near the Note buttons section - on the New Layout, - or in the Floating buttons on +

    These buttons can be found near the Note buttons section + on the New Layout, + or in the Floating buttons on the old layout.

    The display node is stored at note level.

    Relation to read-only notes

    -

    If a note is marked as read-only, - the source view will not be editable. While in preview mode, marking a - note as read-only has no effect since the preview itself is not editable.

    \ No newline at end of file +

    If a note is marked as read-only, the + source view will not be editable. While in preview mode, marking a note + as read-only has no effect since the preview itself is not editable.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html index fbd042717a..447e08f942 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Data directory.html @@ -70,6 +70,19 @@ this:

    TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium

    You can then save the above command as a shell script on your path for convenience.

    +

    Electron user data directory (desktop only)

    +

    When running the desktop application, Electron stores internal data (caches, + spell-check dictionaries, session storage, etc.) separately from the Trilium + data directory. By default this goes to the system's application data folder + (e.g. %APPDATA% on Windows), which may be + undesirable in corporate environments with roaming profiles or when running + in portable mode.

    +

    To keep Electron data out of the system's roaming profile, set the + TRILIUM_ELECTRON_DATA_DIRenvironment variable to an explicit path. + The trilium-portable script does this automatically, + pointing it to trilium-electron-data/ next + to the application.

    Fine-grained directory/path location

    Apart from the data directory, some of the subdirectories of it can be moved elsewhere by changing an environment variable:

    @@ -129,5 +142,13 @@ Path to Configuration (config.ini or environment variables) file. + + TRILIUM_ELECTRON_DATA_DIR + + System appData + Directory for Electron internal data (caches, spell-check dictionaries, + etc.). Set this in portable mode to avoid writing to the system profile + (desktop only). + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html index 40d7ddd89c..e1ea2fc9b7 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Desktop Installation.html @@ -23,7 +23,9 @@
  • trilium-portable: Launches Trilium in portable mode, where the data directory is created within the application's directory, making it easy to move the - entire setup.
  • + entire setup. Electron's internal data (caches, dictionaries, etc.) is + also stored within the data directory, so no files are written to the system's + roaming profile.
  • trilium-safe-mode: Boots Trilium in "safe mode," disabling any startup scripts that might cause the application to crash.
  • diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html index 2607200081..d468c589c9 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types.html @@ -9,8 +9,7 @@ note where to place the new one and select:

    • Insert note after, to put the new note underneath the one selected.
    • -
    • Insert child note, to insert the note as a child of the selected +
    • Insert child note, to insert the note as a child of the selected note.

    @@ -21,8 +20,7 @@

  • When adding a link in a Text note, type the desired title of the new note and press Enter. Afterwards the type of the note will be asked.
  • -
  • Similarly, when creating a new tab, type the desired title and press Enter.
  • +
  • Similarly, when creating a new tab, type the desired title and press Enter.
  • Changing the type of a note

    It is possible to change the type of a note after it has been created @@ -32,96 +30,94 @@ edit the source of a note.

    Supported note types

    The following note types are supported by Trilium:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Note TypeDescription
    Text - The default note type, which allows for rich text formatting, images, - admonitions and right-to-left support.
    Code - Uses a mono-space font and can be used to store larger chunks of code - or plain text than a text note, and has better syntax highlighting.
    Saved Search - Stores the information about a search (the search text, criteria, etc.) - for later use. Can be used for quick filtering of a large amount of notes, - for example. The search can easily be triggered.
    Relation Map - Allows easy creation of notes and relations between them. Can be used - for mainly relational data such as a family tree.
    Note Map - Displays the relationships between the notes, whether via relations or - their hierarchical structure.
    Render Note - Used in Scripting, - it displays the HTML content of another note. This allows displaying any - kind of content, provided there is a script behind it to generate it.
    Collections - Displays the children of the note either as a grid, a list, or for a more - specialized case: a calendar.   -
    -
    Generally useful for easy reading of short notes.
    Mermaid Diagrams - Displays diagrams such as bar charts, flow charts, state diagrams, etc. - Requires a bit of technical knowledge since the diagrams are written in - a specialized format.
    Canvas - Allows easy drawing of sketches, diagrams, handwritten content. Uses the - same technology behind excalidraw.com.
    Web View - Displays the content of an external web page, similar to a browser.
    Mind Map - Easy for brainstorming ideas, by placing them in a hierarchical layout.
    Geo Map - Displays the children of the note as a geographical map, one use-case - would be to plan vacations. It even has basic support for tracks. Notes - can also be created from it.
    File - Represents an uploaded file such as PDFs, images, video or audio files.
    -
    \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Note TypeDescription
    Text + The default note type, which allows for rich text formatting, images, + admonitions and right-to-left support.
    Code + Uses a mono-space font and can be used to store larger chunks of code + or plain text than a text note, and has better syntax highlighting.
    Saved Search + Stores the information about a search (the search text, criteria, etc.) + for later use. Can be used for quick filtering of a large amount of notes, + for example. The search can easily be triggered.
    Relation Map + Allows easy creation of notes and relations between them. Can be used + for mainly relational data such as a family tree.
    Note Map + Displays the relationships between the notes, whether via relations or + their hierarchical structure.
    Render Note + Used in Scripting, + it displays the HTML content of another note. This allows displaying any + kind of content, provided there is a script behind it to generate it.
    Collections + Displays the children of the note either as a grid, a list, or for a more + specialized case: a calendar.   +
    +
    Generally useful for easy reading of short notes.
    Mermaid Diagrams + Displays diagrams such as bar charts, flow charts, state diagrams, etc. + Requires a bit of technical knowledge since the diagrams are written in + a specialized format.
    Canvas + Allows easy drawing of sketches, diagrams, handwritten content. Uses the + same technology behind excalidraw.com.
    Web View + Displays the content of an external web page, similar to a browser.
    Mind Map + Easy for brainstorming ideas, by placing them in a hierarchical layout.
    Geo Map + Displays the children of the note as a geographical map, one use-case + would be to plan vacations. It even has basic support for tracks. Notes + can also be created from it.
    File + Represents an uploaded file such as PDFs, images, video or audio files.
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html index 152140d5ed..f64ba7eade 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/File.html @@ -5,8 +5,7 @@ create a File note type directly:

    • Drag a file into the Note Tree.
    • -
    • Right click a note and select Import into note and point it to +
    • Right click a note and select Import into note and point it to one of the supported files.

    Supported file types

    @@ -83,30 +82,28 @@ href="#root/_help_BlN9DFI679QC">Ribbon.
    • Download, which will download the file for local use.
    • -
    • Open, will will open the file with the system-default application.
    • -
    • Upload new revision to replace the file with a new one.
    • +
    • Open, will will open the file with the system-default application.
    • +
    • Upload new revision to replace the file with a new one.
    - -
  • It is not possible to change the note type of a File note.
  • -
  • Convert into an attachment from the note menu.
  • + +
  • It is not possible to change the note type of a File note.
  • +
  • Convert into an attachment from the note menu.
  • Relation with other notes

    • Files are also displayed in the Note List based on their type:

      -

      - -

      + +
    • +
    • +

      Non-image files can be embedded into text notes as read-only widgets via + the Include Note functionality.

      +
    • +
    • +

      Image files can be embedded into text notes like normal images via  + Image references.

    • -
    • Non-image files can be embedded into text notes as read-only widgets via - the Include Note functionality.
    • -
    • Image files can be embedded into text notes like normal images via  - Image references.
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Markdown.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Markdown.html index 74cf113776..9d06e36996 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Markdown.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Markdown.html @@ -1,13 +1,12 @@ -

    Trilium has always supported Markdown through its import feature, +

    Trilium has always supported Markdown through its import feature, however the file was either transformed to a Text note - (converted to Trilium's internal HTML format) or saved as a Code note + href="#root/_help_iPIMuisry3hd">Text note (converted to Trilium's internal + HTML format) or saved as a Code note with only syntax highlight.

    This note type is a split view, meaning that both the source code and a preview of the document are displayed side-by-side. See Note types with split view for - more information.

    + href="#root/_help_SL5f1Auq7sVN">Note types with split view for more + information.

    Rationale

    The goal of this note type is to fill a gap: rendering Markdown but not altering its structure or its whitespace which would inevitably change @@ -37,77 +36,65 @@

  • Code blocks with syntax highlight (e.g. ```js) and automatic syntax highlight
  • -
  • Block quotes & admonitions +
  • Block quotes & admonitions
  • -
  • Math Equations +
  • Math Equations
  • -
  • Mermaid Diagrams using +
  • Mermaid Diagrams using ```mermaid
  • -

    Include Note (no +

    Include Note (no builtin Markdown syntax, but HTML syntax works just fine):

    <section class="include-note" data-note-id="vJDjQm0VK8Na" data-box-size="expandable">
    -	&nbsp;
    +    &nbsp;
     </section>n
  • -

    Internal (reference) links via +

    Internal (reference) links via its HTML syntax, or through a Wikilinks-like format (only  Note ID):

    [[Hg8TS5ZOxti6]]
    + class="reference-link" href="#root/_help_m1lbrzyKDaRB">Note ID):

    [[Hg8TS5ZOxti6]]
  • Creating Markdown notes

    There are two ways to create a Markdown note:

      -
    1. Create a new note (e.g. in the Note Tree) +
    2. Create a new note (e.g. in the Note Tree) and select the type Markdown, just like all the other note types.
    3. Create a note of type Code and - select as the language either Markdown or GitHub-Flavored Markdown. + >Create a note of type Code and + select as the language either Markdown or GitHub-Flavored Markdown. This maintains compatibility with your existing notes prior to the introduction of this feature.

    Import/export

      -
    • -

      By default, when importing a single Markdown file it automatically gets - converted to a Text note. - To avoid that and have it imported as a Markdown note instead:

      +
    • By default, when importing a single Markdown file it automatically gets + converted to a Text note. + To avoid that and have it imported as a Markdown note instead:
        -
      • -

        Right click the Note Tree and - select Import into note.

        -
      • -
      • -

        Select the file normally.

        -
      • -
      • -

        Uncheck Import HTML, Markdown and TXT as text notes if it's unclear from the metadata.

        -
      • +
      • Right click the Note Tree and + select Import into note.
      • +
      • Select the file normally.
      • +
      • Uncheck Import HTML, Markdown and TXT as text notes if it's unclear from the metadata.
    • -
    • -

      When exporting Markdown files, the extension is preserved and the content - remains the same as in the source view.

      -
    • -
    • -

      Once exported as a Trilium ZIP, the ZIP will preserve the Markdown type - without converting to text notes thanks to the meta-information in it.

      -
    • +
    • When exporting Markdown files, the extension is preserved and the content + remains the same as in the source view.
    • +
    • Once exported as a Trilium ZIP, the ZIP will preserve the Markdown type + without converting to text notes thanks to the meta-information in it.

    Conversion between text notes and Markdown notes

    Currently there is no built-in functionality to convert a Text note - into a Markdown note or vice-versa. We do have plans to address this in - the future.

    + href="#root/_help_iPIMuisry3hd">Text note into a Markdown note or vice-versa. + We do have plans to address this in the future.

    This can be achieved manually, for a single note:

    1. Export the file as Markdown, with single format.
    2. @@ -135,6 +122,6 @@

      This feature of synchronizing the scroll is based on blocks but it's provided on a best-effort basis since our underlying Markdown library doesn't support this feature natively, so we had to implement our own algorithm. Feel free - to report issues, - but always provide a sample Markdown file to be able to reproduce it.

      + to report issues, but always provide a + sample Markdown file to be able to reproduce it.

      \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html index d6ff44cd93..a17a7ea0a8 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Mermaid Diagrams.html @@ -12,8 +12,8 @@ the diagram.

      This note type is a split view, meaning that both the source code and a preview of the document are displayed side-by-side. See Note types with split view for - more information.

      + href="#root/_help_SL5f1Auq7sVN">Note types with split view for more + information.

      Sample diagrams

      Starting with v0.103.0, Mermaid diagrams no longer start with a sample flowchart, but instead a pane at the bottom will show all the supported @@ -52,34 +52,30 @@

    3. The preview can be moved around by holding the left mouse button and dragging.
    4. -
    5. Zooming can also be done by using the scroll wheel.
    6. -
    7. The zoom and position on the preview will remain fixed as the diagram - changes, to be able to work more easily with large diagrams.
    8. - +
    9. Zooming can also be done by using the scroll wheel.
    10. +
    11. The zoom and position on the preview will remain fixed as the diagram + changes, to be able to work more easily with large diagrams.
    12. +
    13. The size of the source/preview panes can be adjusted by hovering over the border between them and dragging it with the mouse.
    14. In the Floating buttons area:
      • The source/preview can be laid out left-right or bottom-top via the Move editing pane to the left / bottom option.
      • -
      • Press Lock editing to automatically mark the note as read-only. +
      • Press Lock editing to automatically mark the note as read-only. In this mode, the code pane is hidden and the diagram is displayed full-size. Similarly, press Unlock editing to mark a read-only note as editable.
      • -
      • Press the Copy image reference to the clipboard to be able to insert - the image representation of the diagram into a text note. See Image references for more information.
      • -
      • Press the Export diagram as SVG to download a scalable/vector rendering - of the diagram. Can be used to present the diagram without degrading when - zooming.
      • +
      • Press the Copy image reference to the clipboard to be able to insert + the image representation of the diagram into a text note. See Image references for more information.
      • +
      • Press the Export diagram as SVG to download a scalable/vector rendering + of the diagram. Can be used to present the diagram without degrading when + zooming.
      • Press the Export diagram as PNG to download a normal image (at 1x scale, raster) of the diagram. Can be used to send the diagram in more traditional channels such as e-mail.
      • -
      -
    15. + +

      Errors in the diagram

      If there is an error in the source code, the error will be displayed in diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html index 4a33c30bfe..efff5c09b9 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Render Note.html @@ -13,13 +13,11 @@

      1. HTML language for the legacy/vanilla method, with what needs to be displayed (for example <p>Hello world.</p>).
      2. -
      3. JSX for the Preact-based approach (see below).
      4. -
      +
    16. JSX for the Preact-based approach (see below).
    17. +
  • Create a Render Note.
  • -
  • Assign the renderNote relation to +
  • Assign the renderNote relation to point at the previously created code note.
  • Legacy scripting using jQuery

    @@ -48,9 +46,10 @@ $dateEl.text(new Date());
    need to provide a HTML anymore.

    Here are the steps to creating a simple render note:

      -
    1. Create a note of type Render Note.
    2. -
    3. +
    4. +

      Create a note of type Render Note.

      +
    5. +
    6. Create a child Code note with JSX as the language.
      As an example, use the following content:

      export default function() {
      @@ -60,17 +59,20 @@ $dateEl.text(new Date());
      </> ); } -
    7. -
    8. In the parent render note, define a ~renderNote relation - pointing to the newly created child.
    9. -
    10. Refresh the render note and it should display a “Hello world” message.
    11. + +
    12. +

      In the parent render note, define a ~renderNote relation + pointing to the newly created child.

      +
    13. +
    14. +

      Refresh the render note and it should display a “Hello world” message.

      +

    Refreshing the note

    It's possible to refresh the note via:

    Examples

    diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html index 06f944a848..b9ab252d4c 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Spreadsheets.html @@ -64,9 +64,8 @@ yet:

    • Trilium-specific formulas (e.g. to obtain the title of a note).
    • -
    • User-defined formulas
    • -
    • Cross-workbook calculation
    • +
    • User-defined formulas
    • +
    • Cross-workbook calculation

    If you would like us to work on these features, consider supporting us.

    Known limitations

    @@ -81,8 +80,7 @@
  • There is currently no export functionality, as stated previously.
  • -
  • There is no dedicated mobile support. Mobile support is currently experimental +
  • There is no dedicated mobile support. Mobile support is currently experimental in Univer and when it becomes stable, we could potentially integrate it into Trilium as well.
  • \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html index 26a0791ace..42dbe0fa44 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text.html @@ -20,171 +20,168 @@

    Fore more information see Formatting toolbar.

    Features and formatting

    Here's a list of various features supported by text notes:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Dedicated articleFeature
    General formatting - -
      -
    • Headings (section titles, paragraph)
    • -
    • Font size
    • -
    • Bold, italic, underline, strike-through
    • -
    • Superscript, subscript
    • -
    • Font color & background color
    • -
    • Remove formatting
    • -
    -
    Lists - -
      -
    • Bulleted lists
    • -
    • Numbered lists
    • -
    • To-do lists
    • -
    -
    Block quotes & admonitions - -
      -
    • Block quotes
    • -
    • Admonitions
    • -
    -
    Tables - -
      -
    • Basic tables
    • -
    • Merging cells
    • -
    • Styling tables and cells.
    • -
    • Table captions
    • -
    -
    Developer-specific formatting - -
      -
    • Inline code
    • -
    • Code blocks
    • -
    • Keyboard shortcuts
    • -
    -
    Footnotes - -
      -
    • Footnotes
    • -
    -
    Images - -
      -
    • Images
    • -
    -
    Links - -
      -
    • External links
    • -
    • Internal Trilium links
    • -
    -
    Include Note - -
      -
    • Include note
    • -
    -
    Insert buttons - -
      -
    • Symbols
    • -
    • Math Equations -
    • -
    • Mermaid diagrams
    • -
    • Horizontal ruler
    • -
    • Page break
    • -
    -
    Other features - - -
    Premium features - - -
    -
    -

    Read-Only vs. Editing Mode

    -

    Text notes are usually opened in edit mode. However, they may open in - read-only mode if the note is too big or the note is explicitly marked - as read-only. For more information, see Read-Only Notes.

    -

    Keyboard shortcuts

    -

    There are numerous keyboard shortcuts to format the text without having - to use the mouse. For a reference of all the key combinations, see  - Keyboard Shortcuts. In addition, see Markdown-like formatting as an alternative - to the keyboard shortcuts.

    -

    Technical details

    -

    For the text editing functionality, Trilium uses a commercial product - (with an open-source base) called CKEditor. - This brings the benefit of having a powerful WYSIWYG (What You See Is What - You Get) editor.

    \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Dedicated articleFeature
    General formatting + +
      +
    • Headings (section titles, paragraph)
    • +
    • Font size
    • +
    • Bold, italic, underline, strike-through
    • +
    • Superscript, subscript
    • +
    • Font color & background color
    • +
    • Remove formatting
    • +
    +
    Lists + +
      +
    • Bulleted lists
    • +
    • Numbered lists
    • +
    • To-do lists
    • +
    +
    Block quotes & admonitions + +
      +
    • Block quotes
    • +
    • Admonitions
    • +
    +
    Tables + +
      +
    • Basic tables
    • +
    • Merging cells
    • +
    • Styling tables and cells.
    • +
    • Table captions
    • +
    +
    Developer-specific formatting + +
      +
    • Inline code
    • +
    • Code blocks
    • +
    • Keyboard shortcuts
    • +
    +
    Footnotes + +
      +
    • Footnotes
    • +
    +
    Images + +
      +
    • Images
    • +
    +
    Links + +
      +
    • External links
    • +
    • Internal Trilium links
    • +
    +
    Include Note + +
      +
    • Include note
    • +
    +
    Insert buttons + +
      +
    • Symbols
    • +
    • Math Equations +
    • +
    • Mermaid diagrams
    • +
    • Horizontal ruler
    • +
    • Page break
    • +
    +
    Other features + + +
    Premium features + + +
    +

    Read-Only vs. Editing Mode

    +

    Text notes are usually opened in edit mode. However, they may open in + read-only mode if the note is too big or the note is explicitly marked + as read-only. For more information, see Read-Only Notes.

    +

    Keyboard shortcuts

    +

    There are numerous keyboard shortcuts to format the text without having + to use the mouse. For a reference of all the key combinations, see  + Keyboard Shortcuts. In addition, see Markdown-like formatting as an alternative + to the keyboard shortcuts.

    +

    Technical details

    +

    For the text editing functionality, Trilium uses a commercial product + (with an open-source base) called CKEditor. + This brings the benefit of having a powerful WYSIWYG (What You See Is What + You Get) editor.

    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Bookmarks_plus.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Anchors_plus.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Bookmarks_plus.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/1_Anchors_plus.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Anchors.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Anchors.html new file mode 100644 index 0000000000..8724f8a93d --- /dev/null +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Anchors.html @@ -0,0 +1,70 @@ + +

    Anchors allows creating links to a certain + part of a note, such as referencing a particular heading or section within + a note.

    +

    This feature was introduced in TriliumNext v0.94.0 and augmented in v0.130.0 + to support linking across notes.

    +

    Interaction

    +
      +
    • To create a anchor: +
        +
      • Place the cursor at the desired position where to place the anchor.
      • +
      • Look for the + button in the Formatting toolbar, + and then press the + button.
      • +
      • Alternatively, use Slash Commands and + look for anchor.
      • +
      +
    • +
    • To place a link to a anchor: +
        +
      • Place the cursor at the desired position of the link.
      • +
      • From the link pane, select the Anchors section + and select the desired anchor.
      • +
      +
    • +
    +

    Linking across notes

    +

    Trilium v0.103.0 introduces cross-note Anchors, which makes it possible + to create Internal (reference) links which + point to a specific anchor in that document.

    +

    Compatibility with documents from previous versions

    +

    For notes created prior to Trilium v0.103.0, you might notice that the + Anchors might not be identified. This limitation is intentional in order + not to have to re-process all the notes, looking for anchors.

    +

    To fix this, simply go that note and make any change (e.g. inserting a + space), this will trigger the recalculation of the links.

    +

    Linking to anchors through the Add link dialog

    +
      +
    1. Create an anchor in the target note using the same process as described + above.
    2. +
    3. In another note, press Ctrl+L to insert an internal + link. Select the target note containing Anchors.
    4. +
    5. If the target note contains Anchors, a section will appear underneath + the note selector with the list of Anchors.
    6. +
    7. Add the link normally.
    8. +
    +

    Clicking on a reference link pointing to a anchor will automatically scroll + to the desired section.

    +

    Linking to anchors through the bookmark toolbar

    +
      +
    1. Create an anchor in the target note using the same process as described + above.
    2. +
    3. Click on the anchor to reveal the anchor's floating toolbar.
    4. +
    5. Click on the Copy anchor reference link button.
    6. +
    7. Go to the note where to insert the link and press Ctrl+V.
    8. +
    + \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks_plus.png b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Anchors_plus.png similarity index 100% rename from apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks_plus.png rename to apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Anchors_plus.png diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html deleted file mode 100644 index bc7b346e33..0000000000 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Bookmarks.html +++ /dev/null @@ -1,31 +0,0 @@ -

    Bookmarks allows creating links to a certain - part of a note, such as referencing a particular heading.

    -

    Technically, bookmarks are HTML anchors.

    -

    This feature was introduced in TriliumNext 0.94.0.

    -

    Interaction

    -
      -
    • To create a bookmark: -
        -
      • Place the cursor at the desired position where to place the bookmark.
      • -
      • Look for the - button in the Formatting toolbar, - and then press the - button.
      • -
      -
    • -
    • To place a link to a bookmark: -
        -
      • Place the cursor at the desired position of the link.
      • -
      • From the link pane, select the Bookmarks section - and select the desired bookmark.
      • -
      -
    • -
    -

    Limitations

    -
      -
    • Currently it's not possible to create a link to a bookmark from a different - note. This functionality will be added after the internal links feature - is enhanced to support bookmarks.
    • -
    \ No newline at end of file diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html index e1bfe092f2..550f54e9f1 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Note Types/Text/Insert buttons.html @@ -4,7 +4,7 @@ reveal special inserable items and blocks such as symbols, Math expressions and separators.

    Bookmarks

    -

    See the dedicated Bookmarks section.

    +

    See the dedicated Anchors section.

    Emoji

    { } isAutoLink() { - return this.type === "relation" && ["internalLink", "imageLink", "relationMapLink", "includeNoteLink"].includes(this.name); + if (this.type === "relation") { + return ["internalLink", "imageLink", "relationMapLink", "includeNoteLink"].includes(this.name); + } + + if (this.type === "label") { + return this.name === "internalBookmark"; + } + + return false; } get note() { diff --git a/apps/server/src/services/attributes.ts b/apps/server/src/services/attributes.ts index 2e1a207447..c9642d4777 100644 --- a/apps/server/src/services/attributes.ts +++ b/apps/server/src/services/attributes.ts @@ -77,7 +77,7 @@ function getAttributeNames(type: string, nameLike: string) { } } - names = names.filter((name) => !["internalLink", "imageLink", "includeNoteLink", "relationMapLink"].includes(name)); + names = names.filter((name) => !["internalLink", "imageLink", "includeNoteLink", "relationMapLink", "internalBookmark"].includes(name)); names.sort((a, b) => { const aPrefix = a.toLowerCase().startsWith(nameLike); diff --git a/apps/server/src/services/html_sanitizer.spec.ts b/apps/server/src/services/html_sanitizer.spec.ts index dfbba8fd71..6af366a329 100644 --- a/apps/server/src/services/html_sanitizer.spec.ts +++ b/apps/server/src/services/html_sanitizer.spec.ts @@ -50,4 +50,26 @@ describe("sanitize", () => {
    `; expect(html_sanitizer.sanitize(dirty)).toBe(clean); }); + + describe("bookmark anchors", () => { + it("preserves id attribute on empty tags (CKEditor bookmarks)", () => { + const dirty = ``; + expect(html_sanitizer.sanitize(dirty)).toBe(dirty); + }); + + it("preserves id attribute on tags with bookmark class", () => { + const dirty = ``; + expect(html_sanitizer.sanitize(dirty)).toBe(dirty); + }); + + it("strips id attribute from non-anchor tags to prevent DOM clobbering", () => { + const dirty = `
    content
    `; + expect(html_sanitizer.sanitize(dirty)).toBe(`
    content
    `); + }); + + it("strips id attribute from tags to prevent DOM clobbering", () => { + const dirty = ``; + expect(html_sanitizer.sanitize(dirty)).toBe(``); + }); + }); }); diff --git a/apps/server/src/services/html_sanitizer.ts b/apps/server/src/services/html_sanitizer.ts index f304dcf150..76262c2a32 100644 --- a/apps/server/src/services/html_sanitizer.ts +++ b/apps/server/src/services/html_sanitizer.ts @@ -42,6 +42,7 @@ function sanitize(dirtyHtml: string) { allowedTags: allowedTags as string[], allowedAttributes: { "*": ["class", "style", "title", "src", "href", "hash", "disabled", "align", "alt", "center", "data-*"], + a: ["id"], // CKEditor bookmark anchors use input: ["type", "checked"], img: ["width", "height"], code: [ "spellcheck" ] diff --git a/apps/server/src/services/notes.spec.ts b/apps/server/src/services/notes.spec.ts new file mode 100644 index 0000000000..38d99fc7d7 --- /dev/null +++ b/apps/server/src/services/notes.spec.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from "vitest"; +import { findBookmarks } from "./notes.js"; + +describe("findBookmarks", () => { + it("extracts bookmark IDs from empty anchor tags", () => { + const content = `

    Hello

    World

    `; + expect(findBookmarks(content)).toEqual(["chapter-1"]); + }); + + it("extracts multiple bookmarks", () => { + const content = `

    Text

    `; + expect(findBookmarks(content)).toEqual(["intro", "conclusion"]); + }); + + it("returns empty array when no bookmarks exist", () => { + const content = `

    No bookmarks here

    `; + expect(findBookmarks(content)).toEqual([]); + }); + + it("ignores anchor tags with href (regular links, not bookmarks)", () => { + const content = `link`; + expect(findBookmarks(content)).toEqual([]); + }); + + it("handles bookmarks with various valid ID characters", () => { + const content = ``; + expect(findBookmarks(content)).toEqual(["my_bookmark-2.0"]); + }); + + it("does not produce duplicates", () => { + const content = ``; + expect(findBookmarks(content)).toEqual(["same"]); + }); + + it("matches self-closing bookmark anchors (CKEditor empty elements)", () => { + const content = `

    Text

    More

    `; + // CKEditor may also output without closing tag + const contentNoClose = `

    Text

    More

    `; + expect(findBookmarks(content)).toEqual(["my-bookmark"]); + expect(findBookmarks(contentNoClose)).toEqual(["my-bookmark"]); + }); +}); diff --git a/apps/server/src/services/notes.ts b/apps/server/src/services/notes.ts index 708cab285d..13a0955774 100644 --- a/apps/server/src/services/notes.ts +++ b/apps/server/src/services/notes.ts @@ -454,6 +454,54 @@ function findImageLinks(content: string, foundLinks: FoundLink[]) { return content.replace(/src="[^"]*\/api\/images\//g, 'src="api/images/'); } +/** + * Extracts bookmark IDs from CKEditor bookmark anchors (`
    ` without href). + * Bookmarks are stored as labels on the note so they can be looked up without parsing content. + */ +export function findBookmarks(content: string): string[] { + const re = /]*>(<\/a>)?/g; + const bookmarks: string[] = []; + let match; + + while ((match = re.exec(content))) { + // Skip anchors that also have an href (those are regular links, not bookmarks) + if (match[0].includes("href=")) { + continue; + } + + const id = match[1]; + if (!bookmarks.includes(id)) { + bookmarks.push(id); + } + } + + return bookmarks; +} + +function saveBookmarks(note: BNote, content: string) { + const foundBookmarks = findBookmarks(content); + const existingBookmarks = note.getOwnedLabels("internalBookmark"); + + for (const bookmarkId of foundBookmarks) { + const existing = existingBookmarks.find((l) => l.value === bookmarkId); + + if (!existing) { + new BAttribute({ + noteId: note.noteId, + type: "label", + name: "internalBookmark", + value: bookmarkId + }).save(); + } + } + + // Remove bookmarks that are no longer in the content + const unusedBookmarks = existingBookmarks.filter((l) => !foundBookmarks.includes(l.value)); + for (const unused of unusedBookmarks) { + unused.markAsDeleted(); + } +} + function findInternalLinks(content: string, foundLinks: FoundLink[]) { const re = /href="[^"]*#root[a-zA-Z0-9_\/]*\/([a-zA-Z0-9_]+)\/?"/g; let match; @@ -695,6 +743,7 @@ function saveLinks(note: BNote, content: string | Buffer) { content = findImageLinks(content, foundLinks); content = findInternalLinks(content, foundLinks); content = findIncludeNoteLinks(content, foundLinks); + saveBookmarks(note, content); ({ forceFrontendReload, content } = checkImageAttachments(note, content)); } else if (note.type === "relationMap" && typeof content === "string") { diff --git a/apps/web-clipper/package.json b/apps/web-clipper/package.json index 82e8ffd6e7..f0d8f93f84 100644 --- a/apps/web-clipper/package.json +++ b/apps/web-clipper/package.json @@ -16,7 +16,7 @@ "packageManager": "pnpm@10.33.0", "devDependencies": { "@wxt-dev/auto-icons": "1.1.1", - "wxt": "0.20.21" + "wxt": "0.20.22" }, "dependencies": { "cash-dom": "8.1.5" diff --git a/apps/website/package.json b/apps/website/package.json index e0f95b7596..8d6267f184 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -13,7 +13,7 @@ "preact": "10.29.1", "preact-iso": "2.11.1", "preact-render-to-string": "6.6.7", - "react-i18next": "17.0.2" + "react-i18next": "17.0.3" }, "devDependencies": { "@preact/preset-vite": "2.10.5", diff --git a/docs/Developer Guide/Developer Guide/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md index aae807a49d..9818ff97ba 100644 --- a/docs/Developer Guide/Developer Guide/Documentation.md +++ b/docs/Developer Guide/Developer Guide/Documentation.md @@ -1,5 +1,5 @@ # Documentation -There are multiple types of documentation for Trilium: +There are multiple types of documentation for Trilium: * The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1. * The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers. diff --git a/docs/README-ja.md b/docs/README-ja.md index 6804c08b7c..9f667bc589 100644 --- a/docs/README-ja.md +++ b/docs/README-ja.md @@ -63,7 +63,7 @@ Trilium Notes * ノートは任意の深さのツリーに配置できます。1つのノートをツリー内の複数の場所に配置できます([クローン](https://docs.triliumnotes.org/user-guide/concepts/notes/cloning)を参照) * 豊富な WYSIWYG ノートエディター 例: - 表、画像、[数式](https://docs.triliumnotes.org/user-guide/note-types/text) とマークダウン + 表、画像、[数式](https://docs.triliumnotes.org/user-guide/note-types/text) と markdown [自動フォーマット](https://docs.triliumnotes.org/user-guide/note-types/text/markdown-formatting) など * 構文ハイライト表示を含む diff --git a/docs/README-ug.md b/docs/README-ug.md index b20038be1e..9b081dba6c 100644 --- a/docs/README-ug.md +++ b/docs/README-ug.md @@ -285,23 +285,24 @@ pnpm run --filter desktop electron-forge:make --arch=x64 --platform=win32 ### تەتقىقاتچى ھۆججەتلىرى -Please view the [documentation -guide](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md) -for details. If you have more questions, feel free to reach out via the links -described in the "Discuss with us" section above. +تەپسىلاتلار ئۈچۈن [ھۆججەت +يېتەكچىسى](https://github.com/TriliumNext/Trilium/blob/main/docs/Developer%20Guide/Developer%20Guide/Environment%20Setup.md)گە +قاراڭ. ئەگەر تېخىمۇ كۆپ سوئاللىرىڭىز بولسا، ئۈستىدىكى "بىز بىلەن ئالاقىلىشىڭ" +بۆلىكىدە تەمىنلەنگەن ئۇلىنىشلار ئارقىلىق بىز بىلەن ئالاقىلىشىڭنى قارشى ئالىمىز. -## 👏 Shoutouts +## 👏 مىننەتدارلىق -* [zadam](https://github.com/zadam) for the original concept and implementation - of the application. -* [Sarah Hussein](https://github.com/Sarah-Hussein) for designing the - application icon. -* [nriver](https://github.com/nriver) for his work on internationalization. -* [Thomas Frei](https://github.com/thfrei) for his original work on the Canvas. -* [antoniotejada](https://github.com/nriver) for the original syntax highlight - widget. -* [Dosu](https://dosu.dev/) for providing us with the automated responses to - GitHub issues and discussions. +* ئەپنىڭ ئەسلى ئۇقۇم لاھىيەسى ۋە ئەمەلگە ئاشۇرۇلۇشىغا تۆھپە قوشقان + [zadam](https://github.com/zadam). +* ئەپ سىنبەلگىسىنى لاھىيەلىگەن [Sarah + Hussein](https://github.com/Sarah-Hussein). +* خەلقئارالاشتۇرۇش خىزمىتىگە تۆھپە قوشقان [nriver](https://github.com/nriver). +* Canvas جەھەتتىكى ئەسلى ئىجادىي خىزمەتلىرى ئۈچۈن [Thomas + Frei](https://github.com/thfrei). +* ئەسلى گرامماتىكا گەۋدىلەندۈرۈش كىچىك زاپچاسلارنى ئاپتورى + [antoniotejada](https://github.com/nriver). +* GitHub مەسىلىلىرى ۋە مۇنازىرىلىرىگە ئاپتوماتىك جاۋاب قايتۇرۇش بىلەن تەمىنلىگەن + [Dosu](https://dosu.dev/). * [Tabler Icons](https://tabler.io/icons) for the system tray icons. Trilium would not be possible without the technologies behind it: diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json index d1b8f5d265..caa6550464 100644 --- a/docs/User Guide/!!!meta.json +++ b/docs/User Guide/!!!meta.json @@ -3984,42 +3984,42 @@ "name": "internalLink", "value": "s1aBHPd79XYj", "isInheritable": false, - "position": 30 + "position": 10 }, { "type": "relation", "name": "internalLink", "value": "6RM1Q7ppFVoj", "isInheritable": false, - "position": 40 - }, - { - "type": "relation", - "name": "internalLink", - "value": "CoFPLs3dRlXc", - "isInheritable": false, - "position": 50 + "position": 20 }, { "type": "relation", "name": "internalLink", "value": "8YBEPzcpUgxw", "isInheritable": false, - "position": 60 + "position": 30 }, { "type": "relation", "name": "internalLink", "value": "IjZS7iK5EXtb", "isInheritable": false, - "position": 70 + "position": 40 }, { "type": "relation", "name": "internalLink", "value": "XpOYSgsLkTJy", "isInheritable": false, - "position": 80 + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "CoFPLs3dRlXc", + "isInheritable": false, + "position": 60 }, { "type": "label", @@ -7188,6 +7188,93 @@ ], "dirFileName": "Text", "children": [ + { + "isClone": false, + "noteId": "oSuaNgyyKnhu", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "iPIMuisry3hd", + "oSuaNgyyKnhu" + ], + "title": "Anchors", + "notePosition": 10, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "u3YFHC9tQlpm", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "QEAPj01N5f7w", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "nRhnJkTT8cPs", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "ZlN4nump6EbW", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "hrZ1D00cLbal", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-bookmark", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "shareAlias", + "value": "bookmarks", + "isInheritable": false, + "position": 30 + } + ], + "format": "markdown", + "dataFileName": "Anchors.md", + "attachments": [ + { + "attachmentId": "2cn9iY3Qgyjs", + "title": "plus.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "Anchors_plus.png" + }, + { + "attachmentId": "JaiAT3dHDIyy", + "title": "plus.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "1_Anchors_plus.png" + } + ] + }, { "isClone": false, "noteId": "NwBbFdNZ9h7O", @@ -7198,7 +7285,7 @@ "NwBbFdNZ9h7O" ], "title": "Block quotes & admonitions", - "notePosition": 10, + "notePosition": 20, "prefix": null, "isExpanded": false, "type": "text", @@ -7262,72 +7349,6 @@ } ] }, - { - "isClone": false, - "noteId": "oSuaNgyyKnhu", - "notePath": [ - "pOsGYCXsbNQG", - "KSZ04uQ2D1St", - "iPIMuisry3hd", - "oSuaNgyyKnhu" - ], - "title": "Bookmarks", - "notePosition": 20, - "prefix": null, - "isExpanded": false, - "type": "text", - "mime": "text/html", - "attributes": [ - { - "type": "relation", - "name": "internalLink", - "value": "QEAPj01N5f7w", - "isInheritable": false, - "position": 10 - }, - { - "type": "relation", - "name": "internalLink", - "value": "nRhnJkTT8cPs", - "isInheritable": false, - "position": 20 - }, - { - "type": "label", - "name": "iconClass", - "value": "bx bx-bookmark", - "isInheritable": false, - "position": 10 - }, - { - "type": "label", - "name": "shareAlias", - "value": "bookmarks", - "isInheritable": false, - "position": 30 - } - ], - "format": "markdown", - "dataFileName": "Bookmarks.md", - "attachments": [ - { - "attachmentId": "2cn9iY3Qgyjs", - "title": "plus.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "Bookmarks_plus.png" - }, - { - "attachmentId": "JaiAT3dHDIyy", - "title": "plus.png", - "role": "image", - "mime": "image/png", - "position": 10, - "dataFileName": "1_Bookmarks_plus.png" - } - ] - }, { "isClone": false, "noteId": "veGu4faJErEM", @@ -10147,17 +10168,24 @@ { "type": "relation", "name": "internalLink", - "value": "XpOYSgsLkTJy", + "value": "SL5f1Auq7sVN", "isInheritable": false, "position": 20 }, { "type": "relation", "name": "internalLink", - "value": "0Ofbk1aSuVRu", + "value": "XpOYSgsLkTJy", "isInheritable": false, "position": 30 }, + { + "type": "relation", + "name": "internalLink", + "value": "0Ofbk1aSuVRu", + "isInheritable": false, + "position": 40 + }, { "type": "label", "name": "shareAlias", @@ -10171,13 +10199,6 @@ "value": "bx bx-selection", "isInheritable": false, "position": 20 - }, - { - "type": "relation", - "name": "internalLink", - "value": "SL5f1Auq7sVN", - "isInheritable": false, - "position": 40 } ], "format": "markdown", @@ -10839,6 +10860,90 @@ "type": "text", "mime": "text/html", "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "Oau6X9rCuegd", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "iPIMuisry3hd", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "SL5f1Auq7sVN", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "NwBbFdNZ9h7O", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "YfYAtQBcfo5V", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s1aBHPd79XYj", + "isInheritable": false, + "position": 70 + }, + { + "type": "relation", + "name": "internalLink", + "value": "nBAXQFj20hS1", + "isInheritable": false, + "position": 80 + }, + { + "type": "relation", + "name": "internalLink", + "value": "hrZ1D00cLbal", + "isInheritable": false, + "position": 90 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m1lbrzyKDaRB", + "isInheritable": false, + "position": 100 + }, + { + "type": "relation", + "name": "internalLink", + "value": "oPVyFC7WL2Lp", + "isInheritable": false, + "position": 110 + }, + { + "type": "relation", + "name": "internalLink", + "value": "wy8So3yZZlH9", + "isInheritable": false, + "position": 120 + }, { "type": "label", "name": "iconClass", @@ -10852,90 +10957,6 @@ "value": "markdown", "isInheritable": false, "position": 40 - }, - { - "type": "relation", - "name": "internalLink", - "value": "Oau6X9rCuegd", - "isInheritable": false, - "position": 50 - }, - { - "type": "relation", - "name": "internalLink", - "value": "iPIMuisry3hd", - "isInheritable": false, - "position": 60 - }, - { - "type": "relation", - "name": "internalLink", - "value": "6f9hih2hXXZk", - "isInheritable": false, - "position": 70 - }, - { - "type": "relation", - "name": "internalLink", - "value": "oPVyFC7WL2Lp", - "isInheritable": false, - "position": 80 - }, - { - "type": "relation", - "name": "internalLink", - "value": "wy8So3yZZlH9", - "isInheritable": false, - "position": 150 - }, - { - "type": "relation", - "name": "internalLink", - "value": "SL5f1Auq7sVN", - "isInheritable": false, - "position": 160 - }, - { - "type": "relation", - "name": "internalLink", - "value": "NwBbFdNZ9h7O", - "isInheritable": false, - "position": 170 - }, - { - "type": "relation", - "name": "internalLink", - "value": "YfYAtQBcfo5V", - "isInheritable": false, - "position": 180 - }, - { - "type": "relation", - "name": "internalLink", - "value": "s1aBHPd79XYj", - "isInheritable": false, - "position": 190 - }, - { - "type": "relation", - "name": "internalLink", - "value": "nBAXQFj20hS1", - "isInheritable": false, - "position": 200 - }, - { - "type": "relation", - "name": "internalLink", - "value": "hrZ1D00cLbal", - "isInheritable": false, - "position": 210 - }, - { - "type": "relation", - "name": "internalLink", - "value": "m1lbrzyKDaRB", - "isInheritable": false, - "position": 220 } ], "format": "markdown", diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md index b110d09b03..7055825a43 100644 --- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md +++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md @@ -99,12 +99,15 @@ To do so: For example, to change the font of the document from the one defined by the theme or the user to a serif one: ``` -body { - --main-font-family: serif !important; - --detail-font-family: var(--main-font-family) !important; +body { + --print-font-family: serif; + --print-font-size: 11pt; } ``` +> [!IMPORTANT] +> When altering `--print-font-family`, make sure the change is done at `body` level and not `:root`, since otherwise it won't be picked up due to specificity rules. + To remark: * Multiple CSS notes can be add by using multiple `~printCss` relations. diff --git a/docs/User Guide/User Guide/Installation & Setup/Data directory.md b/docs/User Guide/User Guide/Installation & Setup/Data directory.md index 3d66bafe90..3e80a27be1 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Data directory.md +++ b/docs/User Guide/User Guide/Installation & Setup/Data directory.md @@ -77,6 +77,12 @@ TRILIUM_DATA_DIR=/home/myuser/data/my-trilium-data trilium You can then save the above command as a shell script on your path for convenience. +## Electron user data directory (desktop only) + +When running the desktop application, Electron stores internal data (caches, spell-check dictionaries, session storage, etc.) separately from the Trilium data directory. By default this goes to the system's application data folder (e.g. `%APPDATA%` on Windows), which may be undesirable in corporate environments with roaming profiles or when running in portable mode. + +To keep Electron data out of the system's roaming profile, set the `TRILIUM_ELECTRON_DATA_DIR` environment variable to an explicit path. The `trilium-portable` script does this automatically, pointing it to `trilium-electron-data/` next to the application. + ## Fine-grained directory/path location Apart from the data directory, some of the subdirectories of it can be moved elsewhere by changing an environment variable: @@ -88,4 +94,5 @@ Apart from the data directory, some of the subdirectories of it can be moved els | `TRILIUM_LOG_DIR` | `${TRILIUM_DATA_DIR}/log` | Directory where daily Backend (server) logs are stored. | | `TRILIUM_TMP_DIR` | `${TRILIUM_DATA_DIR}/tmp` | Directory where temporary files are stored (for example when opening in an external app). | | `TRILIUM_ANONYMIZED_DB_DIR` | `${TRILIUM_DATA_DIR}/anonymized-db` | Directory where a Anonymized Database is stored. | -| `TRILIUM_CONFIG_INI_PATH` | `${TRILIUM_DATA_DIR}/config.ini` | Path to Configuration (config.ini or environment variables) file. | \ No newline at end of file +| `TRILIUM_CONFIG_INI_PATH` | `${TRILIUM_DATA_DIR}/config.ini` | Path to Configuration (config.ini or environment variables) file. | +| `TRILIUM_ELECTRON_DATA_DIR` | System appData | Directory for Electron internal data (caches, spell-check dictionaries, etc.). Set this in portable mode to avoid writing to the system profile (desktop only). | \ No newline at end of file diff --git a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md index c8eb58ee57..b39241c459 100644 --- a/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md +++ b/docs/User Guide/User Guide/Installation & Setup/Desktop Installation.md @@ -11,7 +11,7 @@ Trilium offers various startup scripts to customize your experience: * `trilium-no-cert-check`: Starts Trilium without validating [TLS certificates](Server%20Installation/HTTPS%20\(TLS\).md), useful if connecting to a server with a self-signed certificate. * Alternatively, set the `NODE_TLS_REJECT_UNAUTHORIZED=0` environment variable before starting Trilium. -* `trilium-portable`: Launches Trilium in portable mode, where the [data directory](Data%20directory.md) is created within the application's directory, making it easy to move the entire setup. +* `trilium-portable`: Launches Trilium in portable mode, where the [data directory](Data%20directory.md) is created within the application's directory, making it easy to move the entire setup. Electron's internal data (caches, dictionaries, etc.) is also stored within the data directory, so no files are written to the system's roaming profile. * `trilium-safe-mode`: Boots Trilium in "safe mode," disabling any startup scripts that might cause the application to crash. ## Synchronization diff --git a/docs/User Guide/User Guide/Note Types/Markdown.md b/docs/User Guide/User Guide/Note Types/Markdown.md index b96b627329..906645611e 100644 --- a/docs/User Guide/User Guide/Note Types/Markdown.md +++ b/docs/User Guide/User Guide/Note Types/Markdown.md @@ -33,7 +33,7 @@ The following features are supported by Trilium's Markdown format and will show ```
    -   +  
    n ``` * Internal (reference) links via its HTML syntax, or through a _Wikilinks_\-like format (only Note ID): @@ -55,7 +55,6 @@ There are two ways to create a Markdown note: ## Import/export * By default, when importing a single Markdown file it automatically gets converted to a Text note. To avoid that and have it imported as a Markdown note instead: - * Right click the Note Tree and select _Import into note_. * Select the file normally. * Uncheck _Import HTML, Markdown and TXT as text notes if it's unclear from the metadata_. diff --git a/docs/User Guide/User Guide/Note Types/Text/1_Bookmarks_plus.png b/docs/User Guide/User Guide/Note Types/Text/1_Anchors_plus.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Text/1_Bookmarks_plus.png rename to docs/User Guide/User Guide/Note Types/Text/1_Anchors_plus.png diff --git a/docs/User Guide/User Guide/Note Types/Text/Anchors.md b/docs/User Guide/User Guide/Note Types/Text/Anchors.md new file mode 100644 index 0000000000..00667b7f1c --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Text/Anchors.md @@ -0,0 +1,46 @@ +# Anchors +> [!NOTE] +> This feature used to be called _Bookmarks_ (as it is the official name in the editor we are using), but in order not to collide with the concept of Bookmarks, we have renamed it to _Anchors._ + +Anchors allows creating [links](Links.md) to a certain part of a note, such as referencing a particular heading or section within a note. + +This feature was introduced in TriliumNext v0.94.0 and augmented in v0.130.0 to support linking across notes. + +## Interaction + +* To create a anchor: + * Place the cursor at the desired position where to place the anchor. + * Look for the button in the Formatting toolbar, and then press the button. + * Alternatively, use Slash Commands and look for _anchor_. +* To place a link to a anchor: + * Place the cursor at the desired position of the link. + * From the [link](Links.md) pane, select the _Anchors_ section and select the desired anchor. + +## Linking across notes + +Trilium v0.103.0 introduces cross-note Anchors, which makes it possible to create Internal (reference) links which point to a specific anchor in that document. + +### Compatibility with documents from previous versions + +For notes created prior to Trilium v0.103.0, you might notice that the Anchors might not be identified. This limitation is intentional in order not to have to re-process all the notes, looking for anchors. + +To fix this, simply go that note and make any change (e.g. inserting a space), this will trigger the recalculation of the links. + +### Linking to anchors through the _Add link_ dialog + +1. Create an anchor in the target note using the same process as described above. +2. In another note, press Ctrl+L to insert an internal link. Select the target note containing Anchors. +3. If the target note contains Anchors, a section will appear underneath the note selector with the list of Anchors. +4. Add the link normally. + +Clicking on a reference link pointing to a anchor will automatically scroll to the desired section. + +### Linking to anchors through the bookmark toolbar + +1. Create an anchor in the target note using the same process as described above. +2. Click on the anchor to reveal the anchor's floating toolbar. +3. Click on the _Copy anchor reference link_ button. +4. Go to the note where to insert the link and press Ctrl+V. + +> [!NOTE] +> Use this method only to insert Internal (reference) links between two documents. To link to an anchor on the same note, use the _Insert link_ dialog (Ctrl+K) and select the _Anchors_ item instead. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Bookmarks_plus.png b/docs/User Guide/User Guide/Note Types/Text/Anchors_plus.png similarity index 100% rename from docs/User Guide/User Guide/Note Types/Text/Bookmarks_plus.png rename to docs/User Guide/User Guide/Note Types/Text/Anchors_plus.png diff --git a/docs/User Guide/User Guide/Note Types/Text/Bookmarks.md b/docs/User Guide/User Guide/Note Types/Text/Bookmarks.md deleted file mode 100644 index e6321b5b89..0000000000 --- a/docs/User Guide/User Guide/Note Types/Text/Bookmarks.md +++ /dev/null @@ -1,19 +0,0 @@ -# Bookmarks -Bookmarks allows creating [links](Links.md) to a certain part of a note, such as referencing a particular heading. - -Technically, bookmarks are HTML anchors. - -This feature was introduced in TriliumNext 0.94.0. - -## Interaction - -* To create a bookmark: - * Place the cursor at the desired position where to place the bookmark. - * Look for the button in the Formatting toolbar, and then press the button. -* To place a link to a bookmark: - * Place the cursor at the desired position of the link. - * From the [link](Links.md) pane, select the _Bookmarks_ section and select the desired bookmark. - -## Limitations - -* Currently it's not possible to create a link to a bookmark from a different note. This functionality will be added after the internal links feature is enhanced to support bookmarks. \ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md b/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md index 8d87e083c9..39c18dd787 100644 --- a/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md +++ b/docs/User Guide/User Guide/Note Types/Text/Insert buttons.md @@ -3,7 +3,7 @@ Press the button i ## Bookmarks -See the dedicated Bookmarks section. +See the dedicated Anchors section. ## Emoji diff --git a/packages/ckeditor5/src/extra_slash_commands.ts b/packages/ckeditor5/src/extra_slash_commands.ts index ee6068dc3d..6730187bfd 100644 --- a/packages/ckeditor5/src/extra_slash_commands.ts +++ b/packages/ckeditor5/src/extra_slash_commands.ts @@ -17,6 +17,8 @@ import internalLinkIcon from './icons/trilium.svg?raw'; import noteIcon from './icons/note.svg?raw'; import importMarkdownIcon from './icons/markdown-mark.svg?raw'; import { icons as mathIcons, MathUI } from '@triliumnext/ckeditor5-math'; +import { BookmarkUI } from "ckeditor5"; +import bxBookmark from "boxicons/svg/regular/bx-bookmark.svg?raw"; type SlashCommandDefinition = SlashCommandEditorConfig["extraCommands"][number]; @@ -74,6 +76,19 @@ export default function buildExtraCommands(): SlashCommandDefinition[] { description: "Import a markdown file into this note", icon: importMarkdownIcon, commandName: MARKDOWN_IMPORT_COMMAND + }, + { + id: "anchor", + title: "Anchor", + description: "Insert an anchor for internal linking", + aliases: [ "bookmark" ], + icon: bxBookmark, + execute: (editor: Editor) => { + // Defer to the next event loop tick so the slash command fully finishes + // its DOM/selection cleanup; _showFormView needs the view and mapper to + // be in a settled state for balloon positioning. + setTimeout(() => (editor.plugins.get(BookmarkUI) as any)._showFormView(), 0); + } } ]; } diff --git a/packages/ckeditor5/src/plugins.ts b/packages/ckeditor5/src/plugins.ts index 8407bd7026..939a284ea7 100644 --- a/packages/ckeditor5/src/plugins.ts +++ b/packages/ckeditor5/src/plugins.ts @@ -21,6 +21,7 @@ import { Mermaid } from "@triliumnext/ckeditor5-mermaid"; import { Admonition } from "@triliumnext/ckeditor5-admonition"; import { Footnotes } from "@triliumnext/ckeditor5-footnotes"; import { Math, AutoformatMath } from "@triliumnext/ckeditor5-math"; +import CopyAnchorLinkButton from "./plugins/copy_anchor_link.js"; // import "@triliumnext/ckeditor5-mermaid/index.css"; // import "@triliumnext/ckeditor5-admonition/index.css"; @@ -63,6 +64,7 @@ const TRILIUM_PLUGINS: typeof Plugin[] = [ AdmonitionToolbar, IncludeNoteBoxSizeDropdown, IncludeNoteToolbar, + CopyAnchorLinkButton, ]; /** diff --git a/packages/ckeditor5/src/plugins/copy_anchor_link.ts b/packages/ckeditor5/src/plugins/copy_anchor_link.ts new file mode 100644 index 0000000000..670b97b8f5 --- /dev/null +++ b/packages/ckeditor5/src/plugins/copy_anchor_link.ts @@ -0,0 +1,51 @@ +import { ButtonView, Plugin } from "ckeditor5"; +import copyIcon from "../icons/copy.svg?raw"; +import { escapeHtml } from "../utils"; + +/** + * Adds a "Copy anchor link" button to the bookmark/anchor widget toolbar. + * When clicked, copies a reference link href (e.g. `#root/noteId?bookmark=anchorName`) + * to the clipboard. + */ +export default class CopyAnchorLinkButton extends Plugin { + + public init() { + const editor = this.editor; + + editor.ui.componentFactory.add("copyAnchorLink", (locale) => { + const button = new ButtonView(locale); + const t = locale.t; + + button.set({ + label: t("Copy anchor reference link"), + icon: copyIcon, + tooltip: true + }); + + this.listenTo(button, "execute", () => { + const selection = editor.model.document.selection; + const selectedElement = selection.getSelectedElement(); + + if (selectedElement?.name === "bookmark") { + const bookmarkId = selectedElement.getAttribute("bookmarkId") as string; + const noteId = glob.getActiveContextNote()?.noteId; + + if (noteId && bookmarkId) { + const href = `#root/${noteId}?bookmark=${encodeURIComponent(bookmarkId)}`; + const title = glob.getReferenceLinkTitleSync(href); + const html = `${escapeHtml(title)}`; + navigator.clipboard.write([ + new ClipboardItem({ + "text/html": new Blob([html], { type: "text/html" }), + "text/plain": new Blob([href], { type: "text/plain" }) + }) + ]); + } + } + }); + + return button; + }); + } + +} diff --git a/packages/ckeditor5/src/translation_overrides.ts b/packages/ckeditor5/src/translation_overrides.ts index 47c167d518..008f2f0f4a 100644 --- a/packages/ckeditor5/src/translation_overrides.ts +++ b/packages/ckeditor5/src/translation_overrides.ts @@ -2,7 +2,16 @@ window.CKEDITOR_TRANSLATIONS = { en: { dictionary: { "Insert template": "Insert text snippet", - "Search template": "Search text snippet" + "Search template": "Search text snippet", + "Bookmark": "Anchor", + "Bookmarks": "Anchors", + "Bookmark name": "Anchor name", + "Bookmark must not be empty.": "Anchor name must not be empty.", + "Bookmark name already exists.": "Anchor name already exists.", + "Bookmark name cannot contain space characters.": "Anchor name cannot contain space characters.", + "Edit bookmark": "Edit anchor", + "Enter the bookmark name without spaces.": "Enter the anchor name without spaces.", + "Bookmark toolbar": "Anchor toolbar" } } }; diff --git a/packages/ckeditor5/src/utils.ts b/packages/ckeditor5/src/utils.ts index 4ed648d114..056538412d 100644 --- a/packages/ckeditor5/src/utils.ts +++ b/packages/ckeditor5/src/utils.ts @@ -1,5 +1,9 @@ import type { DifferItemAttribute, Editor, ModelDocumentFragment, ModelElement, ModelNode } from "ckeditor5"; +export function escapeHtml(str: string): string { + return str.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); +} + function hasHeadingAncestor(node: ModelElement | ModelNode | ModelDocumentFragment | null): boolean { let current: ModelElement | ModelNode | ModelDocumentFragment | null = node; while (current) { diff --git a/packages/commons/src/lib/builtin_attributes.ts b/packages/commons/src/lib/builtin_attributes.ts index 76cdf033dc..64a2ad48d7 100644 --- a/packages/commons/src/lib/builtin_attributes.ts +++ b/packages/commons/src/lib/builtin_attributes.ts @@ -91,6 +91,7 @@ export default [ { type: "label", name: "printPageSize" }, { type: "label", name: "printScale" }, { type: "label", name: "printMargins" }, + { type: "label", name: "internalBookmark" }, // relation names { type: "relation", name: "internalLink" }, diff --git a/packages/commons/src/lib/markdown_renderer.spec.ts b/packages/commons/src/lib/markdown_renderer.spec.ts new file mode 100644 index 0000000000..c96f632b2c --- /dev/null +++ b/packages/commons/src/lib/markdown_renderer.spec.ts @@ -0,0 +1,85 @@ +import { describe, expect, it } from "vitest"; +import { extractCodeBlocks } from "./markdown_renderer.js"; + +describe("extractCodeBlocks", () => { + it("should extract a fenced code block", () => { + const input = "before\n```js\nconsole.log('hi');\n```\nafter"; + const { processedText, placeholderMap } = extractCodeBlocks(input); + + expect(placeholderMap.size).toBe(1); + expect(processedText).toContain("before\n"); + expect(processedText).toContain("\nafter"); + expect(processedText).not.toContain("```"); + + const placeholder = [...placeholderMap.keys()][0]; + expect(placeholderMap.get(placeholder)).toBe("```js\nconsole.log('hi');\n```"); + }); + + it("should extract inline code", () => { + const input = "use `console.log` here"; + const { processedText, placeholderMap } = extractCodeBlocks(input); + + expect(placeholderMap.size).toBe(1); + expect(processedText).not.toContain("`console.log`"); + + const placeholder = [...placeholderMap.keys()][0]; + expect(placeholderMap.get(placeholder)).toBe("`console.log`"); + }); + + it("should extract multiple fenced code blocks independently", () => { + const input = "```js\na\n```\ntext\n```py\nb\n```"; + const { processedText, placeholderMap } = extractCodeBlocks(input); + + expect(placeholderMap.size).toBe(2); + expect(processedText).toContain("text"); + }); + + it("should not treat inline backtick-escaped triple backticks as a fenced code block", () => { + const input = [ + "* Code blocks with syntax highlight (e.g. ` ```js `) and automatic syntax highlight", + "* Block quotes & admonitions", + "* Math Equations", + "* Mermaid Diagrams using ` ```mermaid `" + ].join("\n"); + + const { processedText, placeholderMap } = extractCodeBlocks(input); + + // All four bullet points must survive + expect(processedText).toContain("Block quotes & admonitions"); + expect(processedText).toContain("Math Equations"); + expect(processedText).toContain("Mermaid Diagrams"); + expect(processedText).toContain("automatic syntax highlight"); + + // The inline code spans should be extracted, not fenced code blocks + for (const value of placeholderMap.values()) { + expect(value).not.toMatch(/^```[\s\S]*```$/); + } + }); + + it("should not swallow content between two inline triple-backtick mentions", () => { + const input = "Use ` ```js ` for JS and ` ```py ` for Python"; + const { processedText } = extractCodeBlocks(input); + + expect(processedText).toContain("for JS and"); + expect(processedText).toContain("for Python"); + }); + + it("should handle a real fenced code block after inline triple backticks", () => { + const input = [ + "Use ` ```js ` for JavaScript.", + "", + "```py", + "print('hello')", + "```" + ].join("\n"); + + const { processedText, placeholderMap } = extractCodeBlocks(input); + + expect(processedText).toContain("for JavaScript."); + + // Should have the inline code and the fenced block as separate entries + const values = [...placeholderMap.values()]; + const hasFencedBlock = values.some((v) => v.includes("print('hello')")); + expect(hasFencedBlock).toBe(true); + }); +}); diff --git a/packages/commons/src/lib/markdown_renderer.ts b/packages/commons/src/lib/markdown_renderer.ts index d6d3f38a99..1afcc48057 100644 --- a/packages/commons/src/lib/markdown_renderer.ts +++ b/packages/commons/src/lib/markdown_renderer.ts @@ -106,13 +106,13 @@ function handleH1(content: string, title: string): string { }); } -function extractCodeBlocks(text: string): { processedText: string; placeholderMap: Map } { +export function extractCodeBlocks(text: string): { processedText: string; placeholderMap: Map } { const codeMap = new Map(); let id = 0; const timestamp = Date.now(); text = text - .replace(/```[\s\S]*?```/g, (m) => { + .replace(/^[ \t]*```[^\n]*\n[\s\S]*?^[ \t]*```[ \t]*$/gm, (m) => { const key = ``; codeMap.set(key, m); return key; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f485d949ee..036a661601 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -187,8 +187,8 @@ importers: apps/build-docs: devDependencies: '@redocly/cli': - specifier: 2.26.0 - version: 2.26.0(@opentelemetry/api@1.9.0)(bufferutil@4.0.9)(core-js@3.46.0)(encoding@0.1.13)(utf-8-validate@6.0.5) + specifier: 2.28.0 + version: 2.28.0(@opentelemetry/api@1.9.0)(bufferutil@4.0.9)(core-js@3.46.0)(encoding@0.1.13)(utf-8-validate@6.0.5) archiver: specifier: 7.0.1 version: 7.0.1 @@ -358,8 +358,8 @@ importers: specifier: 10.29.1 version: 10.29.1 react-i18next: - specifier: 17.0.2 - version: 17.0.2(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + specifier: 17.0.3 + version: 17.0.3(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) react-window: specifier: 2.2.7 version: 2.2.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -575,14 +575,14 @@ importers: specifier: 3.0.63 version: 3.0.63(zod@4.3.6) '@ai-sdk/openai': - specifier: 3.0.52 - version: 3.0.52(zod@4.3.6) + specifier: 3.0.53 + version: 3.0.53(zod@4.3.6) '@modelcontextprotocol/sdk': specifier: ^1.12.1 version: 1.29.0(zod@4.3.6) ai: - specifier: 6.0.159 - version: 6.0.159(zod@4.3.6) + specifier: 6.0.161 + version: 6.0.161(zod@4.3.6) better-sqlite3: specifier: 12.9.0 version: 12.9.0 @@ -890,10 +890,10 @@ importers: devDependencies: '@wxt-dev/auto-icons': specifier: 1.1.1 - version: 1.1.1(wxt@0.20.21(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3)) + version: 1.1.1(wxt@0.20.22(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3)) wxt: - specifier: 0.20.21 - version: 0.20.21(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3) + specifier: 0.20.22 + version: 0.20.22(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3) apps/website: dependencies: @@ -910,8 +910,8 @@ importers: specifier: 6.6.7 version: 6.6.7(preact@10.29.1) react-i18next: - specifier: 17.0.2 - version: 17.0.2(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) + specifier: 17.0.3 + version: 17.0.3(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2) devDependencies: '@preact/preset-vite': specifier: 2.10.5 @@ -1482,8 +1482,8 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@3.0.96': - resolution: {integrity: sha512-BDiVEMUVHGpngReeigzLyJobG0TvzYbNGzdHI8JYBZHrjOX4aL6qwIls7z3p7V4TuXVWUCbG8TSWEe7ksX4Vhw==} + '@ai-sdk/gateway@3.0.98': + resolution: {integrity: sha512-Ol+nP8PIlj8FjN8qKlxhE89N0woqAaGi9CUBGp1boe3RafpphJ7WMuq/RErSvxtwTqje03TP+zIdzP113krxRg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -1494,8 +1494,8 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@3.0.52': - resolution: {integrity: sha512-4Rr8NCGmfWTz6DCUvixn9UmyZcMatiHn0zWoMzI3JCUe9R1P/vsPOpCBALKoSzVYOjyJnhtnVIbfUKujcS39uw==} + '@ai-sdk/openai@3.0.53': + resolution: {integrity: sha512-Wld+Rbc05KaUn08uBt06eEuwcgalcIFtIl32Yp+GxuZXUQwOb6YeAuq+C6da4ch6BurFoqEaLemJVwjBb7x+PQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -4872,27 +4872,27 @@ packages: '@redocly/cli-otel@0.1.2': resolution: {integrity: sha512-Bg7BoO5t1x3lVK+KhA5aGPmeXpQmdf6WtTYHhelKJCsQ+tRMiJoFAQoKHoBHAoNxXrhlS3K9lKFLHGmtxsFQfA==} - '@redocly/cli@2.26.0': - resolution: {integrity: sha512-24S1ls0qvu3uaPiW4OImy06CpImAkUOd3h7OG+Hq9By5pPavjOE34KtdQTaaFso3e1qgzXYdQh6HPqEY1nTZgA==} + '@redocly/cli@2.28.0': + resolution: {integrity: sha512-hAHtMjo4fLdLqZXtZwQqlwGnAiOzEAh7EPbE01rs9j7cewj2btOXrGQW8v6Eg3gDh+i77/DOxxazRWvZ/zAa7w==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} hasBin: true '@redocly/config@0.22.2': resolution: {integrity: sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==} - '@redocly/config@0.46.1': - resolution: {integrity: sha512-dSdkB2wRLtvl3f7ayRu9vqVhUMjjRaxZlHgRbgOtPPXxn4uI/ciDO87h4CJb7Iet+OVpevpAU6gU8bo5qVbQxg==} + '@redocly/config@0.48.0': + resolution: {integrity: sha512-8W3wz+Q7y4e9klJWlYOvQWK5r7P2Mo589vcjtlT5coOxsyAdt53k8Vb8iAqnRiGWExbjBQmSbL2XbuU747Nf6Q==} '@redocly/openapi-core@1.34.5': resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==} engines: {node: '>=18.17.0', npm: '>=9.5.0'} - '@redocly/openapi-core@2.26.0': - resolution: {integrity: sha512-BjTPzSV1Gv430W9S/7i5T/dEZDK00GFk6ILCNTI+31pA9lEFJOXc0XRJT+V3v+m3nXIgGoo6GgqeLdAiM10rNg==} + '@redocly/openapi-core@2.28.0': + resolution: {integrity: sha512-Htpp4PsjKMgEuMT9iJu4iuFFzWCDe8FylvpGaQEA5D7jZXWv+8XvnqhpGCKN2cM/n/Uri2QfqNdw0JlKIC59sg==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} - '@redocly/respect-core@2.26.0': - resolution: {integrity: sha512-mejFg26XNp8pqHwnL75QvI7MO4dhgFKa+v35OgOcVMrU9tGZ/VaFbplEyvdrRgjoonguXoLDoMN4Iw1rWlZg0g==} + '@redocly/respect-core@2.28.0': + resolution: {integrity: sha512-svjCRzXsj/EyN7chfB9pTVYvWT1+hlOqMkZVlkrH6PqFKXAHYeP47YRW9+3omUSDBd1Ph4A4J4NBUW1PRph5+g==} engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} '@replit/codemirror-indentation-markers@6.5.3': @@ -6770,8 +6770,8 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@6.0.159: - resolution: {integrity: sha512-S18ozG7Dkm3Ud1tzOtAK5acczD4vygfml80RkpM9VWMFpvAFwAKSHaGYkATvPQHIE+VpD1tJY9zcTXLZ/zR5cw==} + ai@6.0.161: + resolution: {integrity: sha512-ufhmijmx2YyWTPAicGgtpLOB/xD7mG8zKs1pT1Trj+JL/3r1rS8fkMi/cHZoChSAQSGB4pgmcWVxDrVTUvK2IQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -10860,9 +10860,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.7.4: - resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} - mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -11891,8 +11888,8 @@ packages: peerDependencies: react: ^19.2.4 - react-i18next@17.0.2: - resolution: {integrity: sha512-shBftH2vaTWK2Bsp7FiL+cevx3xFJlvFxmsDFQSrJc+6twHkP0tv/bGa01VVWzpreUVVwU+3Hev5iFqRg65RwA==} + react-i18next@17.0.3: + resolution: {integrity: sha512-x4xjvUNZ56T+zfXWNedNnCET9Xq1IBYWX7IsWo5cCQ/RT+Rm7GWqt0h9PShFi4IhyMnsdiu1C6Jc4DE+/S3PFQ==} peerDependencies: i18next: '>= 26.0.1' react: '>= 16.8.0' @@ -14099,8 +14096,8 @@ packages: resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} engines: {node: '>=20'} - wxt@0.20.21: - resolution: {integrity: sha512-rDocJ9QEWKnGd7NTTTxKIJ5MsXwv9lXk4/ITFS9eeksTCYotshxzAiptkRPEHCgsJNiGMNY/UFNxVDyqWGe7Bw==} + wxt@0.20.22: + resolution: {integrity: sha512-njFI77H0dAbK/bQCN8u8QYiusg6GKDPMtsQDCqIfrh1oGHMHgrMEMgeGOlqAltG9OOGGB1DvFYDzTvxqfEKVKQ==} engines: {bun: '>=1.2.0', node: '>=20.12.0'} hasBin: true peerDependencies: @@ -14270,7 +14267,7 @@ snapshots: '@ai-sdk/provider-utils': 4.0.23(zod@4.3.6) zod: 4.3.6 - '@ai-sdk/gateway@3.0.96(zod@4.3.6)': + '@ai-sdk/gateway@3.0.98(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.8 '@ai-sdk/provider-utils': 4.0.23(zod@4.3.6) @@ -14283,7 +14280,7 @@ snapshots: '@ai-sdk/provider-utils': 4.0.23(zod@4.3.6) zod: 4.3.6 - '@ai-sdk/openai@3.0.52(zod@4.3.6)': + '@ai-sdk/openai@3.0.53(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.8 '@ai-sdk/provider-utils': 4.0.23(zod@4.3.6) @@ -18747,15 +18744,15 @@ snapshots: dependencies: ulid: 2.4.0 - '@redocly/cli@2.26.0(@opentelemetry/api@1.9.0)(bufferutil@4.0.9)(core-js@3.46.0)(encoding@0.1.13)(utf-8-validate@6.0.5)': + '@redocly/cli@2.28.0(@opentelemetry/api@1.9.0)(bufferutil@4.0.9)(core-js@3.46.0)(encoding@0.1.13)(utf-8-validate@6.0.5)': dependencies: '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.34.0 '@redocly/cli-otel': 0.1.2 - '@redocly/openapi-core': 2.26.0 - '@redocly/respect-core': 2.26.0 + '@redocly/openapi-core': 2.28.0 + '@redocly/respect-core': 2.28.0 abort-controller: 3.0.0 ajv: '@redocly/ajv@8.18.0' ajv-formats: 3.0.1(@redocly/ajv@8.18.0) @@ -18789,7 +18786,7 @@ snapshots: '@redocly/config@0.22.2': {} - '@redocly/config@0.46.1': + '@redocly/config@0.48.0': dependencies: json-schema-to-ts: 2.7.2 @@ -18807,10 +18804,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@redocly/openapi-core@2.26.0': + '@redocly/openapi-core@2.28.0': dependencies: '@redocly/ajv': 8.18.0 - '@redocly/config': 0.46.1 + '@redocly/config': 0.48.0 ajv: '@redocly/ajv@8.18.0' ajv-formats: 3.0.1(@redocly/ajv@8.18.0) colorette: 1.4.0 @@ -18820,12 +18817,12 @@ snapshots: pluralize: 8.0.0 yaml-ast-parser: 0.0.43 - '@redocly/respect-core@2.26.0': + '@redocly/respect-core@2.28.0': dependencies: '@faker-js/faker': 7.6.0 '@noble/hashes': 1.8.0 '@redocly/ajv': 8.18.0 - '@redocly/openapi-core': 2.26.0 + '@redocly/openapi-core': 2.28.0 ajv: '@redocly/ajv@8.18.0' better-ajv-errors: 1.2.0(@redocly/ajv@8.18.0) colorette: 2.0.20 @@ -21577,12 +21574,12 @@ snapshots: optionalDependencies: react: 19.2.4 - '@wxt-dev/auto-icons@1.1.1(wxt@0.20.21(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3))': + '@wxt-dev/auto-icons@1.1.1(wxt@0.20.22(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3))': dependencies: defu: 6.1.6 fs-extra: 11.3.4 sharp: 0.34.5 - wxt: 0.20.21(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3) + wxt: 0.20.22(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3) '@wxt-dev/browser@0.1.40': dependencies: @@ -21668,9 +21665,9 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@6.0.159(zod@4.3.6): + ai@6.0.161(zod@4.3.6): dependencies: - '@ai-sdk/gateway': 3.0.96(zod@4.3.6) + '@ai-sdk/gateway': 3.0.98(zod@4.3.6) '@ai-sdk/provider': 3.0.8 '@ai-sdk/provider-utils': 4.0.23(zod@4.3.6) '@opentelemetry/api': 1.9.0 @@ -24676,7 +24673,7 @@ snapshots: glob@13.0.6: dependencies: - minimatch: 10.2.4 + minimatch: 10.2.5 minipass: 7.1.3 path-scurry: 2.0.2 @@ -25924,7 +25921,7 @@ snapshots: local-pkg@1.1.1: dependencies: - mlly: 1.7.4 + mlly: 1.8.0 pkg-types: 2.3.0 quansync: 0.2.10 @@ -26707,13 +26704,6 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.7.4: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.1 - mlly@1.8.0: dependencies: acorn: 8.16.0 @@ -27813,7 +27803,7 @@ snapshots: react: 19.2.4 scheduler: 0.27.0 - react-i18next@17.0.2(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2): + react-i18next@17.0.3(i18next@26.0.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2): dependencies: '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 @@ -30417,7 +30407,7 @@ snapshots: is-wsl: 3.1.1 powershell-utils: 0.1.0 - wxt@0.20.21(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3): + wxt@0.20.22(@types/node@24.12.2)(eslint@10.2.0(jiti@2.6.1))(jiti@2.6.1)(less@4.1.3)(rollup@4.60.1)(sass-embedded@1.91.0)(sass@1.91.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.3): dependencies: '@1natsu/wait-element': 4.1.2 '@aklinker1/rollup-plugin-visualizer': 5.12.0(rollup@4.60.1)