Merge remote-tracking branch 'origin/main' into standalone

This commit is contained in:
Elian Doran
2026-04-19 20:26:10 +03:00
365 changed files with 16768 additions and 5610 deletions

View File

@@ -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'

View File

@@ -8,7 +8,7 @@ inputs:
runs:
using: composite
steps:
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:

View File

@@ -55,7 +55,7 @@ runs:
# Post deployment URL as PR comment
- name: Comment PR with Preview URL
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
uses: actions/github-script@v9
env:
COMMENT_BODY: ${{ inputs.comment_body }}
PRODUCTION_URL: ${{ inputs.production_url }}

View File

@@ -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

50
.github/workflows/claude.yml vendored Normal file
View File

@@ -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 *)'

View File

@@ -45,7 +45,7 @@ jobs:
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v5
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v6

View File

@@ -32,7 +32,7 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -87,7 +87,7 @@ jobs:
- test_dev
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Update build info
@@ -122,7 +122,7 @@ jobs:
- name: Checkout the repository
uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Install dependencies
run: pnpm install --frozen-lockfile

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:

View File

@@ -42,7 +42,7 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -142,7 +142,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:

View File

@@ -42,7 +42,7 @@ jobs:
shell: bash
forge_platform: linux
- name: windows
image: win-signing
image: windows-latest
shell: cmd
forge_platform: win32
# Exclude ARM64 Linux from default matrix to use native runner
@@ -61,7 +61,7 @@ jobs:
runs-on: ${{ matrix.os.image }}
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -88,12 +88,10 @@ jobs:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }}
WINDOWS_SIGN_ERROR_LOG: ${{ vars.WINDOWS_SIGN_ERROR_LOG }}
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
- name: Publish release
uses: softprops/action-gh-release@v2.6.1
uses: softprops/action-gh-release@v3.0.0
if: ${{ github.event_name != 'pull_request' }}
with:
make_latest: false
@@ -134,7 +132,7 @@ jobs:
arch: ${{ matrix.arch }}
- name: Publish release
uses: softprops/action-gh-release@v2.6.1
uses: softprops/action-gh-release@v3.0.0
if: ${{ github.event_name != 'pull_request' }}
with:
make_latest: false

View File

@@ -38,7 +38,7 @@ jobs:
filter: tree:0
fetch-depth: 0
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v6
with:
node-version: 24

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -66,7 +66,7 @@ jobs:
runs-on: ${{ matrix.os.image }}
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -150,7 +150,7 @@ jobs:
path: upload
- name: Publish stable release
uses: softprops/action-gh-release@v2.6.1
uses: softprops/action-gh-release@v3.0.0
with:
draft: false
body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md

View File

@@ -32,7 +32,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
@@ -58,7 +58,7 @@ jobs:
compression-level: 0
- name: Release web clipper extension
uses: softprops/action-gh-release@v2.6.1
uses: softprops/action-gh-release@v3.0.0
if: ${{ startsWith(github.ref, 'refs/tags/web-clipper-v') }}
with:
draft: false

View File

@@ -26,7 +26,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: pnpm/action-setup@v6
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:

118
.mailmap
View File

@@ -1,2 +1,116 @@
zadam <adam.zivner@gmail.com>
zadam <zadam.apps@gmail.com>
# Format: Canonical Name <canonical-email> <commit-email>
# Merges aliases so `git shortlog`, `git log --use-mailmap`, etc. group commits per person.
# Core maintainers
zadam <zadam.apps@gmail.com>
zadam <zadam.apps@gmail.com> <adam.zivner@gmail.com>
zadam <zadam.apps@gmail.com> <adam.zivner@gemalto.com>
Elian Doran <contact@eliandoran.me>
Elian Doran <contact@eliandoran.me> <online@eliandoran.me>
Adorian Doran <adorian@esevo.ro>
Adorian Doran <adorian@esevo.ro> <adoriandoran@gmail.com>
# Contributors with multiple emails / name variants
Panagiotis Papadopoulos <pano_90@gmx.net> <102623907+pano9000@users.noreply.github.com>
Jon Fuller <jonfuller2012@gmail.com>
SiriusXT <1160925501@qq.com>
SiriusXT <1160925501@qq.com> <11609255001@qq.com>
SiriusXT <1160925501@qq.com> <37627919+SiriusXT@users.noreply.github.com>
JYC333 <22962980+JYC333@users.noreply.github.com>
JYC333 <22962980+JYC333@users.noreply.github.com> <yuchuanjin333@gmail.com>
Nriver <6752679+Nriver@users.noreply.github.com>
Francis C. <normitomf@gmail.com>
Francis C. <normitomf@gmail.com> <francistw@users.noreply.github.com>
Thomas Frei <7283497+thfrei@users.noreply.github.com>
hasecilu <hasecilu@tuta.io>
meinzzzz <lukas.geiselhart35@gmail.com>
FliegendeWurst <arne.keller@posteo.de>
FliegendeWurst <arne.keller@posteo.de> <2012gdwu@web.de>
FliegendeWurst <arne.keller@posteo.de> <2012gdwu+github@posteo.de>
MeIchthys <github.com@meichthys.com>
MeIchthys <github.com@meichthys.com> <10717998+meichthys@users.noreply.github.com>
Marcel Wiechmann <marcel.wiechmann@gmail.com>
Marcel Wiechmann <marcel.wiechmann@gmail.com> <github.y3y0w@sl.wiechmann.at>
Tomas Adamek <ad.tomik@seznam.cz>
Tomas Adamek <ad.tomik@seznam.cz> <50672285+Kureii@users.noreply.github.com>
soulsands <407221377@qq.com>
chesspro13 <chesspro13@gmail.com>
sigaloid <69441971+sigaloid@users.noreply.github.com>
Marek Lewandowski <m.lewandowski@cksource.com>
Marek Lewandowski <m.lewandowski@cksource.com> <code@mlewandowski.com>
Marek Lewandowski <m.lewandowski@cksource.com> <mlewand@users.noreply.github.com>
lzinga <lucas.elzinga@outlook.com>
lzinga <lucas.elzinga@outlook.com> <lzinga@users.noreply.github.com>
Sukant Gujar <sukantgujar@yahoo.com>
Matt Wilkie <maphew@gmail.com>
Matt Wilkie <maphew@gmail.com> <matt.wilkie@yukon.ca>
Andreas Haan <andreas.mobil1@googlemail.com>
Potjoe-97 <42873357+Potjoe-97@users.noreply.github.com>
Potjoe-97 <42873357+Potjoe-97@users.noreply.github.com> <giann@LAPTOPT490-GF>
Alex Pietsch <54153428+alexpietsch@users.noreply.github.com>
Laurent Cozic <laurent@cozic.net>
Laurent Cozic <laurent@cozic.net> <laurent22@users.noreply.github.com>
Zexin Yuan <git@yzx9.xyz>
Zexin Yuan <git@yzx9.xyz> <yuan.zx@outlook.com>
hulmgulm <hulmgulm@users.noreply.github.com>
hulmgulm <hulmgulm@users.noreply.github.com> <12165268+hulmgulm@users.noreply.github.com>
hulmgulm <hulmgulm@users.noreply.github.com> <github@hulmgulm.de>
Jules Bertholet <jules.bertholet@gmail.com>
Charles Dagenais <dagenais.charles@gmail.com>
Giulia Ye <yg97.cs@gmail.com>
baddate <37013819+baddate@users.noreply.github.com>
DerVogel101 <128903814+DerVogel101@users.noreply.github.com>
DerVogel101 <128903814+DerVogel101@users.noreply.github.com> <jan.irmer@outlook.de>
Marcello Fuschi <marcellofuschi1@gmail.com>
Jiahao Lee <lijiahao34@live.com>
Dmitry Matveyev <dev@greenfork.me>
Dmitry Matveyev <dev@greenfork.me> <info@greenfork.me>
Grant Zhu <a1065135230@gmail.com>
Sylvain Pasche <sylvain.pasche@gmail.com>
Sylvain Pasche <sylvain.pasche@gmail.com> <spasche@spasche.net>
mm21 <8033134+mm21@users.noreply.github.com>
mm21 <8033134+mm21@users.noreply.github.com> <mm21.dev@gmail.com>
BeatLink <git@beatlink.simplelogin.com>
BeatLink <git@beatlink.simplelogin.com> <github@beatlink.simplelogin.com>
Florian Meißner <161936+Mystler@users.noreply.github.com>
Florian Meißner <161936+Mystler@users.noreply.github.com> <developer@mystler.eu>

2
.nvmrc
View File

@@ -1 +1 @@
24.14.1
24.15.0

View File

@@ -218,8 +218,9 @@ Use `note.getOwnedAttribute()` for direct, `note.getAttribute()` for inherited.
- To add a new user preference:
1. Add the option type to `OptionDefinitions` in `packages/commons/src/lib/options_interface.ts`
2. Add a default value in `apps/server/src/services/options_init.ts` in the `defaultOptions` array
3. **Whitelist the option** in `apps/server/src/routes/api/options.ts` by adding it to `ALLOWED_OPTIONS` (required for client updates)
4. Use `useTriliumOption("optionName")` hook in React components to read/write the option
3. **Whitelist the option** in `apps/server/src/routes/api/options.ts` by adding it to the `ALLOWED_OPTIONS` array — **without this, the API will reject changes with "Option 'X' is not allowed to be changed"**
4. If the option should be user-editable in the UI, add a control in the appropriate settings component (e.g., `apps/client/src/widgets/type_widgets/options/other.tsx`) and a translation key in `apps/client/src/translations/en/translation.json`
5. Use `useTriliumOption("optionName")` hook in React components to read/write the option
- Available hooks: `useTriliumOption` (string), `useTriliumOptionBool`, `useTriliumOptionInt`, `useTriliumOptionJson`
- See `docs/Developer Guide/Developer Guide/Concepts/Options/Creating a new option.md` for detailed documentation

View File

@@ -20,11 +20,11 @@
"@triliumnext/server": "workspace:*"
},
"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",
"typedoc": "0.28.18",
"typedoc": "0.28.19",
"typedoc-plugin-missing-exports": "4.1.3"
}
}

View File

@@ -34,14 +34,14 @@
"@triliumnext/highlightjs": "workspace:*",
"@triliumnext/share-theme": "workspace:*",
"@triliumnext/split.js": "workspace:*",
"@univerjs/preset-sheets-conditional-formatting": "0.20.0",
"@univerjs/preset-sheets-core": "0.20.0",
"@univerjs/preset-sheets-data-validation": "0.20.0",
"@univerjs/preset-sheets-filter": "0.20.0",
"@univerjs/preset-sheets-find-replace": "0.20.0",
"@univerjs/preset-sheets-note": "0.20.0",
"@univerjs/preset-sheets-sort": "0.20.0",
"@univerjs/presets": "0.20.0",
"@univerjs/preset-sheets-conditional-formatting": "0.20.1",
"@univerjs/preset-sheets-core": "0.20.1",
"@univerjs/preset-sheets-data-validation": "0.20.1",
"@univerjs/preset-sheets-filter": "0.20.1",
"@univerjs/preset-sheets-find-replace": "0.20.1",
"@univerjs/preset-sheets-note": "0.20.1",
"@univerjs/preset-sheets-sort": "0.20.1",
"@univerjs/presets": "0.20.1",
"@zumer/snapdom": "2.8.0",
"autocomplete.js": "0.38.1",
"bootstrap": "5.3.8",
@@ -49,9 +49,10 @@
"clsx": "2.1.1",
"color": "5.0.3",
"debounce": "3.0.0",
"dompurify": "3.3.3",
"dompurify": "3.4.0",
"draggabilly": "3.0.0",
"force-graph": "1.51.2",
"htmldiff-js": "1.0.5",
"i18next": "26.0.4",
"i18next-http-backend": "3.0.4",
"jquery": "4.0.0",
@@ -66,9 +67,9 @@
"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.0",
"reveal.js": "6.0.1",
"rrule": "2.8.1",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.4.0",
@@ -84,7 +85,7 @@
"@types/mark.js": "8.11.12",
"@types/tabulator-tables": "6.3.1",
"copy-webpack-plugin": "14.0.0",
"happy-dom": "20.8.9",
"happy-dom": "20.9.0",
"lightningcss": "1.32.0",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "4.0.1"

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><path d="M63.966,45.043c0.008-0.009,0.021-0.021,0.027-0.029c0.938-1.156-0.823-13.453-5.063-20.125 c-1.389-2.186-2.239-3.423-3.219-4.719c-3.907-5.166-6-6.125-6-6.125S35.732,24.78,36.149,44.315 c-1.754,0.065-11.218,7.528-14.826,14.388c-1.206,2.291-1.856,3.645-2.493,5.141c-2.539,5.957-2.33,8.25-2.33,8.25 s16.271,6.79,33.014-3.294c0.007,0.021,0.013,0.046,0.02,0.063c0.537,1.389,12.08,5.979,19.976,5.621 c2.587-0.116,4.084-0.238,5.696-0.444c6.424-0.818,8.298-2.157,8.298-2.157S81.144,54.396,63.966,45.043z M50.787,65.343 c1.059-1.183,4.648-5.853,0.995-11.315c-0.253-0.377-0.496-0.236-0.496-0.236s0.063,10.822-5.162,12.359 c-5.225,1.537-13.886,4.4-20.427,0.455C25,66.186,26.924,53.606,38.544,47.229c0.546,1.599,2.836,6.854,9.292,6.409 c0.453-0.031,0.453-0.313,0.453-0.313s-9.422-5.328-8.156-10.625s3.089-14.236,9.766-17.948c0.714-0.397,10.746,7.593,10.417,20.94 c-1.606-0.319-7.377-1.004-10.226,4.864c-0.198,0.409,0.046,0.549,0.046,0.549s9.31-5.521,13.275-1.789 c3.965,3.733,10.813,9.763,10.71,17.4C74.111,67.533,62.197,72.258,50.787,65.343z M35.613,35.145c0,0-0.991,3.241-0.603,7.524 l-13.393-7.524C21.618,35.145,27.838,30.931,35.613,35.145z M21.193,36.03l13.344,7.612c-3.872,1.872-6.142,4.388-6.142,4.388 C20.78,43.531,21.193,36.03,21.193,36.03z M72.287,49.064c0,0-2.321-2.471-6.23-4.263l13.187-7.881 C79.243,36.92,79.808,44.413,72.287,49.064z M78.687,36.113l-13.237,7.794c0.3-4.291-0.754-7.511-0.754-7.511 C72.383,32.025,78.687,36.113,78.687,36.113z M42.076,73.778c0,0,3.309-0.737,6.845-3.185l0.056,15.361 C48.977,85.955,42.244,82.621,42.076,73.778z M49.956,85.888L50,70.526c3.539,2.445,6.846,3.181,6.846,3.181 C56.686,82.551,49.956,85.888,49.956,85.888z"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>Trilium Notes</title>
<g>
<path d="m202.9 112.7c-22.5 16.1-54.5 12.8-74.9 6.3l14.8-11.8 14.1-11.3 49.1-39.3-51.2 35.9-14.3 10-14.9 10.5c0.7-21.2 7-49.9 28.6-65.4 1.8-1.3 3.9-2.6 6.1-3.8 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.4 2.8-4.9 5.4-7.4 7.8-3.4 3.5-6.8 6.4-10.1 8.8z" fill="#ab60e3"/>
<path d="m213.1 104c-22.2 12.6-51.4 9.3-70.3 3.2l14.1-11.3 49.1-39.3-51.2 35.9-14.3 10c0.5-18.1 4.9-42.1 19.7-58.6 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.3 2.8-4.8 5.4-7.2 7.8z" fill="#8038b8"/>
<path d="m220.5 96.2c-21.1 8.6-46.6 5.3-63.7-0.2l49.2-39.4-51.2 35.9c0.3-15.8 3.5-36.6 14.3-52.8 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.8 66z" fill="#560a8f"/>
<path d="m106.7 179c-5.8-21 5.2-43.8 15.5-57.2l4.8 14.2 4.5 13.4 15.9 47-12.8-47.6-3.6-13.2-3.7-13.9c15.5 6.2 35.1 18.6 40.7 38.8 0.5 1.7 0.9 3.6 1.2 5.5 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.1-3.8-7.6-1.6-3.5-2.9-6.8-3.8-10z" fill="#bb9dd2"/>
<path d="m110.4 188.9c-3.4-19.8 6.9-40.5 16.6-52.9l4.5 13.4 15.9 47-12.8-47.6-3.6-13.2c13.3 5.2 29.9 15 38.1 30.4 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.2-3.8-7.7z" fill="#9a6cbc"/>
<path d="m114.2 196.5c-0.7-18 8.6-35.9 17.3-47.1l15.9 47-12.8-47.6c11.6 4.4 26.1 12.4 35.2 24.8 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8z" fill="#783ba5"/>
<path d="m86.3 59.1c21.7 10.9 32.4 36.6 35.8 54.9l-15.2-6.6-14.5-6.3-50.6-22 48.8 24.9 13.6 6.9 14.3 7.3c-16.6 7.9-41.3 14.5-62.1 4.1-1.8-0.9-3.6-1.9-5.4-3.2-2.3-1.5-4.5-3.2-6.8-5.1-19.9-16.4-40.3-46.4-42.7-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.2 0.8 6.2 1.6 9.1 2.5 4 1.3 7.6 2.8 10.9 4.4z" fill="#ab60e3"/>
<path d="m75.4 54.8c18.9 12 28.4 35.6 31.6 52.6l-14.5-6.3-50.6-22 48.7 24.9 13.6 6.9c-14.1 6.8-34.5 13-53.3 8.2-2.3-1.5-4.5-3.2-6.8-5.1-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.1 0.8 6.2 1.6 9.1 2.6z" fill="#8038b8"/>
<path d="m66.3 52.2c15.3 12.8 23.3 33.6 26.1 48.9l-50.6-22 48.8 24.9c-12.2 6-29.6 11.8-46.5 10-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3z" fill="#6f2796"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 256 256" version="1.1" viewBox="0 0 256 256" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<title>Trilium Notes</title>
<style type="text/css">
.st0{fill:#95C980;}
.st1{fill:#72B755;}
.st2{fill:#4FA52B;}
.st3{fill:#EE8C89;}
.st4{fill:#E96562;}
.st5{fill:#E33F3B;}
.st6{fill:#EFB075;}
.st7{fill:#E99547;}
.st8{fill:#E47B19;}
</style>
<g>
<path class="st0" d="m202.9 112.7c-22.5 16.1-54.5 12.8-74.9 6.3l14.8-11.8 14.1-11.3 49.1-39.3-51.2 35.9-14.3 10-14.9 10.5c0.7-21.2 7-49.9 28.6-65.4 1.8-1.3 3.9-2.6 6.1-3.8 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.4 2.8-4.9 5.4-7.4 7.8-3.4 3.5-6.8 6.4-10.1 8.8z"/>
<path class="st1" d="m213.1 104c-22.2 12.6-51.4 9.3-70.3 3.2l14.1-11.3 49.1-39.3-51.2 35.9-14.3 10c0.5-18.1 4.9-42.1 19.7-58.6 2.7-1.5 5.7-2.9 8.8-4.1 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.9 65.9-2.3 2.8-4.8 5.4-7.2 7.8z"/>
<path class="st2" d="m220.5 96.2c-21.1 8.6-46.6 5.3-63.7-0.2l49.2-39.4-51.2 35.9c0.3-15.8 3.5-36.6 14.3-52.8 27.1-11.1 68.5-15.3 85.2-9.5 0.1 16.2-15.9 45.4-33.8 66z"/>
<path class="st3" d="m106.7 179c-5.8-21 5.2-43.8 15.5-57.2l4.8 14.2 4.5 13.4 15.9 47-12.8-47.6-3.6-13.2-3.7-13.9c15.5 6.2 35.1 18.6 40.7 38.8 0.5 1.7 0.9 3.6 1.2 5.5 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.1-3.8-7.6-1.6-3.5-2.9-6.8-3.8-10z"/>
<path class="st4" d="m110.4 188.9c-3.4-19.8 6.9-40.5 16.6-52.9l4.5 13.4 15.9 47-12.8-47.6-3.6-13.2c13.3 5.2 29.9 15 38.1 30.4 0.4 2.4 0.6 5 0.7 7.7 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8-1.4-2.6-2.7-5.2-3.8-7.7z"/>
<path class="st5" d="m114.2 196.5c-0.7-18 8.6-35.9 17.3-47.1l15.9 47-12.8-47.6c11.6 4.4 26.1 12.4 35.2 24.8 0.9 23.1-7.1 54.9-15.9 65.7-12-4.3-29.3-24-39.7-42.8z"/>
<path class="st6" d="m86.3 59.1c21.7 10.9 32.4 36.6 35.8 54.9l-15.2-6.6-14.5-6.3-50.6-22 48.8 24.9 13.6 6.9 14.3 7.3c-16.6 7.9-41.3 14.5-62.1 4.1-1.8-0.9-3.6-1.9-5.4-3.2-2.3-1.5-4.5-3.2-6.8-5.1-19.9-16.4-40.3-46.4-42.7-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.2 0.8 6.2 1.6 9.1 2.5 4 1.3 7.6 2.8 10.9 4.4z"/>
<path class="st7" d="m75.4 54.8c18.9 12 28.4 35.6 31.6 52.6l-14.5-6.3-50.6-22 48.7 24.9 13.6 6.9c-14.1 6.8-34.5 13-53.3 8.2-2.3-1.5-4.5-3.2-6.8-5.1-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3 3.1 0.8 6.2 1.6 9.1 2.6z"/>
<path class="st8" d="m66.3 52.2c15.3 12.8 23.3 33.6 26.1 48.9l-50.6-22 48.8 24.9c-12.2 6-29.6 11.8-46.5 10-19.8-16.4-40.2-46.4-42.6-61.5 12.4-6.5 41.5-5.8 64.8-0.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -24,6 +24,7 @@ import { IncludeNoteOpts } from "../widgets/dialogs/include_note.jsx";
import type { InfoProps } from "../widgets/dialogs/info.jsx";
import type { MarkdownImportOpts } from "../widgets/dialogs/markdown_import.jsx";
import { ChooseNoteTypeCallback } from "../widgets/dialogs/note_type_chooser.jsx";
import type { PrintPreviewData } from "../widgets/dialogs/print_preview.jsx";
import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js";
import type NoteTreeWidget from "../widgets/note_tree.js";
import Component from "./component.js";
@@ -280,6 +281,7 @@ export type CommandMappings = {
backInNoteHistory: CommandData;
forwardInNoteHistory: CommandData;
forceSaveRevision: CommandData;
saveNamedRevision: CommandData;
scrollToActiveNote: CommandData;
quickSearch: CommandData;
collapseTree: CommandData;
@@ -330,6 +332,7 @@ export type CommandMappings = {
toggleRightPane: CommandData;
printActiveNote: CommandData;
exportAsPdf: CommandData;
showPrintPreview: PrintPreviewData;
openNoteExternally: CommandData;
openNoteCustom: CommandData;
openNoteOnServer: CommandData;

View File

@@ -1,6 +1,7 @@
import { CreateChildrenResponse, SqlExecuteResponse } from "@triliumnext/commons";
import bundleService from "../services/bundle.js";
import dialog from "../services/dialog.js";
import dateNoteService from "../services/date_notes.js";
import froca from "../services/froca.js";
import { t } from "../services/i18n.js";
@@ -216,4 +217,21 @@ export default class Entrypoints extends Component {
toastService.showMessage(t("entrypoints.note-revision-created"));
}
async saveNamedRevisionCommand() {
const noteId = appContext.tabManager.getActiveContextNoteId();
if (!noteId) return;
const name = await dialog.prompt({
title: t("entrypoints.save-named-revision-title"),
message: t("entrypoints.save-named-revision-message"),
defaultValue: ""
});
// null means the user cancelled
if (name === null) return;
await server.post(`notes/${noteId}/revision`, { description: name || undefined });
toastService.showMessage(t("entrypoints.note-revision-created"));
}
}

View File

@@ -25,6 +25,15 @@ export type GetTextEditorCallback = (editor: CKTextEditor) => void;
export type SaveState = "saved" | "saving" | "unsaved" | "error";
const READ_ONLY_CAPABLE_TYPES: string[] = [
"text",
"code",
"mermaid",
"canvas",
"mindMap",
"spreadsheet"
];
export interface NoteContextDataMap {
toc: HeadingContext;
pdfPages: {
@@ -303,8 +312,12 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
return false;
}
// "readOnly" is a state valid only for text/code notes
if (!this.note || (this.note.type !== "text" && this.note.type !== "code")) {
if (!this.note) {
return false;
}
// Note types that support a read-only state (via the #readOnly label, source view, or auto-readonly).
if (!READ_ONLY_CAPABLE_TYPES.includes(this.note.type)) {
return false;
}
@@ -320,6 +333,11 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
return true;
}
// Auto read-only based on content size is only configurable for text/code.
if (this.note.type !== "text" && this.note.type !== "code") {
return false;
}
// Store the initial decision about read-only status in the viewScope
// This will be "remembered" until the viewScope is refreshed
if (!this.viewScope) {

View File

@@ -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() {

View File

@@ -1069,6 +1069,10 @@ export default class FNote {
return this.mime === "text/x-sqlite;schema=trilium";
}
isMarkdown() {
return this.type === "code" && (this.mime === "text/markdown" || this.mime === "text/x-markdown" || this.mime === "text/x-gfm");
}
isTriliumScript() {
return this.mime.startsWith("application/javascript");
}

View File

@@ -24,6 +24,7 @@ import InfoDialog from "../widgets/dialogs/info.js";
import IncorrectCpuArchDialog from "../widgets/dialogs/incorrect_cpu_arch.js";
import CallToActionDialog from "../widgets/dialogs/call_to_action.jsx";
import PopupEditorDialog from "../widgets/dialogs/PopupEditor.jsx";
import PrintPreviewDialog from "../widgets/dialogs/print_preview.jsx";
import ToastContainer from "../widgets/Toast.jsx";
export function applyModals(rootContainer: RootContainer) {
@@ -51,6 +52,7 @@ export function applyModals(rootContainer: RootContainer) {
.child(<PromptDialog />)
.child(<IncorrectCpuArchDialog />)
.child(<PopupEditorDialog />)
.child(<PrintPreviewDialog />)
.child(<CallToActionDialog />)
.child(<ToastContainer />);
}

View File

@@ -39,6 +39,7 @@ export interface MenuCommandItem<T> {
title: string;
command?: T;
type?: string;
mime?: string;
/**
* The icon to display in the menu item.
*

View File

@@ -0,0 +1,101 @@
import type { ToggleInParentResponse } from "@triliumnext/commons";
import type FNote from "../entities/fnote.js";
import branchService from "../services/branches.js";
import { t } from "../services/i18n.js";
import server from "../services/server.js";
import toast from "../services/toast.js";
import contextMenu, { type ContextMenuEvent, type MenuItem } from "./context_menu.js";
const VISIBLE_LAUNCHER_PARENTS = ["_lbVisibleLaunchers", "_lbMobileVisibleLaunchers"];
function getVisibleLauncherBranch(launcherNote: FNote) {
return launcherNote.getParentBranches().find((b) => VISIBLE_LAUNCHER_PARENTS.includes(b.parentNoteId));
}
function getBookmarkBranch(launcherNote: FNote) {
return launcherNote.getParentBranches().find((b) => b.parentNoteId === "_lbBookmarks");
}
async function removeFromLaunchBar(launcherNote: FNote) {
const bookmarkBranch = getBookmarkBranch(launcherNote);
if (bookmarkBranch) {
// Individual bookmarks are represented via a branch under `_lbBookmarks`; removing them
// from the launch bar is the same as unbookmarking the note.
const resp = await server.put<ToggleInParentResponse>(
`notes/${launcherNote.noteId}/toggle-in-parent/_lbBookmarks/false`
);
if (!resp.success && resp.message) {
toast.showError(resp.message);
}
return;
}
const launcherBranch = getVisibleLauncherBranch(launcherNote);
if (!launcherBranch) return;
const isMobileLauncher = launcherBranch.parentNoteId === "_lbMobileVisibleLaunchers";
// Branch IDs in the hidden subtree follow the `${parentNoteId}_${noteId}` convention,
// so the branch linking `_lb(Mobile)?Root` to the "available" launchers root is predictable.
const targetBranchId = isMobileLauncher
? "_lbMobileRoot__lbMobileAvailableLaunchers"
: "_lbRoot__lbAvailableLaunchers";
await branchService.moveToParentNote([launcherBranch.branchId], targetBranchId);
}
export function canRemoveFromLaunchBar(launcherNote: FNote | null | undefined) {
if (!launcherNote) return false;
return !!(getVisibleLauncherBranch(launcherNote) || getBookmarkBranch(launcherNote));
}
export interface ShowLauncherContextMenuOptions<T extends string> {
/** Menu items specific to this launcher (e.g. "Open in new tab" for note-based launchers). They appear above the "Remove from launch bar" item. */
extraItems?: MenuItem<T>[];
/** Handler for the {@link extraItems}. The "Remove from launch bar" item is handled internally and will not be forwarded. */
onCommand?: (command: T | undefined) => void;
}
const REMOVE_COMMAND = "__removeFromLaunchBar__";
/**
* Displays the launch bar icon context menu. When the launcher can be removed (i.e. it is a direct
* child of the visible launchers root or of `_lbBookmarks`), a "Remove from launch bar" entry is
* appended. Extra items can be supplied to preserve launcher-specific actions (e.g. "Open in new tab").
*/
export async function showLauncherContextMenu<T extends string>(
launcherNote: FNote | null | undefined,
e: ContextMenuEvent,
options: ShowLauncherContextMenuOptions<T> = {}
) {
e.preventDefault();
const items = [...(options.extraItems ?? [])] as MenuItem<string>[];
if (canRemoveFromLaunchBar(launcherNote)) {
if (items.length > 0) {
items.push({ kind: "separator" });
}
items.push({
title: t("launcher_button_context_menu.remove_from_launch_bar"),
command: REMOVE_COMMAND,
uiIcon: "bx bx-x-circle"
});
}
if (items.length === 0) return;
contextMenu.show<string>({
x: e.pageX ?? 0,
y: e.pageY ?? 0,
items,
selectMenuItemHandler: ({ command }) => {
if (command === REMOVE_COMMAND) {
if (launcherNote) {
void removeFromLaunchBar(launcherNote);
}
return;
}
options.onCommand?.(command as T | undefined);
}
});
}

View File

@@ -288,7 +288,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
return items.filter((row) => row !== null) as MenuItem<TreeCommandNames>[];
}
async selectMenuItemHandler({ command, type, templateNoteId }: MenuCommandItem<TreeCommandNames>) {
async selectMenuItemHandler({ command, type, mime, templateNoteId }: MenuCommandItem<TreeCommandNames>) {
const notePath = treeService.getNotePath(this.node);
if (utils.isMobile()) {
@@ -305,6 +305,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
target: "after",
targetBranchId: this.node.data.branchId,
type,
mime,
isProtected,
templateNoteId
});
@@ -313,6 +314,7 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
noteCreateService.createNote(parentNotePath, {
type,
mime,
isProtected: this.node.data.isProtected,
templateNoteId
});

View File

@@ -2,18 +2,17 @@
:root {
--print-font-size: 11pt;
--ck-content-color-image-caption-background: transparent !important;
}
html,
body {
--print-font-family: var(--detail-font-family, sans-serif);
width: 100%;
height: 100%;
color: black;
}
@page {
margin: 2cm;
font-family: var(--print-font-family);
}
.note-list-widget.full-height,
@@ -26,6 +25,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 +159,4 @@ span[style] {
.page-break::after {
display: none !important;
}
/* #endregion */
/* #endregion */

View File

@@ -31,6 +31,21 @@ async function main() {
if (!noteId) return;
await import("./print.css");
// Browser printing relies on @page margins since there's no programmatic control.
// Electron uses printToPDF() margins instead, so we only inject this for the browser path.
if (!isElectron()) {
const style = document.createElement("style");
style.textContent = "@page { margin: 2cm; }";
document.head.appendChild(style);
}
// 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 +120,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 +148,7 @@ function CollectionRenderer({ note, onReady, onProgressChanged }: RendererProps)
media="print"
onReady={async (data: PrintReport) => {
await loadCustomCss(note);
await document.fonts.ready;
onReady(data);
}}
onProgressChanged={onProgressChanged}

View File

@@ -7,6 +7,10 @@ async function renderAttribute(attribute: FAttribute, renderIsInheritable: boole
const isInheritable = renderIsInheritable && attribute.isInheritable ? `(inheritable)` : "";
const $attr = $("<span>");
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) {

View File

@@ -1,6 +1,7 @@
import "./content_renderer.css";
import { normalizeMimeTypeForCKEditor, type TextRepresentationResponse } from "@triliumnext/commons";
import { normalizeMimeTypeForCKEditor, renderToHtml, type TextRepresentationResponse } from "@triliumnext/commons";
import DOMPurify from "dompurify";
import { h, render } from "preact";
import WheelZoom from 'vanilla-js-wheel-zoom';
@@ -8,7 +9,7 @@ import FAttachment from "../entities/fattachment.js";
import FNote from "../entities/fnote.js";
import imageContextMenuService from "../menus/image_context_menu.js";
import { t } from "../services/i18n.js";
import renderText from "./content_renderer_text.js";
import renderText, { postProcessRichContent, renderChildrenList } from "./content_renderer_text.js";
import renderDoc from "./doc_renderer.js";
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
import openService from "./open.js";
@@ -54,6 +55,8 @@ export async function getRenderedContent(this: {} | { ctx: string }, entity: FNo
if (type === "text" || type === "book") {
await renderText(entity, $renderedContent, options);
} else if (type === "markdown") {
await renderMarkdown(entity, $renderedContent, options);
} else if (type === "code") {
await renderCode(entity, $renderedContent);
} else if (["image", "canvas", "mindMap", "spreadsheet"].includes(type)) {
@@ -119,6 +122,31 @@ export async function getRenderedContent(this: {} | { ctx: string }, entity: FNo
};
}
/**
* Renders a markdown note by converting its source to CKEditor-compatible HTML,
* then running the same post-render pipeline as text notes (included notes,
* math, reference links, Mermaid, code highlight) so the preview matches what
* the user sees in the Markdown note type's preview pane.
*/
async function renderMarkdown(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>, options: RenderOptions) {
const blob = await note.getBlob();
const source = blob?.content ?? "";
if (!source.trim()) {
if (note instanceof FNote && !options.noChildrenList) {
await renderChildrenList($renderedContent, note, options.includeArchivedNotes ?? false);
}
return;
}
const html = renderToHtml(source, note.title, {
sanitize: (dirty) => DOMPurify.sanitize(dirty),
wikiLink: { formatHref: (id) => `#root/${id}` }
});
$renderedContent.append($('<div class="ck-content">').html(html));
await postProcessRichContent(note, $renderedContent, options);
}
/**
* Renders a code note, by displaying its content and applying syntax highlighting based on the selected MIME type.
*/
@@ -330,6 +358,8 @@ function getRenderingType(entity: FNote | FAttachment) {
if (type === "file" && mime === "application/pdf") {
type = "pdf";
} else if (type === "code" && entity instanceof FNote && entity.isMarkdown()) {
type = "markdown";
} else if ((type === "file" || type === "viewConfig") && mime && CODE_MIME_TYPES.has(mime) && !isIconPack) {
type = "code";
} else if (type === "file" && mime && mime.startsWith("audio/")) {

View File

@@ -15,37 +15,47 @@ export default async function renderText(note: FNote | FAttachment, $renderedCon
if (blob && !isHtmlEmpty(blob.content)) {
$renderedContent.append($('<div class="ck-content">').html(blob.content));
const seenNoteIds = options.seenNoteIds ?? new Set<string>();
seenNoteIds.add("noteId" in note ? note.noteId : note.attachmentId);
if (!options.noIncludedNotes) {
await renderIncludedNotes($renderedContent[0], seenNoteIds);
} else {
$renderedContent.find("section.include-note").remove();
}
if ($renderedContent.find("span.math-tex").length > 0) {
renderMathInElement($renderedContent[0], { trust: true });
}
const getNoteIdFromLink = (el: HTMLElement) => tree.getNoteIdFromUrl($(el).attr("href") || "");
const referenceLinks = $renderedContent.find<HTMLAnchorElement>("a.reference-link");
const noteIdsToPrefetch = referenceLinks.map((i, el) => getNoteIdFromLink(el));
await froca.getNotes(noteIdsToPrefetch);
for (const el of referenceLinks) {
const innerSpan = document.createElement("span");
await link.loadReferenceLinkTitle($(innerSpan), el.href);
el.replaceChildren(innerSpan);
}
await rewriteMermaidDiagramsInContainer($renderedContent[0] as HTMLDivElement);
await formatCodeBlocks($renderedContent);
await postProcessRichContent(note, $renderedContent, options);
} else if (note instanceof FNote && !options.noChildrenList) {
await renderChildrenList($renderedContent, note, options.includeArchivedNotes ?? false);
}
}
/**
* Apply the post-render passes that make CKEditor-compatible HTML fully
* interactive: expand `<section class="include-note">`, render inline math and
* Mermaid diagrams, rewrite reference-link titles, and highlight code blocks.
* Assumes the caller has already appended the HTML inside a `.ck-content` child
* of `$renderedContent`.
*/
export async function postProcessRichContent(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>, options: RenderOptions = {}) {
const seenNoteIds = options.seenNoteIds ?? new Set<string>();
seenNoteIds.add("noteId" in note ? note.noteId : note.attachmentId);
if (!options.noIncludedNotes) {
await renderIncludedNotes($renderedContent[0], seenNoteIds);
} else {
$renderedContent.find("section.include-note").remove();
}
if ($renderedContent.find("span.math-tex").length > 0) {
renderMathInElement($renderedContent[0], { trust: true });
}
const getNoteIdFromLink = (el: HTMLElement) => tree.getNoteIdFromUrl($(el).attr("href") || "");
const referenceLinks = $renderedContent.find<HTMLAnchorElement>("a.reference-link");
const noteIdsToPrefetch = referenceLinks.map((i, el) => getNoteIdFromLink(el));
await froca.getNotes(noteIdsToPrefetch);
await Promise.all(referenceLinks.toArray().map(async (el) => {
const innerSpan = document.createElement("span");
await link.loadReferenceLinkTitle($(innerSpan), el.getAttribute("href"));
el.replaceChildren(innerSpan);
}));
await rewriteMermaidDiagramsInContainer($renderedContent[0] as HTMLDivElement);
await formatCodeBlocks($renderedContent);
}
async function renderIncludedNotes(contentEl: HTMLElement, seenNoteIds: Set<string>) {
// TODO: Consider duplicating with server's share/content_renderer.ts.
const includeNoteEls = contentEl.querySelectorAll("section.include-note");
@@ -101,19 +111,107 @@ export async function rewriteMermaidDiagramsInContainer(container: HTMLDivElemen
}
}
/**
* Per-container cache of rendered mermaid SVG keyed by diagram source text.
* Populated after each successful render; reused on subsequent renders to
* avoid flicker when the preview HTML is regenerated (e.g. live markdown
* editing). Entries for diagrams no longer present in the container are
* evicted on each run so the cache can't grow unbounded.
*/
const mermaidSvgCache = new WeakMap<HTMLElement, Map<string, string>>();
/**
* Per-container, ordered snapshot of the most recently rendered SVGs. Used as
* a positional placeholder so edits to a diagram's source keep the previous
* SVG visible while the new one renders offscreen.
*/
const mermaidLastRenderedByPosition = new WeakMap<HTMLElement, string[]>();
export async function applyInlineMermaid(container: HTMLDivElement) {
// Initialize mermaid
const nodes = Array.from(container.querySelectorAll<HTMLElement>("div.mermaid-diagram"));
if (!nodes.length) {
mermaidLastRenderedByPosition.delete(container);
return;
}
let cache = mermaidSvgCache.get(container);
if (!cache) {
cache = new Map();
mermaidSvgCache.set(container, cache);
}
const lastRendered = mermaidLastRenderedByPosition.get(container) ?? [];
// Decide per node: exact cache hit → paint final SVG; source changed →
// paint the previous SVG (by position) as a placeholder and queue an
// offscreen re-render. This way the user keeps seeing the old diagram
// until mermaid has finished producing the new one.
const pending: Array<{ visible: HTMLElement; source: string }> = [];
const seenSources = new Set<string>();
for (const [ index, node ] of nodes.entries()) {
const source = (node.textContent ?? "").trim();
seenSources.add(source);
const cached = cache.get(source);
if (cached) {
node.innerHTML = cached;
node.setAttribute("data-processed", "true");
continue;
}
pending.push({ visible: node, source });
const placeholder = lastRendered[index];
if (placeholder) {
node.innerHTML = placeholder;
}
}
// Evict cache entries whose source is no longer present.
for (const key of [ ...cache.keys() ]) {
if (!seenSources.has(key)) cache.delete(key);
}
if (!pending.length) {
mermaidLastRenderedByPosition.set(container, nodes.map((n) => n.innerHTML));
return;
}
const mermaid = (await import("mermaid")).default;
mermaid.initialize(getMermaidConfig());
const nodes = Array.from(container.querySelectorAll<HTMLElement>("div.mermaid-diagram"));
// Render clones offscreen so the visible nodes keep showing the placeholder
// until the new SVG is ready. Keeps mermaid away from our placeholder SVG
// (which would otherwise confuse its text-based parser).
const offscreen = document.createElement("div");
offscreen.style.cssText = "position:absolute;left:-9999px;top:-9999px;width:0;height:0;overflow:hidden;visibility:hidden;";
document.body.appendChild(offscreen);
const pairs = pending.map(({ visible, source }) => {
const clone = document.createElement("div");
clone.className = "mermaid-diagram";
clone.textContent = source;
offscreen.appendChild(clone);
return { visible, clone, source };
});
try {
await mermaid.run({ nodes });
await mermaid.run({ nodes: pairs.map((p) => p.clone) });
for (const { visible, clone, source } of pairs) {
if (clone.getAttribute("data-processed") !== "true") continue;
const svg = clone.innerHTML;
visible.innerHTML = svg;
visible.setAttribute("data-processed", "true");
cache.set(source, svg);
}
} catch (e) {
console.log(e);
console.error(e);
} finally {
offscreen.remove();
}
mermaidLastRenderedByPosition.set(container, nodes.map((n) => n.innerHTML));
}
async function renderChildrenList($renderedContent: JQuery<HTMLElement>, note: FNote, includeArchivedNotes: boolean) {
export async function renderChildrenList($renderedContent: JQuery<HTMLElement>, note: FNote, includeArchivedNotes: boolean) {
let childNoteIds = note.getChildNoteIds();
if (!childNoteIds.length) {

View File

@@ -1,10 +1,10 @@
import { LOCALES } from "@triliumnext/commons";
import { findDuplicateJsonKeys, LOCALES } from "@triliumnext/commons";
import { readFileSync } from "fs";
import { join } from "path";
import { describe, expect, it } from "vitest";
describe("i18n", () => {
it("translations are valid JSON", () => {
it("translations are valid JSON with no duplicate keys", () => {
for (const locale of LOCALES) {
if (locale.contentOnly || locale.id === "en_rtl") {
continue;
@@ -14,6 +14,13 @@ describe("i18n", () => {
const translationFile = readFileSync(translationPath, { encoding: "utf-8" });
expect(() => JSON.parse(translationFile), `JSON error while parsing locale '${locale.id}' at "${translationPath}"`)
.not.toThrow();
const duplicates = findDuplicateJsonKeys(translationFile);
expect(
duplicates,
`Duplicate keys in locale '${locale.id}' at "${translationPath}":\n${
duplicates.map((d) => ` - "${d.key}" (line ${d.line})`).join("\n")}`
).toEqual([]);
}
});
});

View File

@@ -4,6 +4,8 @@ import appContext, { type NoteCommandData } from "../components/app_context.js";
import { openInCurrentNoteContext } from "../components/note_context.js";
import linkContextMenuService from "../menus/link_context_menu.js";
import froca from "./froca.js";
import { t } from "./i18n.js";
import { showError } from "./toast.js";
import treeService from "./tree.js";
import utils from "./utils.js";
@@ -58,6 +60,8 @@ export interface ViewScope {
*/
tocPreviousVisible?: boolean;
tocCollapsedHeadings?: Set<string>;
/** When set, scrolls to a bookmark anchor within the note after navigation. */
bookmark?: string;
}
interface CreateLinkOptions {
@@ -242,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;
@@ -333,15 +337,30 @@ export function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDo
if (openInNewTab || openInNewWindow || (isLeftClick && (withinEditLink || outsideOfCKEditor))) {
if (hrefLink.toLowerCase().startsWith("http") || hrefLink.startsWith("api/")) {
window.open(hrefLink, "_blank");
} else {
} else if (ALLOWED_PROTOCOLS.some((protocol) => hrefLink.toLowerCase().startsWith(`${protocol}:`))) {
// Enable protocols supported by CKEditor 5 to be clickable.
if (ALLOWED_PROTOCOLS.some((protocol) => hrefLink.toLowerCase().startsWith(`${protocol}:`))) {
if ( utils.isElectron()) {
const electron = utils.dynamicRequire("electron");
electron.shell.openExternal(hrefLink);
if (utils.isElectron()) {
const electron = utils.dynamicRequire("electron");
const reportLinkError = (e: unknown) => {
const message = e instanceof Error ? e.message : String(e);
logError(`Failed to open link '${hrefLink}': ${message}`);
showError(t("link.failed_to_open", { href: hrefLink, message }));
};
if (hrefLink.toLowerCase().startsWith("file:")) {
// shell.openExternal mishandles Unicode file:// URLs on Windows;
// convert to a filesystem path and use shell.openPath instead.
// Normalize file://c:/... (2 slashes — drive read as host) to file:///c:/...
const normalized = hrefLink.replace(/^file:\/\/(?=[a-zA-Z]:)/i, "file:///");
const { fileURLToPath } = utils.dynamicRequire("url");
electron.shell.openPath(fileURLToPath(normalized)).then((err: string) => {
if (err) reportLinkError(new Error(err));
}).catch(reportLinkError);
} else {
window.open(hrefLink, "_blank");
electron.shell.openExternal(hrefLink).catch(reportLinkError);
}
} else {
window.open(hrefLink, "_blank");
}
}
}
@@ -415,6 +434,13 @@ async function loadReferenceLinkTitle($el: JQuery<HTMLElement>, href: string | n
const title = await getReferenceLinkTitle(href);
$el.text(title);
if (viewScope?.bookmark) {
$el.append($("<small>").append(
$("<span>").addClass("bx bx-bookmark"),
document.createTextNode(viewScope.bookmark)
));
}
if (note) {
const icon = await getLinkIcon(noteId, viewScope.viewMode);
@@ -440,8 +466,8 @@ async function getReferenceLinkTitle(href: string) {
return attachment ? attachment.title : "[missing attachment]";
}
return note.title;
return note.title;
}
function getReferenceLinkTitleSync(href: string) {
@@ -464,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") {

View File

@@ -32,4 +32,9 @@ describe("Mermaid", () => {
`;
expect(postprocessMermaidSvg(before)).toBe(after);
});
it("replaces &nbsp; with numeric entity for valid XML", () => {
expect(postprocessMermaidSvg("<text>a&nbsp;b&nbsp;&nbsp;c</text>"))
.toBe("<text>a&#160;b&#160;&#160;c</text>");
});
});

View File

@@ -49,11 +49,15 @@ export async function loadElkIfNeeded(mermaid: Mermaid, mermaidContent: string)
* Processes the output of a Mermaid SVG render before it should be delivered to the user.
*
* <p>
* Currently this fixes <br> to <br/> which would otherwise cause an invalid XML.
* Currently this fixes <br> to <br/> and replaces named HTML entities like &nbsp; with their
* numeric equivalents, both of which would otherwise cause invalid XML when the SVG is saved
* as an attachment.
*
* @param svg the Mermaid SVG to process.
* @returns the processed SVG.
*/
export function postprocessMermaidSvg(svg: string) {
return svg.replaceAll(/<br\s*>/ig, "<br/>");
return svg
.replaceAll(/<br\s*>/ig, "<br/>")
.replaceAll(/&nbsp;/g, "&#160;");
}

View File

@@ -27,7 +27,7 @@ export const NOTE_TYPES: NoteTypeMapping[] = [
// The default note type (always the first item)
{ type: "text", mime: "text/html", title: t("note_types.text"), icon: "bx-note" },
{ type: "spreadsheet", mime: "application/json", title: t("note_types.spreadsheet"), icon: "bx-table", isBeta: true },
{ type: "spreadsheet", mime: "application/json", title: t("note_types.spreadsheet"), icon: "bx-table", isBeta: true, isNew: true },
// Text notes group
{ type: "book", mime: "", title: t("note_types.book"), icon: "bx-book" },
@@ -49,6 +49,7 @@ export const NOTE_TYPES: NoteTypeMapping[] = [
// Code notes
{ type: "code", mime: "text/plain", title: t("note_types.code"), icon: "bx-code" },
{ type: "code", mime: "text/x-markdown", title: t("note_types.markdown"), icon: "bxl-markdown", isNew: true },
// Reserved types (cannot be created by the user)
{ type: "contentWidget", mime: "", title: t("note_types.widget"), reserved: true },
@@ -100,6 +101,7 @@ function getBlankNoteTypes(command?: TreeCommandNames): MenuItem<TreeCommandName
title: nt.title,
command,
type: nt.type,
mime: nt.mime,
uiIcon: `bx ${nt.icon}`,
badges: []
};

View File

@@ -362,7 +362,8 @@ function copySelectionToClipboard() {
type dynamicRequireMappings = {
"@electron/remote": typeof import("@electron/remote"),
"electron": typeof import("electron"),
"child_process": typeof import("child_process")
"child_process": typeof import("child_process"),
"url": typeof import("url")
};
export function dynamicRequire<T extends keyof dynamicRequireMappings>(moduleName: T): Awaited<dynamicRequireMappings[T]>{

View File

@@ -835,6 +835,7 @@ table.promoted-attributes-in-tooltip th {
text-align: start;
color: var(--main-text-color) !important;
max-width: 500px;
white-space: pre-line;
box-shadow: 10px 10px 93px -25px #aaaaaa;
}
@@ -960,15 +961,19 @@ table.promoted-attributes-in-tooltip th {
background-color: var(--active-item-background-color);
}
.help-button {
.help-button,
.custom-title-bar-button {
float: inline-end;
background: none;
font-weight: 900;
color: orange;
border: 0;
cursor: pointer;
}
.help-button {
color: orange;
}
.multiplicity {
font-size: 1.3em;
}
@@ -1147,11 +1152,90 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
padding: 0.5rem 1rem 0.5rem 1rem !important; /* make modal header padding slightly smaller */
}
.modal-header .help-button {
.modal-header .help-button,
.modal-header .custom-title-bar-button {
padding: 6px;
margin: 0 12px;
}
.modal-content-with-sidebar {
flex-direction: row !important;
}
.modal-content-with-sidebar > .modal-sidebar {
display: flex;
flex-direction: column;
border-right: 1px solid var(--main-border-color);
flex-shrink: 0;
min-height: 0;
}
.modal-content-with-sidebar .modal-sidebar-header {
padding: 0.75rem 1rem;
flex-shrink: 0;
text-align: center;
border-bottom: 1px solid var(--main-border-color);
}
.modal-content-with-sidebar .modal-sidebar-header h5 {
margin: 0;
font-size: 1em;
}
.modal-content-with-sidebar > .modal-main > .modal-header > .modal-title {
visibility: hidden;
flex-grow: 1;
width: 0;
padding: 0;
margin: 0;
overflow: hidden;
}
.modal-content-with-sidebar > .modal-main > .modal-header {
flex-wrap: nowrap;
}
.modal-content-with-sidebar > .modal-main {
display: flex;
flex-direction: column;
flex-grow: 1;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.modal-content-with-sidebar > .modal-main > .modal-body {
overflow: auto;
flex-grow: 1;
min-height: 0;
}
body.mobile .modal-content-with-sidebar {
flex-direction: column !important;
}
body.mobile .modal-content-with-sidebar > .modal-sidebar {
border-right: none;
border-bottom: 1px solid var(--main-border-color);
height: 30vh;
flex-shrink: 0;
overflow: hidden;
order: 1;
}
body.mobile .modal-content-with-sidebar > .modal-main {
order: 0;
}
body.mobile .modal-content-with-sidebar .modal-sidebar-header {
display: none;
}
body.mobile .modal-content-with-sidebar > .modal-main > .modal-header > .modal-title {
visibility: visible;
width: auto;
}
.ck-mentions .ck-button {
font-size: var(--detail-font-size) !important;
padding: 5px;
@@ -1666,6 +1750,22 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
display: flex;
}
body.mobile .modal-dialog.modal-dialog-full-page-on-mobile {
width: 100%;
height: 100%;
max-height: unset;
max-width: unset;
.modal-content {
border-radius: 0;
border: 0;
.modal-body {
overflow: scroll;
}
}
}
body.mobile .modal-content {
overflow-y: auto;
border-radius: var(--bs-modal-border-radius) var(--bs-modal-border-radius) 0 0;
@@ -1680,7 +1780,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
display: inline !important;
}
body.mobile .options-section table {
body.mobile .options-section-card table {
word-break: break-all;
}
@@ -1860,12 +1960,12 @@ button.close:hover {
margin-bottom: 15px;
}
.options-section h5 {
.options-section-card h5 {
margin-top: 10px;
margin-bottom: 10px;
}
.options-section input[type="number"] {
.options-section-card input[type="number"] {
/* overriding settings from .form-control */
width: 10em !important;
flex-grow: 0 !important;
@@ -2701,3 +2801,7 @@ iframe.print-iframe {
line-height: 1.4;
white-space: pre-wrap;
}
.ck-content pre code {
tab-size: var(--code-block-tab-width, 4);
}

View File

@@ -269,9 +269,9 @@
--timeline-connector-active-color: #ddd;
--timeline-connector-hover-blend-mode: multiply;
--tooltip-background-color: rgba(255, 255, 255, 0.85);
--tooltip-foreground-color: #000000ba;
--tooltip-shadow-color: rgba(0, 0, 0, 0.15);
--tooltip-background-color: rgba(0, 0, 0, 0.818);
--tooltip-foreground-color: #ffffffeb;
--tooltip-shadow-color: rgba(0, 0, 0, 0.2);
--help-background-color: #fffc;
--help-card-background: var(--card-background-color);

View File

@@ -21,6 +21,20 @@ button.ck.ck-button:is(.ck-button-action, .ck-button-save, .ck-button-cancel, .c
&.dropdown-toggle-split {
min-width: unset;
}
.btn-group > & {
border-radius: 0;
}
.btn-group > &:first-child {
border-start-start-radius: 6px;
border-end-start-radius: 6px;
}
.btn-group > &:last-child {
border-start-end-radius: 6px;
border-end-end-radius: 6px;
}
}
button.btn.btn-primary:hover,
@@ -117,11 +131,16 @@ button.tn-low-profile:hover {
color: var(--icon-button-color);
}
:root .btn-group .icon-action:last-child {
:root .btn-group .icon-action:not(:first-child) {
border-top-left-radius: unset !important;
border-bottom-left-radius: unset !important;
}
:root .btn-group .icon-action:not(:last-child) {
border-top-right-radius: unset !important;
border-bottom-right-radius: unset !important;
}
.btn-group .tn-tool-button + .tn-tool-button {
margin-inline-start: 4px !important;
}

View File

@@ -635,6 +635,7 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
inset-inline-end: 0.35em;
}
.ck-content h1,
.ck-content h2,
.ck-content h3,
.ck-content h4,
@@ -694,7 +695,7 @@ html .note-detail-editable-text :not(figure, .include-note, hr):first-child {
outline: none;
box-shadow: 0 0 0 2px var(--link-selection-outline-color);
background: var(--link-hover-background);
}
}
/* Reference link */
@@ -713,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
*/

View File

@@ -186,12 +186,7 @@ body.experimental-feature-new-layout .note-detail-content-widget-content.options
}
.options-section:not(.tn-no-card) {
margin-bottom: calc(var(--options-title-offset) + 26px) !important;
box-shadow: var(--card-box-shadow);
border: 1px solid var(--card-border-color) !important;
border-radius: 8px;
background: var(--card-background-color);
padding: var(--options-card-padding);
margin-bottom: 26px !important;
}
body.desktop .options-section:not(.tn-no-card) {
@@ -199,40 +194,70 @@ body.desktop .options-section:not(.tn-no-card) {
max-width: var(--options-card-max-width);
}
.options-section-card {
box-shadow: var(--card-box-shadow);
border: 1px solid var(--card-border-color);
border-radius: 8px;
background: var(--card-background-color);
padding: var(--options-card-padding);
}
.note-detail-content-widget-content.options {
--default-padding: 15px;
padding-top: calc(var(--default-padding) + var(--options-title-offset) + var(--options-title-font-size));
padding-top: var(--default-padding);
padding-bottom: var(--default-padding);
}
.options-section:not(.tn-no-card) h4,
.options-section:not(.tn-no-card) h5 {
.options-section:not(.tn-no-card) h4 {
text-transform: uppercase;
letter-spacing: .4pt;
}
.options-section:not(.tn-no-card) h4 {
font-size: var(--options-title-font-size);
font-weight: 600;
color: var(--launcher-pane-text-color);
margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important;
margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important;
margin-inline-start: calc(-1 * var(--options-card-padding));
margin-top: 0;
margin-bottom: var(--options-title-offset);
}
.options-section:not(.tn-no-card) h5 {
.options-section:not(.tn-no-card) .options-section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.options-section:not(.tn-no-card) .options-section-header h4 {
margin: 0;
margin-bottom: 0;
}
.options-section:not(.tn-no-card) .options-section-header .icon-action {
margin-inline-start: auto;
}
.options-section-description {
color: var(--muted-text-color);
font-size: 13px;
margin-top: 0;
margin-bottom: 16px;
}
.options-section-card h5 {
text-transform: uppercase;
letter-spacing: .4pt;
font-size: var(--options-title-font-size);
font-weight: bold;
margin-top: 1em !important;
margin-bottom: unset !important;
}
.options-section:not(.tn-no-card) h5:first-of-type {
.options-section-card h5:first-of-type {
margin-top: unset !important;
}
.options-section hr {
.options-section-card hr {
--bs-border-width: 2px;
margin-inline-start: calc(var(--options-card-padding) * -1);
@@ -241,27 +266,26 @@ body.desktop .options-section:not(.tn-no-card) {
color: var(--root-background);
}
.options-section p:last-of-type:not(:first-of-type),
.options-section h4 + p:last-child,
.options-section .existing-anonymized-databases {
.options-section-card p:last-of-type:not(:first-of-type),
.options-section-card .existing-anonymized-databases {
margin-bottom: 0;
}
.options-section .form-group {
.options-section-card .form-group {
margin-bottom: 1em;
}
.options-section .form-group:last-child {
.options-section-card .form-group:last-child {
margin-bottom: 0;
}
.options-section ul {
.options-section-card ul {
margin: 0;
padding: 0;
margin-bottom: 1em;
}
.options-section label:not(.tn-checkbox):not(.tn-radio) {
.options-section-card label:not(.tn-checkbox):not(.tn-radio) {
margin-bottom: 6px;
}
@@ -275,7 +299,7 @@ nav.options-section-tabs .nav-tabs {
border-bottom: 0;
}
nav.options-section-tabs + .options-section {
nav.options-section-tabs + .options-section .options-section-card {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
@@ -329,3 +353,9 @@ nav.options-section-tabs + .options-section {
.etapi-options-section div {
height: auto !important;
}
/* BACKUP */
.options-section-card table a {
color: inherit;
}

View File

@@ -1,13 +1,6 @@
{
"about": {
"title": "حول تريليوم للملاحظات",
"homepage": "الصفحة الرئيسية:",
"app_version": "اصدار التطبيق:",
"sync_version": "اصدار المزامنه:",
"build_date": "تاريخ الانشاء:",
"build_revision": "مراجعة الاصدار:",
"data_directory": "مجلد البيانات:",
"db_version": "اصدار قاعدة البيانات:"
"data_directory": "مجلد البيانات:"
},
"toast": {
"critical-error": {
@@ -373,7 +366,6 @@
"theme_defined": "النسق المحدد",
"main_font": "الخط الرئيسي",
"font_family": "عائلة الخطوط",
"reload_frontend": "اعادة تحميل الواجهة",
"generic-fonts": "الخطوط العامة",
"sans-serif": "خطوط بدون زوائد",
"system-default": "الاعداد الافتراضي للنظام",
@@ -485,26 +477,6 @@
"start_button": "بدء جلسة محمية",
"help_title": "مساعدة حول الملاحظات المحمية"
},
"revisions": {
"delete_button": "حذف",
"download_button": "تنزيل",
"restore_button": "أستعادة",
"note_revisions": "مراجعات الملاحظة",
"diff_on": "عرض الفروقات",
"diff_off": "عرض المحتوى",
"file_size": "حجم الملف:",
"mime": "MIME: ",
"delete_all_button": "حذف كل المراجعات",
"settings": "اعدادات مراجعة الملاحظة",
"diff_not_available": "المقارنة غير متوفرة.",
"help_title": "مساعدة حول مراجعات الملاحظة",
"diff_off_hint": "انقر لعرض محتويات الملاحظة",
"revisions_deleted": "تم حذف جميع نسخ المراجعات للملاحظة.",
"revision_restored": "تم استعادة نسخ المراجعة للملاحظة.",
"revision_deleted": "تم حذف مراجعة الملاحظة.",
"snapshot_interval": "فاصل زمني لحفظ لقطات اصدارات المراجعة: {{seconds}}",
"maximum_revisions": "حد عدد لقطات اصدارات الملاحظة: {{number}}"
},
"sort_child_notes": {
"title": "عنوان",
"ascending": "تصاعدي",
@@ -662,7 +634,6 @@
"default_shortcuts": "اختصارات افتراضية"
},
"sync_2": {
"note": "ملاحظة",
"save": "حفظ",
"help": "المساعدة",
"config_title": "تهيئة المزامنة",

View File

@@ -1,10 +1,4 @@
{
"about": {
"title": "Sobre Trilium Notes",
"homepage": "Pàgina principal:",
"app_version": "Versió de l'aplicació:",
"db_version": "Versió de la base de dades:"
},
"add_link": {
"note": "Nota"
},
@@ -59,12 +53,6 @@
"recent_changes": {
"undelete_link": "recuperar"
},
"revisions": {
"restore_button": "Restaura",
"delete_button": "Suprimeix",
"download_button": "Descarrega",
"mime": "MIME: "
},
"sort_child_notes": {
"title": "títol",
"ascending": "ascendent",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "关于 Trilium Notes",
"homepage": "项目主页:",
"app_version": "应用版本:",
"db_version": "数据库版本:",
"sync_version": "同步版本:",
"build_date": "编译日期:",
"build_revision": "编译版本:",
"data_directory": "数据目录:"
},
"toast": {
@@ -41,7 +34,9 @@
"link_title_mirrors": "链接标题跟随笔记标题变化",
"link_title_arbitrary": "链接标题可随意修改",
"link_title": "链接标题",
"button_add_link": "添加链接"
"button_add_link": "添加链接",
"anchor": "锚点(可选)",
"anchor_none": "无(笔记链接)"
},
"branch_prefix": {
"edit_branch_prefix": "编辑分支前缀",
@@ -90,12 +85,20 @@
"delete_notes": {
"close": "关闭",
"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}})",
"cancel": "取消"
"broken_relations_to_be_deleted": "断开的关联({{relationCount}}",
"cancel": "取消",
"title": "删除笔记",
"delete": "删除",
"clones_label": "克隆",
"delete_clones_description_other": "同时删除 {{count}} 个其他克隆。此操作可在最近的更改中撤销。",
"erase_notes_label": "永久擦除",
"table_note_with_relation": "关联笔记",
"table_relation": "关联",
"table_points_to": "指向(已删除)"
},
"export": {
"export_note_title": "导出笔记",
@@ -206,7 +209,8 @@
"box_size_small": "小型 (显示大约10行)",
"box_size_medium": "中型 (显示大约30行)",
"box_size_full": "完整显示(完整文本框)",
"button_include": "包含笔记"
"button_include": "包含笔记",
"box_size_expandable": "可展开(默认折叠)"
},
"info": {
"modalTitle": "信息消息",
@@ -267,33 +271,6 @@
"undelete_link": "恢复删除",
"confirm_undelete": "您确定要恢复此笔记及其子笔记吗?"
},
"revisions": {
"note_revisions": "笔记历史版本",
"delete_all_revisions": "删除此笔记的所有修订版本",
"delete_all_button": "删除所有修订版本",
"help_title": "关于笔记修订版本的帮助",
"confirm_delete_all": "您是否要删除此笔记的所有修订版本?",
"no_revisions": "此笔记暂无修订版本...",
"restore_button": "恢复",
"confirm_restore": "您是否要恢复此修订版本?这将使用此修订版本覆盖笔记的当前标题和内容。",
"delete_button": "删除",
"confirm_delete": "您是否要删除此修订版本?",
"revisions_deleted": "笔记修订版本已删除。",
"revision_restored": "笔记修订版本已恢复。",
"revision_deleted": "笔记修订版本已删除。",
"snapshot_interval": "笔记快照保存间隔: {{seconds}}秒。",
"maximum_revisions": "当前笔记的最大历史数量: {{number}}。",
"settings": "笔记修订设置",
"download_button": "下载",
"mime": "MIME 类型: ",
"file_size": "文件大小:",
"preview_not_available": "无法预览此类型的笔记。",
"diff_on": "显示差异",
"diff_off": "显示内容",
"diff_on_hint": "点击以显示笔记源代码差异",
"diff_off_hint": "点击以显示笔记内容",
"diff_not_available": "差异不可用。"
},
"sort_child_notes": {
"sort_children_by": "按...排序子笔记",
"sorting_criteria": "排序条件",
@@ -444,7 +421,9 @@
"print_landscape": "导出为 PDF 时,将页面方向更改为横向而不是纵向。",
"print_page_size": "导出为 PDF 时,更改页面大小。支持的值:<code>A0</code>、<code>A1</code>、<code>A2</code>、<code>A3</code>、<code>A4</code>、<code>A5</code>、<code>A6</code>、<code>Legal</code>、<code>Letter</code>、<code>Tabloid</code>、<code>Ledger</code>。",
"color_type": "颜色",
"textarea": "多行文本"
"textarea": "多行文本",
"print_scale": "导出为 PDF 时,更改渲染内容的比例。取值范围从 0.1 (10%) 到 2 (200%),默认值为 1 (100%)。",
"print_margins": "导出为 PDF 时,设置页面边距。可以使用 <code>default</code>、<code>none</code>、<code>minimum</code> 或以毫米为单位的自定义值,例如 <code>top,right,bottom,left</code>。"
},
"attribute_editor": {
"help_text_body1": "要添加标签,只需输入例如 <code>#rock</code> 或者如果您还想添加值,则例如 <code>#year = 2020</code>",
@@ -707,7 +686,12 @@
"export_as_image": "导出为图像",
"export_as_image_png": "PNG栅格",
"export_as_image_svg": "SVG矢量图",
"view_ocr_text": "查看 OCR 文本"
"view_ocr_text": "查看 OCR 文本",
"word_wrap": "自动换行",
"word_wrap_auto": "自动",
"word_wrap_auto_description": "遵循全局设置",
"word_wrap_on": "开启",
"word_wrap_off": "关闭"
},
"onclick_button": {
"no_click_handler": "按钮组件'{{componentId}}'没有定义点击处理程序"
@@ -1074,15 +1058,17 @@
"title": "检查一致性",
"find_and_fix_button": "查找并修复一致性问题",
"finding_and_fixing_message": "正在查找并修复一致性问题...",
"issues_fixed_message": "一致性问题应该已被修复。"
"issues_fixed_message": "一致性问题应该已被修复。",
"find_and_fix_label": "查找并修复一致性问题",
"find_and_fix_description": "扫描并自动修复数据库中的任何数据一致性问题。"
},
"database_anonymization": {
"title": "数据库匿名化",
"full_anonymization": "完全匿名化",
"full_anonymization_description": "此操作将创建一个新的数据库副本并进行匿名化处理(删除所有笔记内容,仅保留结构和一些非敏感元数据),用来分享到网上做调试而不用担心泄漏您的个人资料。",
"full_anonymization_description": "创建数据库副本,移除所有笔记内容,仅保留数据库结构和非敏感元数据。在调试问题时,可安全地在线共享。",
"save_fully_anonymized_database": "保存完全匿名化的数据库",
"light_anonymization": "轻度匿名化",
"light_anonymization_description": "此操作将创建一个新的数据库副本,并对其进行轻度匿名化处理——仅删除所有笔记内容,但保留标题属性。此外,自定义 JS 前端/后端脚本笔记和自定义小部件将保留。这提供更多上下文以调试问题。",
"light_anonymization_description": "创建一个副本,其中移除笔记内容,但保留标题属性和自定义脚本/小部件。这有助于提供更多调试信息。",
"choose_anonymization": "您可以自行决定是提供完全匿名化还是轻度匿名化的数据库。即使是完全匿名化的数据库也非常有用,但在某些情况下,轻度匿名化的数据库可以加快错误识别和修复的过程。",
"save_lightly_anonymized_database": "保存轻度匿名化的数据库",
"existing_anonymized_databases": "现有的匿名化数据库",
@@ -1091,15 +1077,17 @@
"error_creating_anonymized_database": "无法创建匿名化数据库,请检查后端日志以获取详细信息",
"successfully_created_fully_anonymized_database": "成功创建完全匿名化的数据库,路径为 {{anonymizedFilePath}}",
"successfully_created_lightly_anonymized_database": "成功创建轻度匿名化的数据库,路径为 {{anonymizedFilePath}}",
"no_anonymized_database_yet": "尚无匿名化数据库。"
"no_anonymized_database_yet": "尚无匿名化数据库。",
"description": "创建数据库的匿名副本,以便在调试问题时与开发人员共享,而不会泄露个人数据。"
},
"database_integrity_check": {
"title": "数据库完整性检查",
"description": "检查 SQLite 数据库是否损坏。根据数据库的大小,可能会需要一些时间。",
"check_button": "检查数据库完整性",
"checking_integrity": "正在检查数据库完整性...",
"integrity_check_succeeded": "完整性检查成功 - 未发现问题。",
"integrity_check_failed": "完整性检查失败: {{results}}"
"integrity_check_failed": "完整性检查失败: {{results}}",
"check_integrity_label": "检查数据库完整性",
"check_integrity_description": "验证 SQLite 数据库是否已损坏。"
},
"sync": {
"title": "同步",
@@ -1109,28 +1097,31 @@
"filling_entity_changes": "正在填充实体变更行...",
"sync_rows_filled_successfully": "同步行填充成功",
"finished-successfully": "同步已完成。",
"failed": "同步失败:{{message}}"
"failed": "同步失败:{{message}}",
"force_full_sync_label": "强制全量同步",
"force_full_sync_description": "触发与同步服务器的全量同步,重新上传所有更改。",
"fill_entity_changes_description": "重建实体变更记录。如果同步过程中缺少某些变更,请使用此功能。",
"fill_entity_changes_label": "填充实体变更"
},
"vacuum_database": {
"title": "数据库清理",
"description": "这会重建数据库,通常会减少占用空间,不会删除数据。",
"button_text": "清理数据库",
"vacuuming_database": "正在清理数据库...",
"database_vacuumed": "数据库已清理"
"database_vacuumed": "数据库已清理",
"vacuum_label": "数据库清理",
"vacuum_description": "重建数据库以减小文件大小。数据不会发生任何变化。"
},
"fonts": {
"theme_defined": "跟随主题",
"fonts": "字体",
"main_font": "字体",
"main_font": "界面字体",
"font_family": "字体系列",
"size": "大小",
"note_tree_font": "笔记树字体",
"note_detail_font": "笔记详情字体",
"monospace_font": "等宽(代码)字体",
"note_tree_and_detail_font_sizing": "请注意,笔记树字体和详细字体的大小相对于主字体大小设置。",
"not_all_fonts_available": "并非所有列出的字体都可能在您的系统上可用。",
"apply_font_changes": "要应用字体更改,请点击",
"reload_frontend": "重载前端",
"note_detail_font": "文档字体",
"monospace_font": "等宽字体",
"not_all_fonts_available": "并非所有列出的字体都可能在您的系统上可用",
"generic-fonts": "通用字体",
"sans-serif-system-fonts": "无衬线系统字体",
"serif-system-fonts": "衬线系统字体",
@@ -1139,7 +1130,12 @@
"serif": "衬线",
"sans-serif": "无衬线",
"monospace": "等宽",
"system-default": "系统默认"
"system-default": "系统默认",
"custom_fonts": "使用自定义字体",
"preview": "预览",
"monospace_font_description": "用于代码注释和代码块",
"size_relative_to_general": "大小相对于一般字体大小",
"apply_changes": "重新加载以应用更改"
},
"max_content_width": {
"title": "内容宽度",
@@ -1159,20 +1155,23 @@
"edited_notes_message": "日记笔记自动打开编辑过的笔记功能区标签页"
},
"theme": {
"title": "主题",
"theme_label": "主题",
"title": "用户界面",
"theme_label": "应用主题",
"override_theme_fonts_label": "覆盖主题字体",
"triliumnext": "Trilium跟随系统颜色方案",
"triliumnext-light": "Trilium浅色",
"triliumnext-dark": "Trilium深色",
"triliumnext": "跟随系统颜色方案",
"triliumnext-light": "浅色",
"triliumnext-dark": "深色",
"layout": "布局",
"layout-vertical-title": "垂直",
"layout-horizontal-title": "水平",
"layout-vertical-description": "启动栏位于左侧(默认)",
"layout-horizontal-description": "启动栏位于标签页栏下方,标签页栏现在是全宽的。",
"auto_theme": "传统(跟随系统配色方案",
"light_theme": "传统(浅色",
"dark_theme": "传统(深色"
"auto_theme": "跟随系统配色方案",
"light_theme": "浅色",
"dark_theme": "深色",
"modern_themes": "现代",
"legacy_themes": "传统",
"custom_themes": "自定义"
},
"zoom_factor": {
"title": "缩放系数(仅桌面客户端有效)",
@@ -1181,7 +1180,7 @@
"code_auto_read_only_size": {
"title": "自动只读大小",
"description": "自动只读大小是指笔记超过设置的大小后自动设置为只读模式(为性能考虑)。",
"label": "自动只读大小(代码笔记)",
"label": "自动只读大小",
"unit": "字符"
},
"code_mime_types": {
@@ -1224,24 +1223,27 @@
"batch_ocr_error": "批量处理过程中出错:{{error}}"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "附件清理超时",
"attachment_auto_deletion_description": "如果附件在一段时间后不再被笔记引用,它们将自动被删除(并被清理)。",
"erase_attachments_after": "在此时间后删除未使用的附件:",
"manual_erasing_description": "您还可以手动触发清理(而不考虑上述定义的超时时间):",
"erase_unused_attachments_now": "立即清理未使用的附件笔记",
"unused_attachments_erased": "未使用的附件已被删除。"
"attachment_erasure_timeout": "未使用的附件",
"erase_attachments_after": "在此时间后清理未使用的附件",
"manual_erasing_description": "手动触发清理,忽略上述超时。",
"erase_unused_attachments_now": "立即清理未使用的附件",
"unused_attachments_erased": "未使用的附件已被清理。",
"description": "不再被任何笔记引用的附件被视为未使用,可以在一段时间后自动清理。",
"erase_attachments_after_description": "未使用附件被永久清理前的时间。"
},
"network_connections": {
"network_connections_title": "网络连接",
"check_for_updates": "自动检查更新"
"network_connections_title": "网络",
"check_for_updates": "自动检查更新",
"check_for_updates_description": "在 GitHub 上检查新版本,并在可用时在全局菜单中显示通知。"
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "笔记清理超时",
"note_erasure_description": "被删除的笔记(以及属性、修订历史等)最初仅被标记为“删除”,可以从“最近修改”对话框中恢复它们。经过一段时间后,已删除的笔记会被“清理”,这意味着它们的内容将无法恢复。此设置允许您配置从删除到清除笔记之间的时间长度。",
"erase_notes_after": "在此时间后删除笔记:",
"manual_erasing_description": "您还可以手动触发清理(不考虑上述定义的超时):",
"note_erasure_timeout_title": "已删除的笔记",
"erase_notes_after": "在此时间后清理笔记",
"manual_erasing_description": "手动触发清理,忽略上述超时。",
"erase_deleted_notes_now": "立即清理已删除的笔记",
"deleted_notes_erased": "已删除的笔记已被清理。"
"deleted_notes_erased": "已删除的笔记已被清理。",
"description": "删除的笔记最初只是被标记为已删除,可以从“最近的笔记”中恢复。经过一段时间后,它们将被永久清理。",
"erase_notes_after_description": "删除的笔记被永久清理之前的时间。"
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "笔记修订快照间隔",
@@ -1316,7 +1318,6 @@
"first-week-contains-first-thursday": "第一周包含一年的第一个周四",
"first-week-has-minimum-days": "第一周有最小天数",
"min-days-in-first-week": "第一周的最小天数",
"first-week-info": "第一周包含一年的第一个周四,基于 <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> 标准。",
"first-week-warning": "更改第一周选项可能会导致与现有周笔记重复,已创建的周笔记将不会相应更新。",
"formatting-locale": "日期和数字格式",
"tuesday": "周二",
@@ -1453,9 +1454,6 @@
"server_address": "服务器实例地址",
"timeout": "同步超时(单位:毫秒)",
"proxy_label": "同步代理服务器(可选)",
"note": "注意",
"note_description": "代理设置留空则使用系统代理(仅桌面客户端有效)。",
"special_value_description": "另一个特殊值是 <code>noproxy</code>,它强制忽略系统代理并遵守 <code>NODE_TLS_REJECT_UNAUTHORIZED</code>。",
"save": "保存",
"help": "帮助",
"test_title": "同步测试",
@@ -1867,7 +1865,9 @@
}
},
"code-editor-options": {
"title": "编辑器"
"title": "编辑器",
"tab_width": "制表符宽度",
"tab_width_unit": "空格"
},
"custom_date_time_format": {
"title": "自定义日期/时间格式",
@@ -2026,11 +2026,11 @@
},
"ui-performance": {
"title": "性能",
"enable-motion": "启用过渡和动画",
"enable-shadows": "启用阴影",
"enable-backdrop-effects": "启用菜单、弹窗和面板的背景效果",
"enable-smooth-scroll": "启用平滑滚动",
"app-restart-required": "(需重启程序以应用更改)"
"enable-motion": "过渡和动画",
"enable-shadows": "阴影",
"enable-backdrop-effects": "菜单、弹窗和面板的背景效果",
"enable-smooth-scroll": "平滑滚动",
"app-restart-required": "需要重启应用"
},
"pagination": {
"total_notes": "{{count}} 篇笔记",
@@ -2326,5 +2326,38 @@
"no_providers_configured": "尚未配置任何供应商。",
"provider_name": "名称",
"provider_type": "供应商"
},
"revisions": {
"note_revisions": "笔记修订",
"delete_all_revisions": "删除此笔记的所有修订版本",
"delete_all_button": "删除所有修订版本",
"help_title": "关于笔记修订的帮助",
"confirm_delete_all": "是否要删除此笔记的所有修订版本?",
"no_revisions": "这篇笔记目前还没有修改……",
"restore_button": "恢复",
"diff_on": "显示差异",
"diff_off": "显示内容",
"diff_on_hint": "点击显示笔记来源差异",
"diff_off_hint": "点击显示笔记内容",
"diff_not_available": "差异数据不可用。",
"confirm_restore": "是否恢复此版本?这将用此版本覆盖笔记的当前标题和内容。",
"delete_button": "删除",
"confirm_delete": "您要删除此修订吗?",
"revisions_deleted": "笔记修订已被删除。",
"revision_restored": "笔记修订已恢复。",
"revision_deleted": "笔记修订已删除。",
"snapshot_interval": "笔记修订快照间隔:{{seconds}}秒。",
"maximum_revisions": "笔记修订快照限制:{{number}}。",
"settings": "笔记修订设置",
"download_button": "下载",
"mime": "MIME 类型: ",
"file_size": "文件大小:",
"preview_not_available": "无法预览此类型的笔记。"
},
"database": {
"title": "数据库"
},
"auto_link_attribute_list": {
"title": "系统属性"
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "O Trilium Notes",
"homepage": "Domovská stránka:",
"app_version": "Verze aplikace:",
"db_version": "Verze DB:",
"sync_version": "Verze synchronizace:",
"build_date": "Datum sestavení:",
"build_revision": "Revize sestavení:",
"data_directory": "Datový adresář:"
},
"toast": {
@@ -273,33 +266,6 @@
"undelete_link": "obnovit",
"confirm_undelete": "Chcete obnovit tuto poznámku a její podpoznámky?"
},
"revisions": {
"note_revisions": "Revize poznámek",
"delete_all_revisions": "Smazat všechny revize této poznámky",
"delete_all_button": "Smazat všechny revize",
"help_title": "Nápověda k revizím poznámek",
"confirm_delete_all": "Chcete smazat všechny revize této poznámky?",
"no_revisions": "Ještě nejsou žádné revize pro tuto poznámku...",
"restore_button": "Obnovit",
"diff_on": "Zobrazit rozdíly",
"diff_off": "Zobrazit obsah",
"diff_on_hint": "Klikněte pro zobrazení rozdílů zdrojového kódu poznámky",
"diff_off_hint": "Klikněte pro zobrazení obsahu poznámky",
"diff_not_available": "Rozdíly nejsou dostupné.",
"confirm_restore": "Chcete obnovit tuto revizi? Tím se přepíše aktuální název a obsah poznámky s touto revizí.",
"delete_button": "Smazat",
"confirm_delete": "Chcete smazat tuto revizi?",
"revisions_deleted": "Revize poznámky byly smazány.",
"revision_restored": "Revize poznámky byla obnovena.",
"revision_deleted": "Revize poznámky byla smazána.",
"snapshot_interval": "Interval snímků revizí poznámky: {{seconds}}s.",
"maximum_revisions": "Limit snímků revizí poznámky: {{number}}.",
"settings": "Nastavení revizí poznámky",
"download_button": "Stáhnout",
"mime": "MIME: ",
"file_size": "Velikost souboru:",
"preview_not_available": "Náhled není dostupný pro tento typ poznámky."
},
"sort_child_notes": {
"sort_children_by": "Seřadit dceřiné podle...",
"sorting_criteria": "Kritéria řazení",
@@ -1130,7 +1096,6 @@
},
"database_integrity_check": {
"title": "Kontrola integrity databáze",
"description": "Toto zkontroluje, zda databáze není poškozena na úrovni SQLite. Může to chvíli trvat v závislosti na velikosti databáze.",
"check_button": "Zkontrolovat integritu databáze",
"checking_integrity": "Probíhá kontrola integrity databáze...",
"integrity_check_succeeded": "Kontrola integrity proběhla úspěšně - nebyly nalezeny žádné problémy.",
@@ -1170,10 +1135,7 @@
"note_tree_font": "Font stromu poznámek",
"note_detail_font": "Font detailu poznámky",
"monospace_font": "Monospace (kód) Font",
"note_tree_and_detail_font_sizing": "Upozorňujeme, že velikost fontu stromu a detailu je relativní k hlavnímu nastavení velikosti fontu.",
"not_all_fonts_available": "Ne všechny uvedené fonty nemusí být dostupné ve vašem systému.",
"apply_font_changes": "Pro použití změn fontu klikněte na",
"reload_frontend": "obnovení frontendu",
"generic-fonts": "Obecné fonty",
"sans-serif-system-fonts": "Systémové sans-serif fonty",
"serif-system-fonts": "Systémové serif fonty",
@@ -1279,7 +1241,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Časový limit pro vymazání příloh",
"attachment_auto_deletion_description": "Přílohy jsou automaticky smazány (a vymazány), pokud nejsou po definovaném časovém limitu odkazovány jejich poznámkách.",
"erase_attachments_after": "Vymazat nepoužité přílohy po:",
"manual_erasing_description": "Můžete také spustit vymazání ručně (bez ohledu na výše definovaný časový limit):",
"erase_unused_attachments_now": "Vymazat nepoužité přílohy nyní",
@@ -1291,7 +1252,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Časový limit pro vymazání Poznámky",
"note_erasure_description": "Odstraněné poznámky (a atributy, revize...) jsou zpočátku pouze označeny jako odstraněné a lze je obnovit v dialogovém okně „Poslední poznámky“. Po uplynutí určité doby jsou odstraněné poznámky „vymazány“, což znamená, že jejich obsah již nelze obnovit. Toto nastavení vám umožňuje určit dobu, která uplyne mezi odstraněním a vymazáním poznámky.",
"erase_notes_after": "Vymazat Poznámky po:",
"manual_erasing_description": "Můžete také spustit vymazání ručně (bez ohledu na výše uvedený časový limit):",
"erase_deleted_notes_now": "Vymazat smazané Poznámky nyní",
@@ -1381,7 +1341,6 @@
"first-week-contains-first-thursday": "První týden obsahuje první čtvrtek v roce",
"first-week-has-minimum-days": "První týden má minimální počet dní",
"min-days-in-first-week": "Minimální počet dní v prvním týdnu",
"first-week-info": "První týden obsahuje první čtvrtek v roce je založen na <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> standardu.",
"first-week-warning": "Změna možností prvního týdne může způsobit duplikaci se stávajícími Týdenními Poznámkami a stávající Týdenní Poznámky nebudou odpovídajícím způsobem aktualizovány.",
"formatting-locale": "Formát data & čísel",
"formatting-locale-auto": "Na základě jazyka aplikace"
@@ -1506,9 +1465,6 @@
"server_address": "Adresa instance serveru",
"timeout": "Časový limit synchronizace",
"proxy_label": "Proxy server pro synchronizaci (volitelné)",
"note": "Poznámka",
"note_description": "Pokud ponecháte nastavení proxy prázdné, bude použit systémový proxy (platí pouze pro desktop/electron build).",
"special_value_description": "Další speciální hodnota je <code>noproxy</code>, která vynutí ignorování i systémového proxy a respektuje <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Uložit",
"help": "Nápověda",
"test_title": "Test Synchronizace",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Über Trilium Notes",
"homepage": "Startseite:",
"app_version": "App-Version:",
"db_version": "DB-Version:",
"sync_version": "Sync-Version:",
"build_date": "Build-Datum:",
"build_revision": "Build-Revision:",
"data_directory": "Datenverzeichnis:"
},
"toast": {
@@ -92,10 +85,18 @@
"delete_all_clones_description": "auch alle Klone löschen (kann bei letzte Änderungen rückgängig gemacht werden)",
"erase_notes_description": "Beim normalen (vorläufigen) Löschen werden die Notizen nur als gelöscht markiert und sie können innerhalb eines bestimmten Zeitraums (im Dialogfeld „Letzte Änderungen“) wiederhergestellt werden. Wenn du diese Option aktivierst, werden die Notizen sofort gelöscht und es ist nicht möglich, die Notizen wiederherzustellen.",
"erase_notes_warning": "Notizen dauerhaft löschen (kann nicht rückgängig gemacht werden), einschließlich aller Klone. Dadurch wird ein Neuladen der Anwendung erzwungen.",
"notes_to_be_deleted": "Folgende Notizen werden gelöscht ({{notesCount}})",
"notes_to_be_deleted": "({{notesCount}}) Notizen werden gelöscht",
"no_note_to_delete": "Es werden keine Notizen gelöscht (nur Klone).",
"broken_relations_to_be_deleted": "Folgende Beziehungen werden gelöst und gelöscht ({{ relationCount}})",
"cancel": "Abbrechen"
"broken_relations_to_be_deleted": "Unterbrochene Beziehungen ({{relationCount}})",
"cancel": "Abbrechen",
"title": "Notizen löschen",
"clones_label": "Duplikate",
"delete_clones_description_one": "Löscht {{count}} weiteres Duplikat. Kann unter „Letzte Änderungen“ rückgängig gemacht werden.",
"delete_clones_description_other": "Löscht {{count}} weitere Duplikate. Kann unter „Letzte Änderungen“ rückgängig gemacht werden.",
"erase_notes_label": "Permanent löschen",
"table_note_with_relation": "Notiz mit Beziehung",
"table_relation": "Beziehung",
"delete": "Löschen"
},
"export": {
"export_note_title": "Notiz exportieren",
@@ -267,33 +268,6 @@
"undelete_link": "Wiederherstellen",
"confirm_undelete": "Möchten Sie diese Notiz und ihre Unternotizen wiederherstellen?"
},
"revisions": {
"note_revisions": "Notizrevisionen",
"delete_all_revisions": "Lösche alle Revisionen dieser Notiz",
"delete_all_button": "Alle Revisionen löschen",
"help_title": "Hilfe zu Notizrevisionen",
"confirm_delete_all": "Möchtest du alle Revisionen dieser Notiz löschen?",
"no_revisions": "Für diese Notiz gibt es noch keine Revisionen...",
"confirm_restore": "Möchtest du diese Revision wiederherstellen? Dadurch werden der aktuelle Titel und Inhalt der Notiz mit dieser Revision überschrieben.",
"confirm_delete": "Möchtest du diese Revision löschen?",
"revisions_deleted": "Notizrevisionen wurden gelöscht.",
"revision_restored": "Die Notizrevision wurde wiederhergestellt.",
"revision_deleted": "Notizrevision wurde gelöscht.",
"snapshot_interval": "Notizrevisionen-Snapshot Intervall: {{seconds}}s.",
"maximum_revisions": "Maximale Revisionen für aktuelle Notiz: {{number}}.",
"settings": "Einstellungen für Notizrevisionen",
"download_button": "Herunterladen",
"mime": "MIME: ",
"file_size": "Dateigröße:",
"preview_not_available": "Für diesen Notiztyp ist keine Vorschau verfügbar.",
"restore_button": "Wiederherstellen",
"delete_button": "Löschen",
"diff_on": "Zeige Differenz",
"diff_off": "Zeige Inhalt",
"diff_on_hint": "Klicke, um die Differenz des Notiz-Quellcodes zu zeigen",
"diff_off_hint": "Klicke, um den Notizinhalt zu zeigen",
"diff_not_available": "Differenz-Abgleich ist nicht verfügbar."
},
"sort_child_notes": {
"sort_children_by": "Unternotizen sortieren nach...",
"sorting_criteria": "Sortierkriterien",
@@ -365,7 +339,7 @@
"calendar_root": "Markiert eine Notiz, die als Basis für Tagesnotizen verwendet werden soll. Nur einer sollte als solcher gekennzeichnet sein.",
"archived": "Notizen mit dieser Bezeichnung werden standardmäßig nicht in den Suchergebnissen angezeigt (auch nicht in den Dialogen „Springen zu“, „Link hinzufügen“ usw.).",
"exclude_from_export": "Notizen (mit ihrem Unterbaum) werden nicht im Notizexport inkludiert",
"run": "Definiert, bei welchen Ereignissen das Skript ausgeführt werden soll. Mögliche Werte sind:\n<ul>\n<li>frontendStartup - wenn das Trilium-Frontend startet (oder aktualisiert wird), außer auf mobilen Geräten.</li>\n<li>mobileStartup - wenn das Trilium-Frontend auf einem mobilen Gerät startet (oder aktualisiert wird).</li>\n<li>backendStartup - wenn das Trilium-Backend startet</li>\n<li>hourly - einmal pro Stunde ausführen. Du kannst das zusätzliche Label <code>runAtHour</code> verwenden, um die genaue Stunde festzulegen.</li>\n<li>daily - einmal pro Tag ausführen</li>\n</ul>",
"run": "Definiert bei welchen Ereignissen das Skript ausgeführt werden soll. Mögliche Werte sind:\n<ul>\n<li>frontendStartup - wenn das Trilium-Frontend startet (oder aktualisiert wird), außer auf mobilen Geräten.</li>\n<li>mobileStartup - wenn das Trilium-Frontend auf einem mobilen Gerät startet (oder aktualisiert wird).</li>\n<li>backendStartup - wenn das Trilium-Backend startet.</li>\n<li>hourly - einmal pro Stunde ausführen. Du kannst das zusätzliche Label <code>runAtHour</code> verwenden, um die genaue Stunde festzulegen.</li>\n<li>daily - einmal pro Tag ausführen</li>\n</ul>",
"run_on_instance": "Definiere, auf welcher Trilium-Instanz dies ausgeführt werden soll. Standardmäßig alle Instanzen.",
"run_at_hour": "Zu welcher Stunde soll das laufen? Sollte zusammen mit <code>#runu003dhourly</code> verwendet werden. Kann für mehr Läufe im Laufe des Tages mehrfach definiert werden.",
"disable_inclusion": "Skripte mit dieser Bezeichnung werden nicht in die Ausführung des übergeordneten Skripts einbezogen.",
@@ -703,7 +677,8 @@
"export_as_image_svg": "SVG (Vektor)",
"note_map": "Notizen Karte",
"view_revisions": "Notizrevisionen...",
"advanced": "Erweitert"
"advanced": "Erweitert",
"view_ocr_text": "OCR text anzeigen"
},
"onclick_button": {
"no_click_handler": "Das Schaltflächen-Widget „{{componentId}}“ hat keinen definierten Klick-Handler"
@@ -799,7 +774,10 @@
"expand_tooltip": "Erweitert die direkten Unterelemente dieser Sammlung (eine Ebene tiefer). Für weitere Optionen auf den Pfeil rechts klicken.",
"expand_first_level": "Direkte Unterelemente erweitern",
"expand_nth_level": "{{depth}} Ebenen erweitern",
"hide_child_notes": "Untergeordnete Notizen im Baum ausblenden"
"hide_child_notes": "Untergeordnete Notizen im Baum ausblenden",
"open_all_in_tabs": "Alle öffnen",
"open_all_in_tabs_tooltip": "Alle Resultate in neuen Tabs öffnen",
"open_all_confirm": "Dies öffnet {{count}} Notizen in neuen Tabs. Fortfahren?"
},
"edited_notes": {
"no_edited_notes_found": "An diesem Tag wurden noch keine Notizen bearbeitet...",
@@ -853,7 +831,8 @@
"collapse": "Auf normale Größe reduzieren",
"title": "Notizkarte",
"fix-nodes": "Knoten fixieren",
"link-distance": "Verbindungslänge"
"link-distance": "Verbindungslänge",
"too-many-notes": "Dieser Unterbaum enthält {{count}} Notizen, welche die Limitierung von {{max}} überschreitet die in der Notizkarte dargestellt werden können."
},
"note_paths": {
"title": "Notizpfade",
@@ -901,7 +880,7 @@
"limit": "Limit",
"limit_description": "Begrenze die Anzahl der Ergebnisse",
"debug": "debuggen",
"debug_description": "Debug gibt zusätzliche Debuginformationen in die Konsole aus, um das Debuggen komplexer Abfragen zu erleichtern",
"debug_description": "Debug gibt zusätzliche Protokolleinträge in der Konsole aus, um die Fehlerdiagnose komplexer Abfragen zu erleichtern",
"action": "Aktion",
"search_button": "Suchen",
"search_execute": "Aktionen suchen und ausführen",
@@ -933,7 +912,7 @@
},
"debug": {
"debug": "Debuggen",
"debug_info": "Debug gibt zusätzliche Debuginformationen in die Konsole aus, um das Debuggen komplexer Abfragen zu erleichtern.",
"debug_info": "Debug gibt zusätzliche Protokolleinträge in der Konsole aus, um die Fehlerdiagnose komplexer Abfragen zu erleichtern.",
"access_info": "Um auf die Debug-Informationen zuzugreifen, führe die Abfrage aus und klicke oben links auf \"Backend-Log anzeigen\"."
},
"fast_search": {
@@ -1058,7 +1037,8 @@
"note_already_in_diagram": "Die Notiz \"{{title}}\" ist schon im Diagram.",
"enter_title_of_new_note": "Gebe den Titel der neuen Notiz ein",
"default_new_note_title": "neue Notiz",
"click_on_canvas_to_place_new_note": "Klicke auf den Canvas, um eine neue Notiz zu platzieren"
"click_on_canvas_to_place_new_note": "Klicke auf den Canvas, um eine neue Notiz zu platzieren",
"rename_relation": "Beziehung umbenennen"
},
"backend_log": {
"refresh": "Aktualisieren"
@@ -1067,15 +1047,17 @@
"title": "Konsistenzprüfungen",
"find_and_fix_button": "Finde und behebe die Konsistenzprobleme",
"finding_and_fixing_message": "Konsistenzprobleme finden und beheben...",
"issues_fixed_message": "Konsistenzprobleme sollten behoben werden."
"issues_fixed_message": "Konsistenzprobleme sollten behoben werden.",
"find_and_fix_label": "Finde und behebe Konsistenzprobleme",
"find_and_fix_description": "Suche nach Probleme mit der Datenkonsistenz in der Datenbank und repariere diese automatisch."
},
"database_anonymization": {
"title": "Datenbankanonymisierung",
"full_anonymization": "Vollständige Anonymisierung",
"full_anonymization_description": "Durch diese Aktion wird eine neue Kopie der Datenbank erstellt und anonymisiert (der gesamte Notizinhalt wird entfernt und nur die Struktur und einige nicht vertrauliche Metadaten bleiben übrig), sodass sie zu Debugging-Zwecken online geteilt werden kann, ohne befürchten zu müssen, dass Ihre persönlichen Daten verloren gehen.",
"full_anonymization_description": "Erstellt eine Kopie der Datenbank, wo der Inhalt der Notizen entfernt wurde. Es vergleicht lediglich die Struktur sowie nicht-kritische Metadaten. Sicher zum teilen für die Fehlerdiagnose.",
"save_fully_anonymized_database": "Speichere eine vollständig anonymisierte Datenbank",
"light_anonymization": "Leichte Anonymisierung",
"light_anonymization_description": "Durch diese Aktion wird eine neue Kopie der Datenbank erstellt und eine leichte Anonymisierung vorgenommen insbesondere wird nur der Inhalt aller Notizen entfernt, Titel und Attribute bleiben jedoch erhalten. Darüber hinaus bleiben benutzerdefinierte JS-Frontend-/Backend-Skriptnotizen und benutzerdefinierte Widgets erhalten. Dies bietet mehr Kontext zum Debuggen der Probleme.",
"light_anonymization_description": "Erstellt eine Kopie wo der Inhalt der Notiz entfernt ist, jedoch Title, Attribute und benutzerdefinierte Skripte erhalten bleiben. Hilfreich zur Fehlerdiagnose.",
"choose_anonymization": "Du kannst selbst entscheiden, ob du eine vollständig oder leicht anonymisierte Datenbank bereitstellen möchten. Selbst eine vollständig anonymisierte Datenbank ist sehr nützlich. In einigen Fällen kann jedoch eine leicht anonymisierte Datenbank den Prozess der Fehlererkennung und -behebung beschleunigen.",
"save_lightly_anonymized_database": "Speichere eine leicht anonymisierte Datenbank",
"existing_anonymized_databases": "Vorhandene anonymisierte Datenbanken",
@@ -1084,15 +1066,17 @@
"error_creating_anonymized_database": "Die anonymisierte Datenbank konnte nicht erstellt werden. Überprüfe die Backend-Protokolle auf Details",
"successfully_created_fully_anonymized_database": "Vollständig anonymisierte Datenbank in {{anonymizedFilePath}} erstellt",
"successfully_created_lightly_anonymized_database": "Leicht anonymisierte Datenbank in {{anonymizedFilePath}} erstellt",
"no_anonymized_database_yet": "Noch keine anonymisierte Datenbank."
"no_anonymized_database_yet": "Noch keine anonymisierte Datenbank.",
"description": "Erstellt eine anonymisierte Kopie deiner Datenbank für den Austausch mit Entwicklern zur Fehlerdiagnose, ohne persönliche Daten preiszugeben."
},
"database_integrity_check": {
"title": "Datenbankintegritätsprüfung",
"description": "Dadurch wird überprüft, ob die Datenbank auf SQLite-Ebene nicht beschädigt ist. Abhängig von der DB-Größe kann es einige Zeit dauern.",
"check_button": "Überprüfe die Datenbankintegrität",
"checking_integrity": "Datenbankintegrität prüfen...",
"integrity_check_succeeded": "Integritätsprüfung erfolgreich keine Probleme gefunden.",
"integrity_check_failed": "Integritätsprüfung fehlgeschlagen: {{results}}"
"integrity_check_failed": "Integritätsprüfung fehlgeschlagen: {{results}}",
"check_integrity_label": "Überprüfe die Datenbankintegrität",
"check_integrity_description": "Überprüfe die Datenbank auf SQLite Ebene auf Fehler."
},
"sync": {
"title": "Synchronisieren",
@@ -1102,14 +1086,18 @@
"filling_entity_changes": "Entitätsänderungszeilen werden gefüllt...",
"sync_rows_filled_successfully": "Synchronisierungszeilen erfolgreich gefüllt",
"finished-successfully": "Synchronisierung erfolgreich beendet.",
"failed": "Synchronisierung fehlgeschlagen: {{message}}"
"failed": "Synchronisierung fehlgeschlagen: {{message}}",
"force_full_sync_label": "Vollständige Synchronisierung erzwingen",
"force_full_sync_description": "Vollständige Synchronisation mit dem Sync-Server auslösen, lädt alle Änderungen erneut hoch."
},
"vacuum_database": {
"title": "Datenbank aufräumen",
"description": "Dadurch wird die Datenbank neu erstellt, was normalerweise zu einer kleineren Datenbankdatei führt. Es werden keine Daten tatsächlich geändert.",
"button_text": "Datenbank aufräumen",
"vacuuming_database": "Datenbank wird geleert...",
"database_vacuumed": "Die Datenbank wurde geleert"
"database_vacuumed": "Die Datenbank wurde geleert",
"vacuum_label": "Datenbank bereinigen",
"vacuum_description": "Datenbank neu aufbauen um die Dateigröße zu reduzieren. Keine Daten werden verändert."
},
"fonts": {
"theme_defined": "Thema definiert",
@@ -1120,10 +1108,7 @@
"note_tree_font": "Notizbaum-Schriftart",
"note_detail_font": "Notiz-Detail-Schriftart",
"monospace_font": "Minivan (Code) Schriftart",
"note_tree_and_detail_font_sizing": "Beachte, dass die Größe der Baum- und Detailschriftarten relativ zur Hauptschriftgrößeneinstellung ist.",
"not_all_fonts_available": "Möglicherweise sind nicht alle aufgelisteten Schriftarten auf Ihrem System verfügbar.",
"apply_font_changes": "Um Schriftartänderungen zu übernehmen, klicke auf",
"reload_frontend": "Frontend neu laden",
"not_all_fonts_available": "Möglicherweise sind nicht alle aufgelisteten Schriftarten auf Ihrem System verfügbar",
"generic-fonts": "Generische Schriftarten",
"sans-serif-system-fonts": "Sans-serif Systemschriftarten",
"serif-system-fonts": "Serif Systemschriftarten",
@@ -1132,7 +1117,9 @@
"serif": "Serif",
"sans-serif": "Sans Serif",
"monospace": "Monospace",
"system-default": "System Standard"
"system-default": "System Standard",
"custom_fonts": "Benutzerdefinierte Schriftarten verwenden",
"preview": "Vorschau"
},
"max_content_width": {
"title": "Inhaltsbreite",
@@ -1165,7 +1152,10 @@
"layout-horizontal-description": "Startleiste ist unter der Tableiste. Die Tableiste wird dadurch auf die ganze Breite erweitert.",
"auto_theme": "Alt (Folge dem Farbschema des Systems)",
"light_theme": "Alt (Hell)",
"dark_theme": "Alt (Dunkel)"
"dark_theme": "Alt (Dunkel)",
"modern_themes": "Modern",
"legacy_themes": "Veraltet",
"custom_themes": "Benutzerdefiniert"
},
"zoom_factor": {
"title": "Zoomfaktor (nur Desktop-Build)",
@@ -1193,18 +1183,25 @@
},
"images": {
"images_section_title": "Bilder",
"download_images_automatically": "Lade Bilder automatisch herunter, um sie offline zu verwenden.",
"download_images_description": "Eingefügter HTML-Code kann Verweise auf Online-Bilder enthalten. Trilium findet diese Verweise und lädt die Bilder herunter, sodass sie offline verfügbar sind.",
"enable_image_compression": "Bildkomprimierung aktivieren",
"max_image_dimensions": "Maximale Breite/Höhe eines Bildes in Pixel (die Größe des Bildes wird geändert, wenn es diese Einstellung überschreitet).",
"jpeg_quality_description": "JPEG-Qualität (10 schlechteste Qualität, 100 beste Qualität, 50 85 wird empfohlen)",
"max_image_dimensions_unit": "Pixel"
"download_images_automatically": "Bilder automatisch herunterladen",
"download_images_description": "Referenzierte online Bilder vom eingefügten HTML-Code herunterladen, damit diese offline zur Verfügung stehen.",
"enable_image_compression": "Bildkomprimierung",
"max_image_dimensions": "Maximale Maße eines Bildes",
"jpeg_quality_description": "Empfohlener Bereich liegt zwischen 50-85. Niedrige Werte reduzieren die Dateigröße, höhere Werte bewahren Details.",
"max_image_dimensions_unit": "Pixel",
"enable_image_compression_description": "Komprimieren und skalieren Bilder, wenn diese hochgeladen oder eingefügt werden.",
"max_image_dimensions_description": "Bilder, die diese Größe überschreiten, werden automatisch verkleinert.",
"jpeg_quality": "JPEG Qualität",
"ocr_section_title": "Text Extrahierung (OCR)",
"ocr_related_content_languages": "Inhaltssprachen (für Textextrahierung verwendet)",
"ocr_auto_process": "Neue Dateien automatisch verarbeiten",
"ocr_auto_process_description": "Text automatisch extrahieren von neu hochgeladenen oder eingefügten Dateien.",
"ocr_min_confidence": "Minimale Sicherheit"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Zeitüberschreitung beim Löschen von Anhängen",
"attachment_auto_deletion_description": "Anhänge werden automatisch gelöscht (und gelöscht), wenn sie nach einer definierten Zeitspanne nicht mehr in ihrer Notiz referenziert werden.",
"erase_attachments_after": "Nicht verwendete Anhänge löschen nach:",
"manual_erasing_description": "Du kannst das Löschen auch manuell auslösen (ohne Berücksichtigung des oben definierten Timeouts):",
"erase_attachments_after": "Nicht verwendete Anhänge löschen nach",
"manual_erasing_description": "Manuelle Löschung aktivieren, ignoriert den obigen Zeitpunkt.",
"erase_unused_attachments_now": "Lösche jetzt nicht verwendete Anhangnotizen",
"unused_attachments_erased": "Nicht verwendete Anhänge wurden gelöscht."
},
@@ -1214,28 +1211,29 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Beachte das Zeitlimit für die Löschung",
"note_erasure_description": "Gelöschte Notizen (und Attribute, Notizrevisionen...) werden zunächst nur als gelöscht markiert und können über den Dialog „Zuletzt verwendete Notizen” wiederhergestellt werden. Nach einer bestimmten Zeit werden gelöschte Notizen „gelöscht”, was bedeutet, dass ihr Inhalt nicht mehr wiederhergestellt werden kann. Mit dieser Einstellung können Sie die Zeitspanne zwischen dem Löschen und dem endgültigen Löschen der Notiz festlegen.",
"erase_notes_after": "Notizen löschen nach:",
"manual_erasing_description": "Du kannst das Löschen auch manuell auslösen (ohne Berücksichtigung des oben definierten Timeouts):",
"erase_notes_after": "Notizen löschen nach",
"manual_erasing_description": "Manuelle Löschung aktivieren, ignoriert den obigen Zeitpunkt.",
"erase_deleted_notes_now": "Jetzt gelöschte Notizen löschen",
"deleted_notes_erased": "Gelöschte Notizen wurden gelöscht."
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "Snapshot-Intervall für Notizrevisionen",
"note_revisions_snapshot_description": "Das Snapshot-Zeitintervall für Notizrevisionen ist die Zeit, nach der eine neue Notizrevision erstellt wird. Weitere Informationen findest du im <doc>Wiki</doc>.",
"snapshot_time_interval_label": "Zeitintervall für Notiz-Revisions-Snapshot:"
"snapshot_time_interval_label": "Snapshot Intervall"
},
"revisions_snapshot_limit": {
"note_revisions_snapshot_limit_title": "Limit für Notizrevision-Snapshots",
"note_revisions_snapshot_limit_description": "Das Limit für Notizrevision-Snapshots bezieht sich auf die maximale Anzahl von Revisionen, die für jede Notiz gespeichert werden können. Dabei bedeutet -1, dass es kein Limit gibt, und 0 bedeutet, dass alle Revisionen gelöscht werden. Du kannst das maximale Limit für Revisionen einer einzelnen Notiz über das Label #versioningLimit festlegen.",
"snapshot_number_limit_label": "Limit der Notizrevision-Snapshots:",
"snapshot_number_limit_label": "Maximale Revisionen",
"erase_excess_revision_snapshots": "Überschüssige Revision-Snapshots jetzt löschen",
"erase_excess_revision_snapshots_prompt": "Überschüssige Revision-Snapshots wurden gelöscht.",
"snapshot_number_limit_unit": "Momentaufnahmen"
"snapshot_number_limit_unit": "Momentaufnahmen",
"note_revisions_snapshot_limit_description_short": "Maximale Anzahl an Revisionen pro Notiz. Nutze -1 für unlimitiert oder 0 zum deaktivieren.",
"erase_excess_revision_snapshots_description": "Lösche Revisionen aller Notizen die das Limit überschreiten."
},
"search_engine": {
"title": "Suchmaschine",
"custom_search_engine_info": "Für eine benutzerdefinierte Suchmaschine müssen sowohl ein Name als auch eine URL festgelegt werden. Wenn keine dieser Optionen festgelegt ist, wird DuckDuckGo als Standardsuchmaschine verwendet.",
"custom_search_engine_info": "Wird verwendet bei der Suche im Web für den ausgewählten Text. Wenn nicht konfiguriert, wird DuckDuckGo verwendet.",
"predefined_templates_label": "Vordefinierte Suchmaschinenvorlagen",
"bing": "Bing",
"baidu": "Baidu",
@@ -1293,7 +1291,6 @@
"first-week-contains-first-thursday": "Erste Woche enthält den ersten Donnerstag des Jahres",
"first-week-has-minimum-days": "Erste Woche hat Mindestanzahl an Tagen",
"min-days-in-first-week": "Mindestanzahl an Tagen in erster Woche",
"first-week-info": "Die erste Woche, die den ersten Donnerstag des Jahres enthält, basiert auf dem Standard <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Das Ändern der Optionen für die erste Woche kann zu Duplikaten mit bestehenden Wochen-Notizen führen. Bestehende Wochen-Notizen werden nicht entsprechend aktualisiert.",
"formatting-locale": "Datums- und Zahlenformat",
"tuesday": "Dienstag",
@@ -1316,7 +1313,9 @@
"date-and-time": "Datum & Uhrzeit",
"path": "Pfad",
"database_backed_up_to": "Die Datenbank wurde gesichert unter {{backupFilePath}}",
"no_backup_yet": "noch kein Backup"
"no_backup_yet": "noch kein Backup",
"title": "Sicherung",
"download": "Download"
},
"etapi": {
"title": "ETAPI",
@@ -1355,14 +1354,17 @@
"protected_session_timeout_description": "Das Zeitlimit für geschützte Sitzungen ist ein Zeitraum, nach dem die geschützte Sitzung aus dem Speicher des Browsers gelöscht wird. Dies wird ab der letzten Interaktion mit geschützten Notizen gemessen. Sehen",
"wiki": "Wiki",
"for_more_info": "für weitere Informationen.",
"protected_session_timeout_label": "Zeitüberschreitung der geschützten Sitzung:",
"protected_session_timeout_label": "Automatisches beenden der Sitzung nach",
"reset_confirmation": "Durch das Zurücksetzen des Passworts verlierst du für immer den Zugriff auf alle Ihre bestehenden geschützten Notizen. Möchtest du das Passwort wirklich zurücksetzen?",
"reset_success_message": "Das Passwort wurde zurückgesetzt. Bitte lege ein neues Passwort fest",
"change_password_heading": "Kennwort ändern",
"set_password_heading": "Passwort festlegen",
"set_password": "Passwort festlegen",
"password_mismatch": "Neue Passwörter sind nicht dasselbe.",
"password_changed_success": "Das Passwort wurde geändert. Trilium wird neu geladen, nachdem du auf OK geklickt hast."
"password_changed_success": "Das Passwort wurde geändert. Trilium wird neu geladen, nachdem du auf OK geklickt hast.",
"change_password_description": "Aktualisiere dein aktuelles Passwort",
"reset_password": "Passwort zurücksetzen",
"cancel": "Abbrechen"
},
"shortcuts": {
"keyboard_shortcuts": "Tastaturkürzel",
@@ -1383,16 +1385,16 @@
"description": "Diese Optionen gelten nur für Desktop-Builds. Browser verwenden ihre eigene native Rechtschreibprüfung.",
"enable": "Aktiviere die Rechtschreibprüfung",
"language_code_label": "Sprachcode(s)",
"restart-required": "Änderungen an den Rechtschreibprüfungsoptionen werden nach dem Neustart der Anwendung wirksam."
"restart-required": "Änderungen an den Rechtschreibprüfungsoptionen werden nach dem Neustart der Anwendung wirksam.",
"custom_dictionary_title": "Benutzerdefiniertes Wörterbuch",
"custom_dictionary_edit": "Benutzerdefiniert Wörter",
"custom_dictionary_open": "Wörterbuch bearbeiten"
},
"sync_2": {
"config_title": "Synchronisierungskonfiguration",
"server_address": "Adresse der Serverinstanz",
"timeout": "Synchronisierungs-Timeout (Millisekunden)",
"proxy_label": "Proxyserver synchronisieren (optional)",
"note": "Notiz",
"note_description": "Wenn du die Proxy-Einstellung leer lässt, wird der System-Proxy verwendet (gilt nur für Desktop-/Electron-Build).",
"special_value_description": "Ein weiterer besonderer Wert ist <code>noproxy</code>, der das Ignorieren sogar des System-Proxys erzwingt und <code>NODE_TLS_REJECT_UNAUTHORIZED</code> respektiert.",
"save": "Speichern",
"help": "Helfen",
"test_title": "Synchronisierungstest",
@@ -1495,7 +1497,8 @@
"task-list": "Aufgabenliste",
"new-feature": "Neu",
"collections": "Sammlungen",
"spreadsheet": "Tabelle"
"spreadsheet": "Tabelle",
"llm-chat": "KI-Chat"
},
"protect_note": {
"toggle-on": "Notiz schützen",
@@ -1697,7 +1700,8 @@
"theme_none": "Keine Syntaxhervorhebung",
"theme_group_light": "Helle Themen",
"theme_group_dark": "Dunkle Themen",
"copy_title": "Kopiere in Zwischenablage"
"copy_title": "Kopiere in Zwischenablage",
"click_to_copy": "Klicke zum kopieren"
},
"classic_editor_toolbar": {
"title": "Format"
@@ -1716,7 +1720,7 @@
"title": "Fixiert",
"description": "Werkzeuge erscheinen im \"Format\" Tab."
},
"multiline-toolbar": "Toolbar wenn nötig in mehreren Zeilen darstellen."
"multiline-toolbar": "Toolbar wenn nötig in mehreren Zeilen darstellen"
}
},
"electron_context_menu": {
@@ -1807,8 +1811,9 @@
"custom_date_time_format": {
"title": "Benutzerdefiniertes Datums-/Zeitformat",
"description": "Passe das Format des Datums und der Uhrzeit an, die über <shortcut /> oder die Symbolleiste eingefügt werden. Die verfügbaren Format-Tokens sind unter <doc>Day.js docs</doc> zu finden.",
"format_string": "Format Zeichenfolge:",
"formatted_time": "Formatiertes Datum/Uhrzeit:"
"format_string": "Format Zeichenfolge",
"formatted_time": "Formatiertes Datum/Uhrzeit",
"preview": "Vorschau: {{preview}}"
},
"multi_factor_authentication": {
"title": "Multi-Faktor-Authentifizierung",
@@ -2039,7 +2044,9 @@
"title": "Experimentelle Optionen",
"disclaimer": "Diese Optionen sind experimentell und können Instabilitäten verursachen. Achtsam zu verwenden.",
"new_layout_name": "Neues Layout",
"new_layout_description": "Probiere das neue Layout für eine modernere Darstellung und verbesserte Benutzbarkeit aus. Kann sich in Zukunft stark ändern."
"new_layout_description": "Probiere das neue Layout für eine modernere Darstellung und verbesserte Benutzbarkeit aus. Kann sich in Zukunft stark ändern.",
"llm_name": "KI- / LLM-Chat",
"llm_description": "Aktiviert die KI-Chat Seitenleiste sowie LLM-Chat Notizen die von einem Sprachmodell betrieben werden."
},
"server": {
"unknown_http_error_title": "Kommunikationsfehler mit dem Server",
@@ -2223,5 +2230,79 @@
"sample_xy": "XY",
"sample_venn": "Mengen",
"sample_ishikawa": "Ursache-Wirkung"
},
"database": {
"title": "Datenbank"
},
"search": {
"title": "Suche",
"fuzzy_matching_label": "Fehlertoleranz bei Suche"
},
"text_editor": {
"title": "Editor"
},
"llm_chat": {
"placeholder": "Schreibe eine Nachricht...",
"send": "Senden",
"sending": "Sende...",
"empty_state": "Starte eine Unterhaltung indem du unten eine Nachricht schreibst.",
"searching_web": "Suche im Web...",
"web_search": "Websuche",
"note_tools": "Notizzugriff",
"sources": "Quellen",
"legacy_models": "Veraltete Modelle",
"thinking": "Denke...",
"thought_process": "Denkprozess",
"result": "Ergebnis",
"error": "Fehler",
"tool_error": "Fehlgeschlagen",
"total_tokens": "{{total}} Token",
"tokens": "Token",
"context_used": "{{percentage}}% verwendet",
"no_provider_message": "Kein KI-Anbieter konfiguriert. Fügen einen hinzu, um zu chatten.",
"add_provider": "KI-Anbieter hinzufügen",
"stop": "Stopp"
},
"sidebar_chat": {
"title": "KI-Chat",
"launcher_title": "KI-Chat öffnen",
"new_chat": "Neuen Chat starten",
"save_chat": "Chat in Notiz sichern",
"empty_state": "Starte Unterhaltung",
"history": "Chathistorie",
"recent_chats": "Kürzliche Chats",
"no_chats": "Keine vorherigen Chats"
},
"llm": {
"tools": {
"clone_note": "Notiz duplizieren",
"move_note": "Notiz verschieben",
"delete_note": "Notiz löschen",
"rename_note": "Notiz umbenennen",
"web_search": "Websuche",
"create_note": "Notiz erstellen",
"append_to_note": "An Notiz anhängen",
"get_note": "Notiz beziehen",
"search_notes": "Notizen durchsuchen"
},
"cancel": "Abbrechen",
"api_key": "API Schlüssel",
"delete_provider": "Löschen",
"actions": "Aktionen",
"provider_type": "Anbieter",
"provider_name": "Name",
"settings_title": "KI / LLM"
},
"mind-map": {
"summary": "Zusammenfassung",
"link": "Link"
},
"ocr": {
"view_extracted_text": "Extrahierten Text anzeigen (OCR)",
"open_media_settings": "Öffne Einstellungen",
"processing": "Verarbeite...",
"loading_text": "Lädt OCR Text...",
"extracted_text_title": "Extrahierter Text (OCR)",
"extracted_text": "Extrahierter Text (OCR)"
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Σχετικά με το Trilium Notes",
"homepage": "Αρχική Σελίδα:",
"app_version": "Έκδοση εφαρμογής:",
"db_version": "Έκδοση βάσης δεδομένων:",
"sync_version": "Έκδοση συγχρονισμού:",
"build_date": "Ημερομηνία χτισίματος εφαρμογής:",
"build_revision": "Αριθμός αναθεώρησης χτισίματος:",
"data_directory": "Φάκελος δεδομένων:"
},
"toast": {

View File

@@ -66,6 +66,172 @@
"set-custom-color": "Set custom note colour"
},
"about": {
"title": "About Trilium Notes"
"data_directory": "Data directory:"
},
"toast": {
"critical-error": {
"title": "Critical error",
"message": "A critical error has occurred which prevents the client application from starting:\n\n{{message}}\n\nThis is most likely caused by a script failing in an unexpected way. Try starting the application in safe mode and addressing the issue."
},
"widget-error": {
"title": "Failed to initialise a widget",
"message-custom": "Custom widget from note with ID \"{{id}}\", titled \"{{title}}\" could not be initialised due to:\n\n{{message}}",
"message-unknown": "Unknown widget could not be initialised due to:\n\n{{message}}"
},
"bundle-error": {
"title": "Failed to load a custom script",
"message": "Script could not be executed due to:\n\n{{message}}"
},
"widget-list-error": {
"title": "Failed to obtain the list of widgets from the server"
},
"widget-render-error": {
"title": "Failed to render a custom React widget"
},
"widget-missing-parent": "Custom widget does not have mandatory '{{property}}' property defined.\n\nIf this script is meant to be run without a UI element, use '#run=frontendStartup' instead.",
"open-script-note": "Open script note",
"scripting-error": "Custom script error: {{title}}"
},
"add_link": {
"add_link": "Add link",
"help_on_links": "Help on links",
"note": "Note",
"search_note": "search for note by its name",
"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"
},
"delete_notes": {
"delete_clones_description_one": "Also delete {{count}} other clone. Can be undone in recent changes.",
"delete_clones_description_other": "Also delete {{count}} other clones. Can be undone in recent changes.",
"title": "Delete notes",
"close": "Close",
"clones_label": "Clones",
"delete_all_clones_description": "Delete also all clones (can be undone in recent changes)",
"erase_notes_label": "Erase permanently",
"erase_notes_description": "Erase notes immediately instead of soft deletion. This cannot be undone and will force application reload.",
"erase_notes_warning": "Erase notes permanently (can't be undone), including all clones. This will force application reload.",
"notes_to_be_deleted": "Notes to be deleted ({{notesCount}})",
"no_note_to_delete": "No note will be deleted (only clones).",
"broken_relations_to_be_deleted": "Broken relations ({{relationCount}})",
"table_note_with_relation": "Note with relation",
"table_relation": "Relation",
"table_points_to": "Points to (deleted)",
"cancel": "Cancel",
"delete": "Delete"
},
"branch_prefix": {
"edit_branch_prefix": "Edit branch prefix",
"edit_branch_prefix_multiple": "Edit branch prefix for {{count}} branches",
"help_on_tree_prefix": "Help on Tree prefix",
"prefix": "Prefix: ",
"save": "Save",
"branch_prefix_saved": "Branch prefix has been saved.",
"branch_prefix_saved_multiple": "Branch prefix has been saved for {{count}} branches.",
"affected_branches": "Affected branches ({{count}}):"
},
"bulk_actions": {
"bulk_actions": "Bulk actions",
"affected_notes": "Affected notes",
"include_descendants": "Include descendants of the selected notes",
"available_actions": "Available actions",
"chosen_actions": "Chosen actions",
"execute_bulk_actions": "Execute bulk actions",
"bulk_actions_executed": "Bulk actions have been executed successfully.",
"none_yet": "None yet... add an action by clicking one of the available ones above.",
"labels": "Labels",
"relations": "Relations",
"notes": "Notes",
"other": "Other"
},
"clone_to": {
"clone_notes_to": "Clone notes to...",
"help_on_links": "Help on links",
"notes_to_clone": "Notes to clone",
"target_parent_note": "Target parent note",
"search_for_note_by_its_name": "search for note by its name",
"cloned_note_prefix_title": "Cloned note will be shown in note tree with given prefix",
"prefix_optional": "Prefix (optional)",
"clone_to_selected_note": "Clone to selected note",
"no_path_to_clone_to": "No path to clone to.",
"note_cloned": "Note \"{{clonedTitle}}\" has been cloned into \"{{targetTitle}}\""
},
"confirm": {
"confirmation": "Confirmation",
"cancel": "Cancel",
"ok": "OK",
"are_you_sure_remove_note": "Are you sure you want to remove the note \"{{title}}\" from relation map? ",
"if_you_dont_check": "If you don't check this, the note will be only removed from the relation map.",
"also_delete_note": "Also delete the note"
},
"export": {
"export_note_title": "Export note",
"close": "Close",
"export_type_subtree": "This note and all of its descendants",
"format_html": "HTML - recommended as it keeps all format",
"format_html_zip": "HTML in ZIP archive - this is recommended since this preserves all the formatting.",
"format_markdown": "Markdown - this preserves most of the formatting.",
"format_opml": "OPML - outliner interchange format for text only. Formatting, images and files are not included.",
"opml_version_1": "OPML v1.0 - plain text only",
"opml_version_2": "OPML v2.0 - allows also HTML",
"export_type_single": "Only this note without its descendants",
"export": "Export",
"choose_export_type": "Choose export type first please",
"export_status": "Export status",
"export_in_progress": "Export in progress: {{progressCount}}",
"export_finished_successfully": "Export finished successfully.",
"format_pdf": "PDF - for printing or sharing purposes.",
"share-format": "HTML for web publishing - uses the same theme that is used shared notes, but can be published as a static website."
},
"help": {
"title": "Cheatsheet",
"collapseSubTree": "collapse sub-tree",
"activateNextTab": "activate next tab",
"editShortcuts": "Edit keyboard shortcuts",
"noteNavigation": "Note navigation",
"goUpDown": "go up/down in the list of notes",
"collapseExpand": "collapse/expand node",
"notSet": "not set",
"goBackForwards": "go back / forwards in the history",
"showJumpToNoteDialog": "show <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">\"Jump to\" dialog</a>",
"scrollToActiveNote": "scroll to active note",
"jumpToParentNote": "jump to parent note",
"collapseWholeTree": "collapse whole note tree",
"tabShortcuts": "Tab shortcuts",
"newTabNoteLink": "on note link opens note in a new tab",
"newTabWithActivationNoteLink": "on note link opens and activates the note in a new tab",
"onlyInDesktop": "Only in desktop (Electron build)",
"openEmptyTab": "open empty tab",
"closeActiveTab": "close active tab",
"activatePreviousTab": "activate previous tab",
"creatingNotes": "Creating notes",
"createNoteAfter": "create new note after the active note",
"createNoteInto": "create new sub-note into active note",
"editBranchPrefix": "edit <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">prefix</a> of active note clone",
"movingCloningNotes": "Moving / cloning notes",
"moveNoteUpDown": "move note up/down in the note list",
"moveNoteUpHierarchy": "move note up in the hierarchy",
"multiSelectNote": "multi-select note above/below",
"selectAllNotes": "select all notes in the current level",
"selectNote": "select note",
"copyNotes": "copy active note (or current selection) into clipboard (used for <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/cloning-notes.html#cloning-notes\">cloning</a>)",
"cutNotes": "cut current note (or current selection) into clipboard (used for moving notes)",
"pasteNotes": "paste note(s) as sub-note into active note (which is either move or clone depending on whether it was copied or cut into clipboard)",
"deleteNotes": "delete note / sub-tree",
"editingNotes": "Editing notes",
"editNoteTitle": "in tree pane will switch from tree pane into note title. Enter from note title will switch focus to text editor. <kbd>Ctrl+.</kbd> will switch back from editor to tree pane.",
"createEditLink": "create / edit external link",
"createInternalLink": "create internal link",
"followLink": "follow link under cursor",
"insertDateTime": "insert current date and time at caret position",
"jumpToTreePane": "jump away to the tree pane and scroll to active note",
"markdownAutoformat": "Markdown-like autoformatting",
"headings": "<code>##</code>, <code>###</code>, <code>####</code> etc. followed by space for headings",
"bulletList": "<code>*</code> or <code>-</code> followed by space for bullet list",
"numberedList": "<code>1.</code> or <code>1)</code> followed by space for numbered list",
"blockQuote": "start a line with <code>></code> followed by space for block quote"
}
}

View File

@@ -1,13 +1,23 @@
{
"about": {
"title": "About Trilium Notes",
"homepage": "Homepage:",
"app_version": "App version:",
"db_version": "DB version:",
"sync_version": "Sync version:",
"build_date": "Build date:",
"build_revision": "Build revision:",
"data_directory": "Data directory:"
"about": {
"version_label": "Version:",
"version": "{{appVersion}} (database: {{dbVersion}}, sync protocol: {{syncVersion}})",
"build_info": "Build: {{buildDate}}, revision: <buildRevision />",
"contributors_label": "Contributors:",
"contributor_roles": {
"lead-dev": "lead developer",
"original-dev": "original developer"
},
"role_brief_history": {
"lead-dev": "Elian Doran founded TriliumNext in 2024, a community fork created after Zadam stepped back from the project. Zadam later transferred the original repository to the TriliumNext team, merging both projects back into one.",
"original-dev": "On 25th December 2017, Zadam released the first beta of Trilium (written with a single \"l\", unlike the flower). Dissatisfied with existing note organizers, he built a powerful self-hosted hierarchical knowledge base that gathered over 22,000 GitHub stars. In 2024, as life got busier, he placed the project into maintenance mode."
},
"contributor_full_list": "See the entire community",
"data_directory": "Data directory:",
"github_tooltip": "Report bugs, suggest features, or contribute on GitHub",
"license_tooltip": "View license",
"donate": "Donate",
"donate_tooltip": "Donate to support this project"
},
"toast": {
"critical-error": {
@@ -41,6 +51,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": {
@@ -285,6 +297,7 @@
"confirm_delete_all": "Do you want to delete all revisions of this note?",
"no_revisions": "No revisions for this note yet...",
"restore_button": "Restore",
"highlight_changes": "Highlight changes",
"diff_on": "Show diff",
"diff_off": "Show content",
"diff_on_hint": "Click to show note source diff",
@@ -298,11 +311,39 @@
"revision_deleted": "Note revision has been deleted.",
"snapshot_interval": "Note Revision Snapshot Interval: {{seconds}}s.",
"maximum_revisions": "Note Revision Snapshot Limit: {{number}}.",
"save_revision_now": "Save a revision now",
"save_named_revision": "Save named revision...",
"snapshot_header": "Note revision snapshot",
"snapshot_interval_value": "Interval: {{seconds}}s",
"snapshot_limit_value": "Limit: {{number}}",
"settings": "Note Revision Settings",
"menu_tooltip": "Revision options",
"download_button": "Download",
"mime": "MIME: ",
"file_size": "File size:",
"preview_not_available": "Preview isn't available for this note type."
"preview_not_available": "Preview isn't available for this note type.",
"save_revision": "Save revision",
"save_revision_tooltip": "Manually save a snapshot of the current note",
"description_placeholder": "Name this revision",
"revision_saved": "Note revision has been saved.",
"edit_description": "Edit name",
"description_updated": "Revision name has been updated.",
"source_auto": "Auto-save",
"source_manual": "Manual save",
"source_etapi": "ETAPI",
"source_llm": "LLM",
"source_restore": "Restore",
"source_unknown": "Snapshot",
"date_today": "Today",
"date_yesterday": "Yesterday",
"date_this_week": "This week",
"date_this_month": "This month",
"source_description_auto": "Automatically saved by the system at regular intervals",
"source_description_manual": "Manually saved by the user",
"source_description_etapi": "Created via the External Trilium API",
"source_description_llm": "Created by the AI assistant",
"source_description_restore": "Saved before restoring a previous revision",
"source_description_unknown": "Source not available"
},
"sort_child_notes": {
"sort_children_by": "Sort children by...",
@@ -454,6 +495,8 @@
"and_more": "... and {{count}} more.",
"print_landscape": "When exporting to PDF, changes the orientation of the page to landscape instead of portrait.",
"print_page_size": "When exporting to PDF, changes the size of the page. Supported values: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.",
"print_scale": "When exporting to PDF, changes the scale of the rendered content. Values range from 0.1 (10%) to 2 (200%), default is 1 (100%).",
"print_margins": "When exporting to PDF, sets page margins. Use <code>default</code>, <code>none</code>, <code>minimum</code>, or custom values as <code>top,right,bottom,left</code> in millimeters.",
"color_type": "Color"
},
"attribute_editor": {
@@ -693,6 +736,11 @@
"move_right": "Move right"
},
"note_actions": {
"word_wrap": "Word wrap",
"word_wrap_auto": "Auto",
"word_wrap_auto_description": "Follow the global setting",
"word_wrap_on": "On",
"word_wrap_off": "Off",
"convert_into_attachment": "Convert into attachment",
"re_render_note": "Re-render note",
"search_in_note": "Search in note",
@@ -709,6 +757,7 @@
"print_note": "Print note",
"view_revisions": "Note revisions...",
"save_revision": "Save revision",
"save_named_revision": "Save named revision...",
"advanced": "Advanced",
"convert_into_attachment_failed": "Converting note '{{title}}' failed.",
"convert_into_attachment_successful": "Note '{{title}}' has been converted to attachment.",
@@ -853,6 +902,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",
@@ -1121,17 +1173,20 @@
},
"consistency_checks": {
"title": "Consistency Checks",
"find_and_fix_label": "Find and fix consistency issues",
"find_and_fix_description": "Scan for and automatically repair any data consistency issues in the database.",
"find_and_fix_button": "Find and fix consistency issues",
"finding_and_fixing_message": "Finding and fixing consistency issues...",
"issues_fixed_message": "Any consistency issue which may have been found is now fixed."
},
"database_anonymization": {
"title": "Database Anonymization",
"full_anonymization": "Full Anonymization",
"full_anonymization_description": "This action will create a new copy of the database and anonymize it (remove all note content and leave only structure and some non-sensitive metadata) for sharing online for debugging purposes without fear of leaking your personal data.",
"description": "Create an anonymized copy of your database for sharing with developers when debugging issues, without exposing personal data.",
"full_anonymization": "Full anonymization",
"full_anonymization_description": "Creates a copy of the database with all note content removed, leaving only structure and non-sensitive metadata. Safe for sharing online when debugging issues.",
"save_fully_anonymized_database": "Save fully anonymized database",
"light_anonymization": "Light Anonymization",
"light_anonymization_description": "This action will create a new copy of the database and do a light anonymization on it — specifically only content of all notes will be removed, but titles and attributes will remain. Additionally, custom JS frontend/backend script notes and custom widgets will remain. This provides more context to debug the issues.",
"light_anonymization": "Light anonymization",
"light_anonymization_description": "Creates a copy with note content removed, but titles, attributes, and custom scripts/widgets remain. Provides more context for debugging.",
"choose_anonymization": "You can decide yourself if you want to provide a fully or lightly anonymized database. Even fully anonymized DB is very useful, however in some cases lightly anonymized database can speed up the process of bug identification and fixing.",
"save_lightly_anonymized_database": "Save lightly anonymized database",
"existing_anonymized_databases": "Existing anonymized databases",
@@ -1144,7 +1199,8 @@
},
"database_integrity_check": {
"title": "Database Integrity Check",
"description": "This will check that the database is not corrupted on the SQLite level. It might take some time, depending on the DB size.",
"check_integrity_label": "Check database integrity",
"check_integrity_description": "Verify that the database is not corrupted on the SQLite level.",
"check_button": "Check database integrity",
"checking_integrity": "Checking database integrity...",
"integrity_check_succeeded": "Integrity check succeeded - no problems found.",
@@ -1152,7 +1208,11 @@
},
"sync": {
"title": "Sync",
"force_full_sync_label": "Force full sync",
"force_full_sync_description": "Trigger a complete synchronization with the sync server, re-uploading all changes.",
"force_full_sync_button": "Force full sync",
"fill_entity_changes_label": "Fill entity changes",
"fill_entity_changes_description": "Rebuild entity change records. Use this if sync is missing some changes.",
"fill_entity_changes_button": "Fill entity changes records",
"full_sync_triggered": "Full sync triggered",
"filling_entity_changes": "Filling entity changes rows...",
@@ -1160,8 +1220,13 @@
"finished-successfully": "Sync finished successfully.",
"failed": "Sync failed: {{message}}"
},
"database": {
"title": "Database"
},
"vacuum_database": {
"title": "Vacuum Database",
"vacuum_label": "Vacuum database",
"vacuum_description": "Rebuild the database to reduce file size. No data will be changed.",
"description": "This will rebuild the database which will typically result in a smaller database file. No data will be actually changed.",
"button_text": "Vacuum database",
"vacuuming_database": "Vacuuming database...",
@@ -1178,16 +1243,18 @@
"fonts": {
"theme_defined": "Theme defined",
"fonts": "Fonts",
"main_font": "Main Font",
"custom_fonts": "Use custom fonts",
"main_font": "Interface text",
"font_family": "Font family",
"size": "Size",
"note_tree_font": "Note Tree Font",
"note_detail_font": "Note Detail Font",
"monospace_font": "Monospace (code) Font",
"note_tree_and_detail_font_sizing": "Note that tree and detail font sizing is relative to the main font size setting.",
"not_all_fonts_available": "Not all listed fonts may be available on your system.",
"apply_font_changes": "To apply font changes, click on",
"reload_frontend": "reload frontend",
"preview": "Preview",
"note_tree_font": "Note tree text",
"note_detail_font": "Document text",
"monospace_font": "Monospace text",
"monospace_font_description": "Used for code notes and code blocks",
"size_relative_to_general": "Size is relative to the general font size",
"not_all_fonts_available": "Not all listed fonts may be available on your system",
"apply_changes": "Reload to apply changes",
"generic-fonts": "Generic fonts",
"sans-serif-system-fonts": "Sans-serif system fonts",
"serif-system-fonts": "Serif system fonts",
@@ -1216,15 +1283,18 @@
"edited_notes_message": "Edited Notes ribbon tab will automatically open on day notes"
},
"theme": {
"title": "Application Theme",
"theme_label": "Theme",
"title": "User Interface",
"theme_label": "Application theme",
"override_theme_fonts_label": "Override theme fonts",
"auto_theme": "Legacy (Follow system color scheme)",
"light_theme": "Legacy (Light)",
"dark_theme": "Legacy (Dark)",
"triliumnext": "Trilium (Follow system color scheme)",
"triliumnext-light": "Trilium (Light)",
"triliumnext-dark": "Trilium (Dark)",
"auto_theme": "Follow system color scheme",
"light_theme": "Light",
"dark_theme": "Dark",
"triliumnext": "Follow system color scheme",
"triliumnext-light": "Light",
"triliumnext-dark": "Dark",
"modern_themes": "Modern",
"legacy_themes": "Legacy",
"custom_themes": "Custom",
"layout": "Layout",
"layout-vertical-title": "Vertical",
"layout-horizontal-title": "Horizontal",
@@ -1233,11 +1303,11 @@
},
"ui-performance": {
"title": "Performance",
"enable-motion": "Enable transitions and animations",
"enable-shadows": "Enable shadows",
"enable-backdrop-effects": "Enable background effects for menus, popups and panels",
"enable-smooth-scroll": "Enable smooth scrolling",
"app-restart-required": "(a restart of the application is required for the change to take effect)"
"enable-motion": "Transitions and animations",
"enable-shadows": "Shadows",
"enable-backdrop-effects": "Background effects for menus, popups and panels",
"enable-smooth-scroll": "Smooth scrolling",
"app-restart-required": "Requires app restart"
},
"zoom_factor": {
"title": "Zoom Factor (desktop build only)",
@@ -1246,11 +1316,13 @@
"code_auto_read_only_size": {
"title": "Automatic Read-Only Size",
"description": "Automatic read-only note size is the size after which notes will be displayed in a read-only mode (for performance reasons).",
"label": "Automatic read-only size (code notes)",
"label": "Automatic read-only size",
"unit": "characters"
},
"code-editor-options": {
"title": "Editor"
"title": "Editor",
"tab_width": "Tab width",
"tab_width_unit": "spaces"
},
"code_mime_types": {
"title": "Available MIME types in the dropdown",
@@ -1292,58 +1364,80 @@
"batch_ocr_error": "Error during batch processing: {{error}}"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Attachment Erasure Timeout",
"attachment_auto_deletion_description": "Attachments get automatically deleted (and erased) if they are not referenced by their note anymore after a defined time out.",
"erase_attachments_after": "Erase unused attachments after:",
"manual_erasing_description": "You can also trigger erasing manually (without considering the timeout defined above):",
"erase_unused_attachments_now": "Erase unused attachment notes now",
"attachment_erasure_timeout": "Unused Attachments",
"description": "Attachments that are no longer referenced by any note are considered unused and can be automatically erased after a period of time.",
"erase_attachments_after": "Erase unused attachments after",
"erase_attachments_after_description": "Time before unused attachments are permanently erased.",
"manual_erasing_description": "Trigger erasing manually, ignoring the timeout above.",
"erase_unused_attachments_now": "Erase unused attachments now",
"unused_attachments_erased": "Unused attachments have been erased."
},
"network_connections": {
"network_connections_title": "Network Connections",
"check_for_updates": "Check for updates automatically"
"network_connections_title": "Network",
"check_for_updates": "Check for updates automatically",
"check_for_updates_description": "Checks for new versions on GitHub and shows a notification in the global menu when available."
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Note Erasure Timeout",
"note_erasure_description": "Deleted notes (and attributes, revisions...) are at first only marked as deleted and it is possible to recover them from Recent Notes dialog. After a period of time, deleted notes are \"erased\" which means their content is not recoverable anymore. This setting allows you to configure the length of the period between deleting and erasing the note.",
"erase_notes_after": "Erase notes after:",
"manual_erasing_description": "You can also trigger erasing manually (without considering the timeout defined above):",
"note_erasure_timeout_title": "Deleted Notes",
"description": "Deleted notes are first only marked as deleted and can be recovered from Recent Notes. After a period of time, they are permanently erased.",
"erase_notes_after": "Erase notes after",
"erase_notes_after_description": "Time before deleted notes are permanently erased.",
"manual_erasing_description": "Trigger erasing manually, ignoring the timeout above.",
"erase_deleted_notes_now": "Erase deleted notes now",
"deleted_notes_erased": "Deleted notes have been erased."
},
"revisions_snapshot": {
"title": "Note Revisions"
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "Note Revision Snapshot Interval",
"note_revisions_snapshot_description": "The Note revision snapshot interval is the time after which a new note revision will be created for the note. See <doc>wiki</doc> for more info.",
"snapshot_time_interval_label": "Note revision snapshot time interval:"
"note_revisions_snapshot_description_short": "Time after which a new note revision will be created.",
"snapshot_time_interval_label": "Snapshot interval"
},
"revisions_snapshot_limit": {
"note_revisions_snapshot_limit_title": "Note Revision Snapshot Limit",
"note_revisions_snapshot_limit_description": "The note revision snapshot number limit refers to the maximum number of revisions that can be saved for each note. Where -1 means no limit, 0 means delete all revisions. You can set the maximum revisions for a single note through the #versioningLimit label.",
"snapshot_number_limit_label": "Note revision snapshot number limit:",
"note_revisions_snapshot_limit_description_short": "Max revisions per note. Use -1 for unlimited, 0 to disable.",
"snapshot_number_limit_label": "Maximum revisions",
"snapshot_number_limit_unit": "snapshots",
"erase_excess_revision_snapshots": "Erase excess revision snapshots now",
"erase_excess_revision_snapshots_description": "Delete revisions exceeding the limit for all notes.",
"erase_excess_revision_snapshots_prompt": "Excess revision snapshots have been erased."
},
"search": {
"title": "Search",
"fuzzy_matching_label": "Typo tolerance in search",
"fuzzy_matching_description": "Affects quick search and full search. Finds similar words when exact matches are insufficient.",
"autocomplete_fuzzy_label": "Typo tolerance in autocomplete",
"autocomplete_fuzzy_description": "Affects jump-to-note and note selectors. Slower but tolerates typos."
},
"search_engine": {
"title": "Search Engine",
"custom_search_engine_info": "Custom search engine requires both a name and a URL to be set. If either of these is not set, DuckDuckGo will be used as the default search engine.",
"predefined_templates_label": "Predefined search engine templates",
"custom_search_engine_info": "Used when searching the web for selected text. If not configured, DuckDuckGo will be used.",
"predefined_templates_label": "Presets",
"bing": "Bing",
"baidu": "Baidu",
"duckduckgo": "DuckDuckGo",
"google": "Google",
"custom_name_label": "Custom search engine name",
"custom_name_placeholder": "Customize search engine name",
"custom_url_label": "Custom search engine URL should include {keyword} as a placeholder for the search term.",
"custom_url_placeholder": "Customize search engine URL",
"custom_name_label": "Name",
"custom_name_placeholder": "Search engine name",
"custom_url_label": "URL",
"custom_url_description": "Use {keyword} as a placeholder for the search term.",
"custom_url_placeholder": "Search engine URL",
"save_button": "Save"
},
"tray": {
"title": "System Tray",
"enable_tray": "Enable tray (Trilium needs to be restarted for this change to take effect)"
"enable_tray": "Tray icon",
"enable_tray_description": "Trilium needs to be restarted for this change to take effect."
},
"text_editor": {
"title": "Editor"
},
"heading_style": {
"title": "Heading Style",
"title": "Heading style",
"description": "Visual style for headings in text notes.",
"plain": "Plain",
"underline": "Underline",
"markdown": "Markdown-style"
@@ -1370,14 +1464,16 @@
"text_auto_read_only_size": {
"title": "Automatic Read-Only Size",
"description": "Automatic read-only note size is the size after which notes will be displayed in a read-only mode (for performance reasons).",
"label": "Automatic read-only size (text notes)",
"label": "Automatic read-only size",
"unit": "characters"
},
"custom_date_time_format": {
"title": "Custom Date/Time Format",
"title": "Date/time format",
"description": "Customize the format of the date and time inserted via <shortcut /> or the toolbar. See <doc>Day.js docs</doc> for available format tokens.",
"format_string": "Format string:",
"formatted_time": "Formatted date/time:"
"description_short": "Customize the format of the date and time inserted via the toolbar.",
"preview": "Preview: {{preview}}",
"format_string": "Format string",
"formatted_time": "Formatted date/time"
},
"i18n": {
"title": "Localization",
@@ -1392,20 +1488,20 @@
"sunday": "Sunday",
"first-week-of-the-year": "First week of the year",
"first-week-contains-first-day": "First week contains first day of the year",
"first-week-contains-first-thursday": "First week contains first Thursday of the year",
"first-week-contains-first-thursday": "First week contains first Thursday (ISO 8601)",
"first-week-has-minimum-days": "First week has minimum days",
"min-days-in-first-week": "Minimum days in first week",
"first-week-info": "First week contains first Thursday of the year is based on <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> standard.",
"first-week-warning": "Changing first week options may cause duplicate with existing Week Notes and the existing Week Notes will not be updated accordingly.",
"first-week-warning": "Changing this may cause duplicates with existing Week Notes.",
"formatting-locale": "Date & number format",
"formatting-locale-auto": "Based on the application's language"
},
"backup": {
"title": "Backup",
"automatic_backup": "Automatic backup",
"automatic_backup_description": "Trilium can back up the database automatically:",
"enable_daily_backup": "Enable daily backup",
"enable_weekly_backup": "Enable weekly backup",
"enable_monthly_backup": "Enable monthly backup",
"enable_daily_backup": "Backup daily",
"enable_weekly_backup": "Backup weekly",
"enable_monthly_backup": "Backup monthly",
"backup_recommendation": "It's recommended to keep the backup turned on, but this can make application startup slow with large databases and/or slow storage devices.",
"backup_now": "Backup now",
"backup_database_now": "Backup database now",
@@ -1449,11 +1545,15 @@
"new_password": "New password",
"new_password_confirmation": "New password confirmation",
"change_password": "Change password",
"protected_session_timeout": "Protected Session Timeout",
"protected_session_timeout_description": "Protected session timeout is a time period after which the protected session is wiped from the browser's memory. This is measured from the last interaction with protected notes. See",
"change_password_description": "Update your current password",
"reset_password": "Reset password",
"reset_password_description": "Permanently lose access to protected notes",
"cancel": "Cancel",
"protected_session_timeout": "Protected Session",
"protected_session_timeout_description": "Time of inactivity before the session is cleared from browser memory. See",
"wiki": "wiki",
"for_more_info": "for more info.",
"protected_session_timeout_label": "Protected session timeout:",
"protected_session_timeout_label": "Auto-close session after",
"reset_confirmation": "By resetting the password you will forever lose access to all your existing protected notes. Do you really want to reset the password?",
"reset_success_message": "Password has been reset. Please set new password",
"change_password_heading": "Change Password",
@@ -1523,18 +1623,17 @@
"related_description": "Configure spell check languages and custom dictionary."
},
"sync_2": {
"config_title": "Sync Configuration",
"server_address": "Server instance address",
"timeout": "Sync timeout",
"timeout_description": "How long to wait before giving up on a slow sync connection. Increase if you have an unstable network.",
"proxy_label": "Sync proxy server (optional)",
"note": "Note",
"note_description": "If you leave the proxy setting blank, the system proxy will be used (applies to desktop/electron build only).",
"special_value_description": "Another special value is <code>noproxy</code> which forces ignoring even the system proxy and respects <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"config_title": "Sync Server",
"server_address": "Server address",
"server_address_description": "URL of the Trilium server to sync with.",
"timeout": "Connection timeout",
"timeout_description": "Time to wait before giving up on a slow connection.",
"proxy_label": "Proxy server",
"proxy_description": "Leave blank to use system proxy (desktop only). Use \"noproxy\" to bypass all proxies.",
"save": "Save",
"help": "Help",
"test_title": "Sync Test",
"test_description": "This will test the connection and handshake to the sync server. If the sync server isn't initialized, this will set it up to sync with the local document.",
"test_title": "Test Connection",
"test_description": "Test the connection to the sync server. If not initialized, this will set up syncing.",
"test_button": "Test sync",
"handshake_failed": "Sync server handshake failed, error: {{message}}"
},
@@ -1617,6 +1716,7 @@
"note_types": {
"text": "Text",
"code": "Code",
"markdown": "Markdown",
"saved-search": "Saved Search",
"relation-map": "Relation Map",
"note-map": "Note Map",
@@ -1759,7 +1859,7 @@
"note_detail": {
"could_not_find_typewidget": "Could not find typeWidget for type '{{type}}'",
"printing": "Printing in progress...",
"printing_pdf": "Exporting to PDF in progress...",
"printing_pdf": "Preparing print preview...",
"print_report_title": "Print report",
"print_report_error_title": "Failed to print",
"print_report_stack_trace": "Stack trace",
@@ -1837,6 +1937,8 @@
},
"entrypoints": {
"note-revision-created": "Note revision has been created.",
"save-named-revision-title": "Save named revision",
"save-named-revision-message": "Enter a name for this revision (leave empty for no name):",
"note-executed": "Note executed.",
"sql-error": "Error occurred while executing SQL query: {{message}}"
},
@@ -1874,6 +1976,9 @@
"move-to-available-launchers": "Move to available launchers",
"duplicate-launcher": "Duplicate launcher <kbd data-command=\"duplicateSubtree\">"
},
"launcher_button_context_menu": {
"remove_from_launch_bar": "Remove from launch bar"
},
"highlighting": {
"title": "Code Blocks",
"description": "Controls the syntax highlighting for code blocks inside text notes, code notes will not be affected.",
@@ -1885,7 +1990,9 @@
"theme_group_light": "Light themes",
"theme_group_dark": "Dark themes",
"copy_title": "Copy to clipboard",
"click_to_copy": "Click to copy"
"click_to_copy": "Click to copy",
"tab_width": "Tab width",
"tab_width_unit": "spaces"
},
"classic_editor_toolbar": {
"title": "Formatting"
@@ -1896,6 +2003,7 @@
"editing": {
"editor_type": {
"label": "Formatting toolbar",
"toolbar_style": "Toolbar style",
"floating": {
"title": "Floating",
"description": "editing tools appear near the cursor;"
@@ -1904,7 +2012,7 @@
"title": "Fixed",
"description": "editing tools appear in the \"Formatting\" ribbon tab."
},
"multiline-toolbar": "Display the toolbar on multiple lines if it doesn't fit."
"multiline-toolbar": "Display the toolbar on multiple lines if it doesn't fit"
}
},
"electron_context_menu": {
@@ -1922,6 +2030,9 @@
"copy_reference_to_clipboard": "Copy reference to clipboard",
"copy_image_to_clipboard": "Copy image to clipboard"
},
"link": {
"failed_to_open": "Failed to open link '{{- href}}': {{- message}}"
},
"link_context_menu": {
"open_note_in_new_tab": "Open note in a new tab",
"open_note_in_new_split": "Open note in a new split",
@@ -1971,7 +2082,7 @@
"days": "Days"
},
"share": {
"title": "Share Settings",
"title": "Share",
"redirect_bare_domain": "Redirect bare domain to Share page",
"redirect_bare_domain_description": "Redirect anonymous users to the Share page instead of showing Login",
"show_login_link": "Show Login link in Share theme",
@@ -2012,6 +2123,11 @@
"unlock-editing": "Unlock editing",
"lock-editing": "Lock editing"
},
"display_mode": {
"source": "Source view",
"split": "Split view",
"preview": "Preview"
},
"png_export_button": {
"button_title": "Export diagram as PNG"
},
@@ -2035,12 +2151,12 @@
},
"editorfeatures": {
"title": "Features",
"emoji_completion_enabled": "Enable Emoji auto-completion",
"emoji_completion_description": "If enabled, emojis can be easily inserted into text by typing `:`, followed by the name of an emoji.",
"note_completion_enabled": "Enable note auto-completion",
"note_completion_description": "If enabled, links to notes can be created by typing `@` followed by the title of a note.",
"slash_commands_enabled": "Enable slash commands",
"slash_commands_description": "If enabled, editing commands such as inserting line breaks or headings can be toggled by typing `/`."
"emoji_completion_enabled": "Emoji auto-completion",
"emoji_completion_description": "Emojis can be easily inserted into text by typing `:`, followed by the name of an emoji.",
"note_completion_enabled": "Note auto-completion",
"note_completion_description": "Links to notes can be created by typing `@` followed by the title of a note.",
"slash_commands_enabled": "Slash commands",
"slash_commands_description": "Editing commands such as inserting line breaks or headings can be toggled by typing `/`."
},
"table_view": {
"new-row": "New row",
@@ -2159,6 +2275,8 @@
"related_code_blocks": "Color scheme for code blocks in text notes",
"related_code_notes": "Color scheme for code notes",
"ui": "User interface",
"ui_layout_style": "Layout style",
"ui_layout_orientation": "Launcher bar orientation",
"ui_old_layout": "Old layout",
"ui_new_layout": "New layout"
},
@@ -2241,7 +2359,19 @@
"note_paths_one": "{{count}} path",
"note_paths_other": "{{count}} paths",
"note_paths_title": "Note paths",
"code_note_switcher": "Change language mode"
"code_note_switcher": "Change language mode",
"tab_width": "Tab Width: {{width}}",
"tab_width_title": "Change tab width",
"tab_width_spaces": "{{count}} spaces",
"tab_width_spaces_short": "Spaces: {{width}}",
"tab_width_tabs": "Tabs: {{width}}",
"tab_width_use_default": "Use default ({{width}})",
"tab_width_use_default_style": "Use default ({{style}})",
"tab_width_display_header": "Display width",
"tab_width_reindent_header": "Re-indent content to",
"tab_width_style_header": "Indent using",
"tab_width_style_spaces": "Spaces",
"tab_width_style_tabs": "Tabs"
},
"attributes_panel": {
"title": "Note Attributes"
@@ -2252,6 +2382,37 @@
"toggle": "Toggle right panel",
"custom_widget_go_to_source": "Go to source code"
},
"print_preview": {
"title": "Print preview",
"close": "Close",
"save": "Save as PDF",
"print": "Print",
"export_pdf": "Export as PDF",
"system_print": "Print using system dialog",
"destination": "Destination",
"destination_pdf": "Save as PDF",
"destination_printers": "Printers",
"destination_default": "Default",
"orientation": "Orientation",
"portrait": "Portrait",
"landscape": "Landscape",
"page_size": "Page size",
"scale": "Scale",
"margins": "Margins",
"render_error": "Unable to render PDF with the current settings. Please check the margins and scale.",
"margins_default": "Default",
"margins_none": "None",
"margins_minimum": "Minimum",
"margins_custom": "Custom",
"margin_top": "Top",
"margin_right": "Right",
"margin_bottom": "Bottom",
"margin_left": "Left",
"page_ranges": "Pages",
"page_ranges_hint": "Leave empty to print all pages.",
"page_ranges_invalid": "Invalid format. Use e.g. 1-5, 8, 11-13.",
"page_ranges_placeholder": "e.g. 1-5, 8, 11-13"
},
"pdf": {
"attachments_one": "{{count}} attachment",
"attachments_other": "{{count}} attachments",
@@ -2439,5 +2600,9 @@
"move_note": "Move note",
"clone_note": "Clone note"
}
},
"common": {
"save": "Save",
"cancel": "Cancel"
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Acerca de Trilium Notes",
"homepage": "Página principal:",
"app_version": "Versión de la aplicación:",
"db_version": "Versión de base de datos:",
"sync_version": "Versión de sincronización:",
"build_date": "Fecha de creación:",
"build_revision": "Revisión de compilación:",
"data_directory": "Directorio de datos:"
},
"toast": {
@@ -90,12 +83,22 @@
"delete_notes": {
"close": "Cerrar",
"delete_all_clones_description": "Eliminar también todos los clones (se puede deshacer en cambios recientes)",
"erase_notes_description": "La eliminación normal (suave) solo marca las notas como eliminadas y se pueden recuperar (en el cuadro de diálogo de cambios recientes) dentro de un periodo de tiempo. Al marcar esta opción se borrarán las notas inmediatamente y no será posible recuperarlas.",
"erase_notes_description": "Borrar notas inmediatamente en lugar de la eliminación con respaldo. Esto no se puede deshacer y forzará la recarga de la aplicación.",
"erase_notes_warning": "Eliminar notas permanentemente (no se puede deshacer), incluidos todos los clones. Esto forzará la recarga de la aplicación.",
"notes_to_be_deleted": "Las siguientes notas serán eliminadas ({{notesCount}})",
"notes_to_be_deleted": "Notas a ser eliminadas ({{notesCount}})",
"no_note_to_delete": "No se eliminará ninguna nota (solo clones).",
"broken_relations_to_be_deleted": "Las siguientes relaciones se romperán y serán eliminadas ({{ relationCount}})",
"cancel": "Cancelar"
"broken_relations_to_be_deleted": "Relaciones rotas ({{ relationCount}})",
"cancel": "Cancelar",
"title": "Eliminar notas",
"clones_label": "Clones",
"delete_clones_description_one": "También eliminar otro clon. Puede deshacerse en los cambios recientes.",
"delete_clones_description_many": "También eliminar otros {{count}} clones. Puede deshacerse en los cambios recientes.",
"delete_clones_description_other": "También eliminar otros {{count}} clones. Puede deshacerse en los cambios recientes.",
"erase_notes_label": "Borrar permanentemente",
"table_note_with_relation": "Nota con relación",
"table_relation": "Relación",
"table_points_to": "Apunta a (eliminado)",
"delete": "Eliminar"
},
"export": {
"export_note_title": "Exportar nota",
@@ -206,7 +209,8 @@
"box_size_small": "pequeño (~ 10 líneas)",
"box_size_medium": "medio (~ 30 líneas)",
"box_size_full": "completo (el cuadro muestra el texto completo)",
"button_include": "Incluir nota"
"button_include": "Incluir nota",
"box_size_expandable": "expandible (colapsado por defecto)"
},
"info": {
"modalTitle": "Mensaje informativo",
@@ -267,33 +271,6 @@
"undelete_link": "recuperar",
"confirm_undelete": "¿Quiere recuperar esta nota y sus subnotas?"
},
"revisions": {
"note_revisions": "Revisiones de nota",
"delete_all_revisions": "Eliminar todas las revisiones de esta nota",
"delete_all_button": "Eliminar todas las revisiones",
"help_title": "Ayuda sobre revisiones de notas",
"confirm_delete_all": "¿Quiere eliminar todas las revisiones de esta nota?",
"no_revisions": "Aún no hay revisiones para esta nota...",
"restore_button": "Restaurar",
"confirm_restore": "¿Quiere restaurar esta revisión? Esto sobrescribirá el título actual y el contenido de la nota con esta revisión.",
"delete_button": "Eliminar",
"confirm_delete": "¿Quieres eliminar esta revisión?",
"revisions_deleted": "Se han eliminado las revisiones de nota.",
"revision_restored": "Se ha restaurado la revisión de nota.",
"revision_deleted": "Se ha eliminado la revisión de la nota.",
"snapshot_interval": "Intervalo de respaldo de revisiones de nota: {{seconds}}s.",
"maximum_revisions": "Máximo de revisiones para la nota actual: {{number}}.",
"settings": "Ajustes para revisiones de nota",
"download_button": "Descargar",
"mime": "MIME: ",
"file_size": "Tamaño del archivo:",
"preview_not_available": "La vista previa no está disponible para este tipo de notas.",
"diff_off": "Mostrar contenido",
"diff_on": "Mostrar diferencia",
"diff_off_hint": "Haga clic para mostrar el contenido de la nota",
"diff_not_available": "Diferencias no disponibles.",
"diff_on_hint": "Haga clic para ver las diferencias"
},
"sort_child_notes": {
"sort_children_by": "Ordenar hijos por...",
"sorting_criteria": "Criterios de ordenamiento",
@@ -365,7 +342,7 @@
"calendar_root": "marca la nota que debe usarse como raíz para las notas del día. Sólo uno debe estar marcado como tal.",
"archived": "las notas con esta etiqueta no serán visibles de forma predeterminada en los resultados de búsqueda (tampoco en los cuadros de diálogo Saltar a, Agregar vínculo, etc.).",
"exclude_from_export": "las notas (con su subárbol) no se incluirán en ninguna exportación de notas",
"run": "define en qué eventos debe ejecutarse el script. Los valores posibles son:\n<ul>\n<li>frontendStartup - cuando Trilium frontend se inicia (o se actualiza), pero no en móvil.</li>\n<li>mobileStartup - cuando Trilium frontend se inicia (o se actualiza), en móvil.</li>\n<li>backendStartup - cuando Trilium backend se inicia</li>\n<li>hourly - se ejecuta una vez por hora. Se puede usar la etiqueta adicional <code>runAtHour</code> para especificar a qué hora.</li>\n<li>daily - se ejecuta una vez al día</li>\n</ul>",
"run": "define en qué eventos debe ejecutarse el script. Los valores posibles son:\n<ul>\n<li>frontendStartup - cuando el frontend de Trilium se inicia (o se actualiza), pero no en móvil.</li>\n<li>mobileStartup - cuando el frontend de Trilium se inicia (o se actualiza), en móvil.</li>\n<li>backendStartup - cuando el backend de Trilium se inicia</li>\n<li>hourly - se ejecuta una vez por hora. Se puede usar la etiqueta adicional <code>runAtHour</code> para especificar a qué hora.</li>\n<li>daily - se ejecuta una vez al día</li>\n</ul>",
"run_on_instance": "Definir en qué instancia de Trilium se debe ejecutar esto. Predeterminado para todas las instancias.",
"run_at_hour": "¿A qué hora debería funcionar? Debe usarse junto con <code>#run=hourly</code>. Se puede definir varias veces para varias ejecuciones durante el día.",
"disable_inclusion": "los scripts con esta etiqueta no se incluirán en la ejecución del script principal.",
@@ -443,7 +420,10 @@
"and_more": "... y {{count}} más.",
"print_landscape": "Al exportar a PDF, cambia la orientación de la página a paisaje en lugar de retrato.",
"print_page_size": "Al exportar a PDF, cambia el tamaño de la página. Valores soportados: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.",
"color_type": "Color"
"color_type": "Color",
"textarea": "Texto multilínea",
"print_scale": "Al exportar a PDF, cambia la escala del contenido renderizado. Los valores varían de 0.1 (10%) a 2 (200%), por defecto es 1 (100%).",
"print_margins": "Al exportar a PDF, establece márgenes de página. Use <code>default</code>, <code>none</code>, <code>minimum</code>, o valores personalizados como <code>top,right,bottom,left</code> en milímetros."
},
"attribute_editor": {
"help_text_body1": "Para agregar una etiqueta, simplemente escriba, por ejemplo. <code>#rock</code> o si desea agregar también valor, p.e. <code>#año = 2020</code>",
@@ -705,7 +685,12 @@
"export_as_image": "Exportar como imagen",
"export_as_image_png": "PNG (ráster)",
"export_as_image_svg": "SVG (vectorial)",
"note_map": "Mapa de la nota"
"note_map": "Mapa de la nota",
"view_ocr_text": "Ver texto OCR",
"word_wrap_auto": "Automático",
"word_wrap_auto_description": "Seguir el ajuste global",
"word_wrap_on": "Encendido",
"word_wrap_off": "Apagado"
},
"onclick_button": {
"no_click_handler": "El widget de botón '{{componentId}}' no tiene un controlador de clics definido"
@@ -803,7 +788,13 @@
"expand_first_level": "Expandir hijos inmediatos",
"expand_nth_level": "Expandir {{depth}} niveles",
"expand_all_levels": "Expandir todos los niveles",
"hide_child_notes": "Ocultar subnotas en el árbol"
"hide_child_notes": "Ocultar subnotas en el árbol",
"open_all_in_tabs": "Abrir todo",
"open_all_in_tabs_tooltip": "Abrir todos los resultados en nuevas pestañas",
"open_all_confirm": "Esto abrirá {{count}} notas en nuevas pestañas. ¿Continuar?",
"open_all_too_one": " ",
"open_all_too_many": " ",
"open_all_too_other": " "
},
"edited_notes": {
"no_edited_notes_found": "Aún no hay notas editadas en este día...",
@@ -857,7 +848,8 @@
"collapse": "Contraer al tamaño normal",
"title": "Mapa de notas",
"fix-nodes": "Fijar nodos",
"link-distance": "Distancia de enlace"
"link-distance": "Distancia de enlace",
"too-many-notes": "Este subárbol contiene {{count}} notas, lo que excede el límite de {{max}} que se puede mostrar en el mapa de notas."
},
"note_paths": {
"title": "Rutas de nota",
@@ -1062,7 +1054,8 @@
"note_already_in_diagram": "La nota \"{{title}}\" ya está en el diagrama.",
"enter_title_of_new_note": "Ingrese el título de la nueva nota",
"default_new_note_title": "nueva nota",
"click_on_canvas_to_place_new_note": "Haga clic en el lienzo para colocar una nueva nota"
"click_on_canvas_to_place_new_note": "Haga clic en el lienzo para colocar una nueva nota",
"rename_relation": "Renombrar relación"
},
"backend_log": {
"refresh": "Refrescar"
@@ -1071,15 +1064,17 @@
"title": "Comprobación de coherencia",
"find_and_fix_button": "Buscar y solucionar problemas de coherencia",
"finding_and_fixing_message": "Buscando y solucionando problemas de coherencia...",
"issues_fixed_message": "Los problemas de coherencia han sido solucionados."
"issues_fixed_message": "Los problemas de coherencia han sido solucionados.",
"find_and_fix_label": "Buscar y solucionar problemas de coherencia",
"find_and_fix_description": "Escanear y reparar automáticamente cualquier problema de consistencia de datos en la base de datos."
},
"database_anonymization": {
"title": "Anonimización de bases de datos",
"full_anonymization": "Anonimización total",
"full_anonymization_description": "Esta acción crea una nueva copia de la base de datos y la anonimizará (eliminará todo el contenido de las notas y deja solo la estructura y algunos metadatos no confidenciales) para compartirla en línea con fines de depuración sin temor a filtrar sus datos personales.",
"full_anonymization_description": "Crea una copia de la base de datos con todo el contenido eliminado, dejando solo la estructura y algunos metadatos no confidenciales. Seguro para compartirla en línea con fines de depuración de problemas.",
"save_fully_anonymized_database": "Guarde la base de datos completamente anónima",
"light_anonymization": "Anonimización ligera",
"light_anonymization_description": "Esta acción crea una nueva copia de la base de datos y realizará una ligera anonimización en ella; específicamente, solo se eliminará el contenido de todas las notas, pero los títulos y atributos permanecerán. Además, se mantendrán las notas de script JS frontend/backend personalizadas y los widgets personalizados. Esto proporciona más contexto para depurar los problemas.",
"light_anonymization_description": "Crea una copia con el contenido de las notas eliminado, excepto los títulos, atributos y scripts/widgets personalizados que permanecerán. Esto proporciona más contexto para el depurado.",
"choose_anonymization": "Puede decidir usted mismo si desea proporcionar una base de datos total o ligeramente anónima. Incluso una base de datos totalmente anónima es muy útil; sin embargo, en algunos casos, una base de datos ligeramente anónima puede acelerar el proceso de identificación y corrección de errores.",
"save_lightly_anonymized_database": "Guarde una base de datos ligeramente anónima",
"existing_anonymized_databases": "Bases de datos anónimas existentes",
@@ -1088,15 +1083,17 @@
"error_creating_anonymized_database": "No se pudo crear una base de datos anónima; consulte los registros de backend para obtener más detalles",
"successfully_created_fully_anonymized_database": "Se creó una base de datos completamente anónima en {{anonymizedFilePath}}",
"successfully_created_lightly_anonymized_database": "Se creó una base de datos ligeramente anónima en {{anonymizedFilePath}}",
"no_anonymized_database_yet": "Aún no hay base de datos anónima."
"no_anonymized_database_yet": "Aún no hay base de datos anónima.",
"description": "Crear una copia anónima de su base de datos para compartir con los desarrolladores cuando depuren problemas, sin exponer datos personales."
},
"database_integrity_check": {
"title": "Verificación de integridad de la base de datos",
"description": "Esto verificará que la base de datos no esté dañada en el nivel SQLite. Puede que tarde algún tiempo, dependiendo del tamaño de la base de datos.",
"check_button": "Verificar la integridad de la base de datos",
"checking_integrity": "Comprobando la integridad de la base de datos...",
"integrity_check_succeeded": "La verificación de integridad fue exitosa; no se encontraron problemas.",
"integrity_check_failed": "La verificación de integridad falló: {{results}}"
"integrity_check_failed": "La verificación de integridad falló: {{results}}",
"check_integrity_label": "Verificar la integridad de la base de datos",
"check_integrity_description": "Verifcar que la base de datos no está dañada en el nivel SQLite."
},
"sync": {
"title": "Sincronizar",
@@ -1106,7 +1103,10 @@
"filling_entity_changes": "Rellenar filas de cambios de entidad...",
"sync_rows_filled_successfully": "Sincronizar filas completadas correctamente",
"finished-successfully": "La sincronización finalizó exitosamente.",
"failed": "La sincronización falló: {{message}}"
"failed": "La sincronización falló: {{message}}",
"force_full_sync_label": "Forzar sincronización completa",
"force_full_sync_description": "Activa una sincronización completa con el servidor de sincronización, resubiendo todos los cambios.",
"fill_entity_changes_label": "Llenar cambios de entidad"
},
"vacuum_database": {
"title": "Limpiar base de datos",
@@ -1124,10 +1124,7 @@
"note_tree_font": "Fuente del árbol de notas",
"note_detail_font": "Fuente de detalle de nota",
"monospace_font": "Fuente Monospace (código)",
"note_tree_and_detail_font_sizing": "Tenga en cuenta que el tamaño de fuente del árbol y de los detalles es relativo a la configuración del tamaño de fuente principal.",
"not_all_fonts_available": "Es posible que no todas las fuentes enumeradas estén disponibles en su sistema.",
"apply_font_changes": "Para aplicar cambios de fuente, haga clic en",
"reload_frontend": "recargar la interfaz",
"not_all_fonts_available": "Es posible que no todas las fuentes enumeradas estén disponibles en su sistema",
"generic-fonts": "Fuentes genéricas",
"sans-serif-system-fonts": "Fuentes Sans-serif del sistema",
"serif-system-fonts": "Fuentes Serif del sistema",
@@ -1200,18 +1197,20 @@
},
"images": {
"images_section_title": "Imágenes",
"download_images_automatically": "Descargar imágenes automáticamente para usarlas sin conexión.",
"download_images_automatically": "Descargar imágenes automáticamente",
"download_images_description": "El HTML pegado puede contener referencias a imágenes en línea; Trilium encontrará esas referencias y descargará las imágenes para que estén disponibles sin conexión.",
"enable_image_compression": "Habilitar la compresión de imágenes",
"max_image_dimensions": "Ancho/alto máximo de una imagen en píxeles (la imagen cambiará de tamaño si excede esta configuración).",
"max_image_dimensions": "Dimensiones máximas de imagen",
"max_image_dimensions_unit": "píxeles",
"jpeg_quality_description": "Calidad JPEG (10 - peor calidad, 100 - mejor calidad, se recomienda 50 - 85)"
"jpeg_quality_description": "Se recomienda un rango 50-85. Valores más pequeños reducen el tamaño del archivo, valores más altos preservan los detalles.",
"enable_image_compression_description": "Comprimir y ajustar el tamaño de las imágenes cuando son subidas o pegadas.",
"max_image_dimensions_description": "Las imágenes que excedan el límite de tamaño serán ajustadas automáticamente.",
"jpeg_quality": "Calidad JPEG"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Tiempo de espera para borrar archivos adjuntos",
"attachment_auto_deletion_description": "Los archivos adjuntos se eliminan (y borran) automáticamente si ya no se hace referencia a ellos en su nota después de un tiempo de espera definido.",
"erase_attachments_after": "Borrar archivos adjuntos después de:",
"manual_erasing_description": "También puede activar el borrado manualmente (sin considerar el tiempo de espera definido anteriormente):",
"manual_erasing_description": "Activar el borrado manualmente, ignorando el tiempo de espera definido anteriormente.",
"erase_unused_attachments_now": "Borrar ahora los archivos adjuntos no utilizados en la nota",
"unused_attachments_erased": "Los archivos adjuntos no utilizados se han eliminado."
},
@@ -1221,9 +1220,8 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Tiempo de espera de borrado de notas",
"note_erasure_description": "Las notas eliminadas (y los atributos, las revisiones ...) en principio solo están marcadas como eliminadas y es posible recuperarlas del diálogo de Notas recientes. Después de un período de tiempo, las notas eliminadas son \" borradas\", lo que significa que su contenido ya no es recuperable. Esta configuración le permite configurar la longitud del período entre eliminar y borrar la nota.",
"erase_notes_after": "Borrar notas después de:",
"manual_erasing_description": "También puede activar el borrado manualmente (sin considerar el tiempo de espera definido anteriormente):",
"manual_erasing_description": "Activar el borrado manualmente, ignorando el tiempo de espera definido anteriormente.",
"erase_deleted_notes_now": "Borrar notas eliminadas ahora",
"deleted_notes_erased": "Las notas eliminadas han sido borradas."
},
@@ -1242,7 +1240,7 @@
},
"search_engine": {
"title": "Motor de búsqueda",
"custom_search_engine_info": "El motor de búsqueda personalizado requiere que se establezcan un nombre y una URL. Si alguno de estos no está configurado, DuckDuckGo se utilizará como motor de búsqueda predeterminado.",
"custom_search_engine_info": "Utilizado al buscar la web para el texto seleccionado. Si no está configurado, DuckDuckGo se utilizado.",
"predefined_templates_label": "Plantillas de motor de búsqueda predefinidas",
"bing": "Bing",
"baidu": "Baidu",
@@ -1306,7 +1304,6 @@
"first-week-contains-first-thursday": "Primer semana que contiene al primer jueves del año",
"first-week-has-minimum-days": "Primer semana que contiene un mínimo de días",
"min-days-in-first-week": "Días mínimos en la primer semana",
"first-week-info": "Primer semana que contiene al primer jueves del año está basado en el estándar<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Cambiar las opciones de primer semana puede causar duplicados con las Notas Semanales existentes y las Notas Semanales existentes no serán actualizadas respectivamente.",
"formatting-locale": "Fecha y formato de número",
"tuesday": "Martes",
@@ -1437,9 +1434,6 @@
"server_address": "Dirección de la instancia del servidor",
"timeout": "Tiempo de espera de sincronización (milisegundos)",
"proxy_label": "Sincronizar servidor proxy (opcional)",
"note": "Nota",
"note_description": "Si deja la configuración del proxy en blanco, se utilizará el proxy del sistema (se aplica únicamente a la compilación de escritorio/electron).",
"special_value_description": "Otro valor especial es <code>noproxy</code> que obliga a ignorar incluso al proxy del sistema y respeta <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Guardar",
"help": "Ayuda",
"test_title": "Prueba de sincronización",
@@ -1621,7 +1615,7 @@
"note_detail": {
"could_not_find_typewidget": "No se pudo encontrar typeWidget para el tipo '{{type}}'",
"printing": "Impresión en curso...",
"printing_pdf": "Exportando a PDF en curso..",
"printing_pdf": "Preparando vista preliminar de impresión...",
"print_report_collection_content_one": "{{count}} nota en la colección no se puede imprimir porque no son compatibles o está protegida.",
"print_report_collection_content_many": "{{count}} notas en la colección no se pueden imprimir porque no son compatibles o están protegidas.",
"print_report_collection_content_other": "{{count}} notas en la colección no se pueden imprimir porque no son compatibles o están protegidas.",
@@ -1766,7 +1760,7 @@
"title": "Fijo",
"description": "las herramientas de edición aparecen en la pestaña de la cinta \"Formato\")."
},
"multiline-toolbar": "Mostrar la barra de herramientas en múltiples líneas si no cabe."
"multiline-toolbar": "Mostrar la barra de herramientas en múltiples líneas si no cabe"
}
},
"electron_context_menu": {

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "درباره Trilium Notes",
"homepage": "صفحه اصلی:",
"app_version": "نسخه برنامه:",
"db_version": "نسخه پایگاه داده:",
"sync_version": "نسخه منطبق:",
"build_date": "تاریخ ساخت:",
"build_revision": "نسخه بازنگری شده:",
"data_directory": "دایرکتوری داده:"
},
"toast": {

View File

@@ -1,13 +1,6 @@
{
"about": {
"title": "Lisätietoja Trilium Notes:ista",
"homepage": "Kotisivu:",
"app_version": "Sovelluksen versio:",
"db_version": "Tietokannan versio:",
"build_date": "Koontipäivämäärä:",
"data_directory": "Datakansio:",
"sync_version": "Synkronoinnin versio:",
"build_revision": "Sovelluksen versio:"
"data_directory": "Datakansio:"
},
"toast": {
"critical-error": {

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "À propos de Trilium Notes",
"homepage": "Page d'accueil :",
"app_version": "Version de l'application :",
"db_version": "Version de la base de données :",
"sync_version": "Version de la synchronisation :",
"build_date": "Date du build :",
"build_revision": "Version de build :",
"data_directory": "Répertoire des données :"
},
"toast": {
@@ -95,7 +88,10 @@
"notes_to_be_deleted": "Les notes suivantes seront supprimées ({{notesCount}})",
"no_note_to_delete": "Aucune note ne sera supprimée (uniquement les clones).",
"broken_relations_to_be_deleted": "Les relations suivantes seront rompues et supprimées ({{ relationCount}})",
"cancel": "Annuler"
"cancel": "Annuler",
"title": "Notes supprimées",
"clones_label": "Clone",
"erase_notes_label": "Supprimer définitivement"
},
"export": {
"export_note_title": "Exporter la note",
@@ -267,33 +263,6 @@
"undelete_link": "annuler la suppression",
"confirm_undelete": "Voulez-vous restaurer cette note et ses sous-notes ?"
},
"revisions": {
"note_revisions": "Versions de la note",
"delete_all_revisions": "Supprimer toutes les versions de cette note",
"delete_all_button": "Supprimer toutes les versions",
"help_title": "Aide sur les versions de notes",
"confirm_delete_all": "Voulez-vous supprimer toutes les versions de cette note ?",
"no_revisions": "Aucune version pour cette note pour l'instant...",
"confirm_restore": "Voulez-vous restaurer cette version ? Le titre et le contenu actuels de la note seront écrasés par cette version.",
"confirm_delete": "Voulez-vous supprimer cette version ?",
"revisions_deleted": "Les versions de notes ont été supprimées.",
"revision_restored": "La version de la note a été restaurée.",
"revision_deleted": "La version de la note a été supprimée.",
"snapshot_interval": "Délai d'enregistrement automatique des versions de notes : {{seconds}}s.",
"maximum_revisions": "Nombre maximal de versions : {{number}}.",
"settings": "Paramètres des versions de notes",
"download_button": "Télécharger",
"mime": "MIME : ",
"file_size": "Taille du fichier :",
"preview_not_available": "L'aperçu n'est pas disponible pour ce type de note.",
"restore_button": "Restaurer",
"delete_button": "Supprimer",
"diff_on": "Afficher les différences",
"diff_off": "Afficher le contenu",
"diff_on_hint": "Cliquer pour afficher les différences avec la note d'origine",
"diff_off_hint": "Cliquer pour afficher le contenu de la note",
"diff_not_available": "La comparaison n'est pas disponible."
},
"sort_child_notes": {
"sort_children_by": "Trier les enfants par...",
"sorting_criteria": "Critères de tri",
@@ -1093,7 +1062,6 @@
},
"database_integrity_check": {
"title": "Vérification de l'intégrité de la base de données",
"description": "Vérifiera que la base de données n'est pas corrompue au niveau SQLite. Cela peut prendre un certain temps, en fonction de la taille de la base de données.",
"check_button": "Vérifier l'intégrité de la base de données",
"checking_integrity": "Vérification de l'intégrité de la base de données...",
"integrity_check_succeeded": "Le contrôle d'intégrité a réussi - aucun problème détecté.",
@@ -1125,10 +1093,7 @@
"note_tree_font": "Police de l'arborescence",
"note_detail_font": "Police du contenu des notes",
"monospace_font": "Police Monospace (code)",
"note_tree_and_detail_font_sizing": "Notez que la taille de la police de larborescence et du contenu est relative au paramètre de taille de police principal.",
"not_all_fonts_available": "Toutes les polices répertoriées peuvent ne pas être disponibles sur votre système.",
"apply_font_changes": "Pour appliquer les modifications de police, cliquez sur",
"reload_frontend": "recharger l'interface",
"generic-fonts": "Polices génériques",
"sans-serif-system-fonts": "Polices système sans serif",
"serif-system-fonts": "Polices système Serif",
@@ -1207,8 +1172,7 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Délai d'effacement des pièces jointes",
"attachment_auto_deletion_description": "Les pièces jointes sont automatiquement supprimées (et effacées) si elles ne sont plus référencées par leur note après un certain délai.",
"erase_attachments_after": "Effacer les pièces jointes inutilisées après :",
"erase_attachments_after": "Effacer les pièces jointes inutilisées après :",
"manual_erasing_description": "Vous pouvez également déclencher l'effacement manuellement (sans tenir compte du délai défini ci-dessus) :",
"erase_unused_attachments_now": "Effacez maintenant les pièces jointes inutilisées",
"unused_attachments_erased": "Les pièces jointes inutilisées ont été effacées."
@@ -1219,7 +1183,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Délai d'effacement des notes",
"note_erasure_description": "Les notes supprimées (et les attributs, versions...) sont seulement marquées comme supprimées et il est possible de les récupérer à partir de la boîte de dialogue Notes récentes. Après un certain temps, les notes supprimées sont « effacées », ce qui signifie que leur contenu n'est plus récupérable. Ce paramètre vous permet de configurer la durée entre la suppression et l'effacement de la note.",
"erase_notes_after": "Effacer les notes après :",
"manual_erasing_description": "Vous pouvez également déclencher l'effacement manuellement (sans tenir compte de la durée définie ci-dessus) :",
"erase_deleted_notes_now": "Effacer les notes supprimées maintenant",
@@ -1303,7 +1266,6 @@
"first-week-contains-first-thursday": "La première semaine contient le premier jeudi de l'année",
"first-week-has-minimum-days": "La première semaine a un nombre minimum de jours",
"min-days-in-first-week": "Nombre minimum de jours dans la première semaine",
"first-week-info": "La première semaine contient le premier jeudi de l'année et est basée sur la norme <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> .",
"first-week-warning": "La modification des options de la première semaine peut entraîner des doublons avec les notes de semaine existantes et les notes de semaine existantes ne seront pas mises à jour en conséquence.",
"formatting-locale": "Format de date et de nombre",
"formatting-locale-auto": "En fonction de la langue de l'application"
@@ -1395,9 +1357,6 @@
"server_address": "Adresse de l'instance du serveur",
"timeout": "Délai d'expiration de la synchronisation (millisecondes)",
"proxy_label": "Serveur proxy de synchronisation (facultatif)",
"note": "Note",
"note_description": "Si vous laissez le paramètre de proxy vide, le proxy système sera utilisé (applicable uniquement à la version de bureau/électronique).",
"special_value_description": "Une autre valeur spéciale est <code>noproxy</code> qui oblige à ignorer même le proxy système et respecte <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Sauvegarder",
"help": "Aide",
"test_title": "Test de synchronisation",

View File

@@ -31,13 +31,6 @@
"search_notes": "Cuardaigh nótaí"
},
"about": {
"title": "Maidir le Trilium Notes",
"homepage": "Leathanach baile:",
"app_version": "Leagan an aip:",
"db_version": "Leagan DB:",
"sync_version": "Leagan sioncrónaithe:",
"build_date": "Dáta tógála:",
"build_revision": "Athbhreithniú tógála:",
"data_directory": "Eolaire sonraí:"
},
"toast": {
@@ -72,7 +65,9 @@
"link_title_mirrors": "Léiríonn teideal an naisc teideal reatha an nóta",
"link_title_arbitrary": "is féidir teideal an naisc a athrú go treallach",
"link_title": "Teideal an naisc",
"button_add_link": "Cuir nasc leis"
"button_add_link": "Cuir nasc leis",
"anchor": "Ancaire (roghnach)",
"anchor_none": "Dada (nasc chuig nóta)"
},
"branch_prefix": {
"edit_branch_prefix": "Cuir réimír na brainse in eagar",
@@ -121,12 +116,24 @@
"delete_notes": {
"close": "Dún",
"delete_all_clones_description": "Scrios gach clón freisin (is féidir é seo a chealú in athruithe le déanaí)",
"erase_notes_description": "Ní mharcálann scriosadh gnáth (bog) ach na nótaí mar scriosta agus is féidir iad a dhíscriosadh (sa dialóg athruithe le déanaí) laistigh de thréimhse ama. Scriosfar na nótaí láithreach má sheiceálann tú an rogha seo agus ní bheidh sé indéanta na nótaí a dhíscriosadh.",
"erase_notes_description": "Scrios nótaí láithreach in ionad scriosadh bog. Ní féidir é seo a chealú agus cuirfidh sé iallach ort an feidhmchlár a athlódáil.",
"erase_notes_warning": "Scrios nótaí go buan (ní féidir é seo a chealú), lena n-áirítear na clónanna go léir. Cuirfidh sé seo iallach ar an bhfeidhmchlár athlódáil.",
"notes_to_be_deleted": "Scriosfar na nótaí seo a leanas ({{notesCount}})",
"notes_to_be_deleted": "Nótaí le scriosadh ({{notesCount}})",
"no_note_to_delete": "Ní scriosfar aon nóta (clóin amháin).",
"broken_relations_to_be_deleted": "Brisfear agus scriosfar na caidrimh seo a leanas ({{ relationCount}})",
"cancel": "Cealaigh"
"broken_relations_to_be_deleted": "Caidrimh bhriste ({{relationCount}})",
"cancel": "Cealaigh",
"title": "Scrios nótaí",
"clones_label": "Clóin",
"delete_clones_description_one": "Scrios {{count}} clón eile freisin. Is féidir é seo a chealú sna hathruithe is déanaí.",
"delete_clones_description_two": "Scrios {{count}} clóin eile freisin. Is féidir é seo a chealú sna hathruithe is déanaí.",
"delete_clones_description_few": "Scrios {{count}} clóin eile freisin. Is féidir é seo a chealú sna hathruithe is déanaí.",
"delete_clones_description_many": "Scrios {{count}} clóin eile freisin. Is féidir é seo a chealú sna hathruithe is déanaí.",
"delete_clones_description_other": "Scrios {{count}} clóin eile freisin. Is féidir é seo a chealú sna hathruithe is déanaí.",
"erase_notes_label": "Scrios go buan",
"table_note_with_relation": "Nóta le gaol",
"table_relation": "Gaol",
"table_points_to": "Pointí chuig (scriosta)",
"delete": "Scrios"
},
"export": {
"export_note_title": "Nóta easpórtála",
@@ -237,7 +244,8 @@
"box_size_small": "beag (~ 10 líne)",
"box_size_medium": "meánach (~ 30 líne)",
"box_size_full": "lán (taispeánann an bosca an téacs iomlán)",
"button_include": "Cuir nóta san áireamh"
"button_include": "Cuir nóta san áireamh",
"box_size_expandable": "inleathnaithe (fillte de réir réamhshocraithe)"
},
"info": {
"modalTitle": "Teachtaireacht eolais",
@@ -298,33 +306,6 @@
"undelete_link": "díscriosadh",
"confirm_undelete": "Ar mhaith leat an nóta seo agus a fho-nótaí a athscriosadh?"
},
"revisions": {
"note_revisions": "Athbhreithnithe Nótaí",
"delete_all_revisions": "Scrios gach athbhreithniú ar an nóta seo",
"delete_all_button": "Scrios gach athbhreithniú",
"help_title": "Cabhair le hathbhreithnithe nótaí",
"confirm_delete_all": "Ar mhaith leat gach athbhreithniú ar an nóta seo a scriosadh?",
"no_revisions": "Gan aon athbhreithnithe don nóta seo go fóill...",
"restore_button": "Athchóirigh",
"diff_on": "Taispeáin an difríocht",
"diff_off": "Taispeáin ábhar",
"diff_on_hint": "Cliceáil chun difríocht foinse an nóta a thaispeáint",
"diff_off_hint": "Cliceáil chun ábhar an nóta a thaispeáint",
"diff_not_available": "Níl an difríocht ar fáil.",
"confirm_restore": "Ar mhaith leat an t-athbhreithniú seo a athbhunú? Scríobhfaidh sé seo teideal agus ábhar reatha an nóta leis an athbhreithniú seo.",
"delete_button": "Delete",
"confirm_delete": "Ar mhaith leat an t-athbhreithniú seo a scriosadh?",
"revisions_deleted": "Scriosadh athbhreithnithe nótaí.",
"revision_restored": "Tá athbhreithniú an nóta athchóirithe.",
"revision_deleted": "Scriosadh athbhreithniú an nóta.",
"snapshot_interval": "Eatramh Léirmheasa ar Nóta: {{seconds}}s.",
"maximum_revisions": "Teorainn maidir le hathbhreithniú nóta: {{number}}.",
"settings": "Socruithe Athbhreithnithe Nóta",
"download_button": "Íoslódáil",
"mime": "MIME: ",
"file_size": "Méid comhaid:",
"preview_not_available": "Níl réamhamharc ar fáil don chineál nóta seo."
},
"sort_child_notes": {
"sort_children_by": "Sórtáil páistí de réir...",
"sorting_criteria": "Critéir sórtála",
@@ -475,7 +456,9 @@
"print_landscape": "Agus é á onnmhairiú go PDF, athraítear treoshuíomh an leathanaigh go tírdhreach seachas portráid.",
"print_page_size": "Agus é á easpórtáil go PDF, athraítear méid an leathanaigh. Luachanna tacaithe: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>.",
"color_type": "Dath",
"textarea": "Téacs Il-líne"
"textarea": "Téacs Il-líne",
"print_scale": "Agus é á onnmhairiú go PDF, athraítear scála an ábhair rindreáilte. Tá na luachanna idir 0.1 (10%) agus 2 (200%), is é 1 (100%) an réamhshocrú.",
"print_margins": "Agus é á onnmhairiú go PDF, socraítear corrlaigh leathanaigh. Úsáid luachanna <code>réamhshocraithe</code>, <code>gan aon cheann</code>, <code>íosmhéid</code>, nó luachanna saincheaptha mar <code>barr, deas, bun, clé</code> i milliméadair."
},
"attribute_editor": {
"help_text_body1": "Chun lipéad a chur leis, clóscríobh m.sh. <code>#rock</code> nó más mian leat luach a chur leis freisin ansin m.sh. <code>#year = 2020</code>",
@@ -707,7 +690,13 @@
"export_as_image_png": "PNG (rastar)",
"export_as_image_svg": "SVG (veicteoir)",
"note_map": "Léarscáil nótaí",
"view_ocr_text": "Féach ar théacs OCR"
"view_ocr_text": "Féach ar théacs OCR",
"word_wrap": "Timfhill focal",
"word_wrap_auto": "Uathoibríoch",
"word_wrap_auto_description": "Lean an suíomh domhanda",
"word_wrap_on": "Ar",
"word_wrap_off": "As",
"save_named_revision": "Sábháil athbhreithniú ainmnithe..."
},
"onclick_button": {
"no_click_handler": "Níl aon láimhseálaí cliceáil sainithe ag an ngiuirléid cnaipe '{{componentId}}'"
@@ -809,7 +798,10 @@
"board": "Bord",
"presentation": "Cur i Láthair",
"include_archived_notes": "Taispeáin nótaí cartlannaithe",
"hide_child_notes": "Folaigh nótaí leanaí sa chrann"
"hide_child_notes": "Folaigh nótaí leanaí sa chrann",
"open_all_in_tabs": "Oscail gach rud",
"open_all_in_tabs_tooltip": "Oscail na torthaí go léir i gcluaisíní nua",
"open_all_confirm": "Osclóidh sé seo {{count}} nótaí i gcluaisíní nua. Lean ar aghaidh?"
},
"edited_notes": {
"no_edited_notes_found": "Gan aon nótaí eagarthóireachta ar an lá seo go fóill...",
@@ -863,7 +855,8 @@
"collapse": "Laghdaigh go dtí an gnáthmhéid",
"title": "Léarscáil Nótaí",
"fix-nodes": "Deisigh nóid",
"link-distance": "Fad naisc"
"link-distance": "Fad naisc",
"too-many-notes": "Tá {{count}} nótaí sa fho-chrann seo, rud a sháraíonn an teorainn {{max}} is féidir a thaispeáint sa léarscáil nótaí."
},
"note_paths": {
"title": "Cosáin Nótaí",
@@ -1078,15 +1071,17 @@
"title": "Seiceálacha Comhsheasmhachta",
"find_and_fix_button": "Fadhbanna comhsheasmhachta a aimsiú agus a shocrú",
"finding_and_fixing_message": "Fadhbanna comhsheasmhachta a aimsiú agus a shocrú...",
"issues_fixed_message": "Tá aon fhadhb chomhsheasmhachta a d'fhéadfadh a bheith aimsithe socraithe anois."
"issues_fixed_message": "Tá aon fhadhb chomhsheasmhachta a d'fhéadfadh a bheith aimsithe socraithe anois.",
"find_and_fix_label": "Fadhbanna comhsheasmhachta a aimsiú agus a shocrú",
"find_and_fix_description": "Déan scanadh le haghaidh aon fhadhbanna comhsheasmhachta sonraí sa bhunachar sonraí agus déan iad a dheisiú go huathoibríoch."
},
"database_anonymization": {
"title": "Anaithnidiú Bunachar Sonraí",
"full_anonymization": "Anaithnidiú Iomlán",
"full_anonymization_description": "Cruthóidh an gníomh seo cóip nua den bhunachar sonraí agus déanfaidh sé anaithnidiú air (bainfear gach ábhar nótaí agus fágfar struchtúr agus roinnt meiteashonraí neamhíogaire amháin) le go mbeidh sé in ann é a roinnt ar líne chun críocha dífhabhtaithe gan eagla go sceithfidh tú do shonraí pearsanta.",
"full_anonymization": "Anaithnidiú iomlán",
"full_anonymization_description": "Cruthaíonn sé cóip den bhunachar sonraí agus gach ábhar nótaí bainte, rud a fhágann struchtúr agus meiteashonraí neamhíogaire amháin. Sábháilte le roinnt ar líne agus fadhbanna dífhabhtaithe á ndífhabhtú.",
"save_fully_anonymized_database": "Sábháil bunachar sonraí lán-anaithnid",
"light_anonymization": "Anaithnidiú Éadrom",
"light_anonymization_description": "Cruthóidh an gníomh seo cóip nua den bhunachar sonraí agus déanfaidh sé beagán anaithnidithe air — go sonrach ní bhainfear ach ábhar na nótaí go léir, ach fanfaidh teidil agus tréithe. Ina theannta sin, fanfaidh nótaí scripte tosaigh/cúil JS saincheaptha agus giuirléidí saincheaptha. Soláthraíonn sé seo níos mó comhthéacs chun na fadhbanna a dhífhabhtú.",
"light_anonymization": "Anaithnidiú éadrom",
"light_anonymization_description": "Cruthaíonn sé cóip agus ábhar na nótaí bainte de, ach fanann teidil, tréithe, agus scripteanna/giuirléidí saincheaptha ann. Soláthraíonn sé níos mó comhthéacs le haghaidh dífhabhtaithe.",
"choose_anonymization": "Is féidir leat cinneadh a dhéanamh duit féin an mian leat bunachar sonraí atá anaithnid go hiomlán nó beagán gan ainm a sholáthar. Tá fiú bunachar sonraí atá anaithnid go hiomlán an-úsáideach, ach i gcásanna áirithe is féidir le bunachar sonraí atá anaithnid go héadrom an próiseas chun fabhtanna a aithint agus a shocrú a bhrostú.",
"save_lightly_anonymized_database": "Sábháil bunachar sonraí atá anaithnidithe go héadrom",
"existing_anonymized_databases": "Bunachair shonraí gan ainm atá ann cheana féin",
@@ -1095,15 +1090,17 @@
"error_creating_anonymized_database": "Níorbh fhéidir bunachar sonraí gan ainm a chruthú, seiceáil logaí an chúltaca le haghaidh sonraí",
"successfully_created_fully_anonymized_database": "Cruthaíodh bunachar sonraí lán-anaithnid i {{anonymizedFilePath}}",
"successfully_created_lightly_anonymized_database": "Cruthaíodh bunachar sonraí atá beagán anaithnid i {{anonymizedFilePath}}",
"no_anonymized_database_yet": "Gan aon bhunachar sonraí anaithnidithe go fóill."
"no_anonymized_database_yet": "Gan aon bhunachar sonraí anaithnidithe go fóill.",
"description": "Cruthaigh cóip gan ainm de do bhunachar sonraí le roinnt le forbróirí agus fadhbanna á ndífhabhtú, gan sonraí pearsanta a nochtadh."
},
"database_integrity_check": {
"title": "Seiceáil Ionracais Bunachar Sonraí",
"description": "Déanfaidh sé seo seiceáil nach bhfuil an bunachar sonraí truaillithe ar leibhéal SQLite. Dfhéadfadh sé go dtógfadh sé tamall, ag brath ar mhéid an bhunachair shonraí.",
"check_button": "Seiceáil sláine an bhunachair shonraí",
"checking_integrity": "Ag seiceáil sláine an bhunachair shonraí...",
"integrity_check_succeeded": "Déirigh leis an tseiceáil ionracais - níor aimsíodh aon fhadhbanna.",
"integrity_check_failed": "Theip ar an tseiceáil ionracais: {{results}}"
"integrity_check_failed": "Theip ar an tseiceáil ionracais: {{results}}",
"check_integrity_label": "Seiceáil sláine an bhunachair shonraí",
"check_integrity_description": "Fíoraigh nach bhfuil an bunachar sonraí truaillithe ar leibhéal SQLite."
},
"sync": {
"title": "Sioncrónaigh",
@@ -1113,14 +1110,20 @@
"filling_entity_changes": "Líonadh sraitheanna athruithe eintiteas...",
"sync_rows_filled_successfully": "Líontar na sraitheanna sioncrónaithe go rathúil",
"finished-successfully": "Críochnaíodh an sioncrónú go rathúil.",
"failed": "Theip ar an sioncrónú: {{message}}"
"failed": "Theip ar an sioncrónú: {{message}}",
"force_full_sync_label": "Fórsaigh sioncrónú iomlán",
"force_full_sync_description": "Spreag sioncrónú iomlán leis an bhfreastalaí sioncrónaithe, ag ath-uaslódáil na hathruithe go léir.",
"fill_entity_changes_label": "Athruithe eintitis líonta",
"fill_entity_changes_description": "Athchruthaigh taifid athraithe eintitis. Bain úsáid as seo má tá roinnt athruithe ar iarraidh sa sioncrónú."
},
"vacuum_database": {
"title": "Bunachar Sonraí Folúis",
"description": "Déanfaidh sé seo an bunachar sonraí a atógáil agus de ghnáth beidh comhad bunachar sonraí níos lú mar thoradh air. Ní athrófar aon sonraí i ndáiríre.",
"button_text": "Bunachar sonraí folúis",
"vacuuming_database": "Bunachar sonraí folúsghlanadh...",
"database_vacuumed": "Tá an bunachar sonraí folúsghlanaithe"
"database_vacuumed": "Tá an bunachar sonraí folúsghlanaithe",
"vacuum_label": "Bunachar sonraí folúis",
"vacuum_description": "Athchruthaigh an bunachar sonraí chun méid an chomhaid a laghdú. Ní athrófar aon sonraí."
},
"experimental_features": {
"title": "Roghanna Turgnamhacha",
@@ -1133,16 +1136,13 @@
"fonts": {
"theme_defined": "Téama sainmhínithe",
"fonts": "Clónna",
"main_font": "Príomhchló",
"main_font": "Téacs comhéadain",
"font_family": "Teaghlach clónna",
"size": "Méid",
"note_tree_font": "Cló Crann Nótaí",
"note_detail_font": "Cló Sonraí Nóta",
"monospace_font": "Cló Aonspáis (cód)",
"note_tree_and_detail_font_sizing": "Tabhair faoi deara go bhfuil méid an ch crainn agus mionsonraí i gcoibhneas leis an bpríomhshocrú méid cló.",
"not_all_fonts_available": "Bfhéidir nach bhfuil na clónna uile atá liostaithe ar fáil ar do chóras.",
"apply_font_changes": "Chun athruithe cló a chur i bhfeidhm, cliceáil ar",
"reload_frontend": "athlódáil tosaigh",
"note_tree_font": "Téacs crann nótaí",
"note_detail_font": "Téacs an doiciméid",
"monospace_font": "Téacs aonspáis",
"not_all_fonts_available": "Bfhéidir nach bhfuil na clónna uile atá liostaithe ar fáil ar do chóras",
"generic-fonts": "Clónna ginearálta",
"sans-serif-system-fonts": "Clónna córais Sans-serif",
"serif-system-fonts": "Clónna córais Serif",
@@ -1151,7 +1151,12 @@
"serif": "Serif",
"sans-serif": "Sans Serif",
"monospace": "Aonspás",
"system-default": "Réamhshocrú an chórais"
"system-default": "Réamhshocrú an chórais",
"custom_fonts": "Úsáid clónna saincheaptha",
"preview": "Réamhamharc",
"monospace_font_description": "Úsáidte le haghaidh nótaí cóid agus bloic cóid",
"size_relative_to_general": "Tá an méid i gcoibhneas leis an méid cló ginearálta",
"apply_changes": "Athlódáil chun na hathruithe a chur i bhfeidhm"
},
"max_content_width": {
"title": "Leithead an Ábhair",
@@ -1171,28 +1176,31 @@
"edited_notes_message": "Osclófar an cluaisín ribín Nótaí Eagarthóireachta go huathoibríoch ar nótaí lae"
},
"theme": {
"title": "Téama an Iarratais",
"theme_label": "Téama",
"title": "Comhéadan Úsáideora",
"theme_label": "Téama an iarratais",
"override_theme_fonts_label": "Sáraigh clónna téama",
"auto_theme": "Seanchóras (Lean scéim dathanna an chórais)",
"light_theme": "Oidhreacht (Éadrom)",
"dark_theme": "Oidhreacht (Dorcha)",
"triliumnext": "Trilium (Lean scéim dathanna an chórais)",
"triliumnext-light": "Trilium (Éadrom)",
"triliumnext-dark": "Trilium (Dorcha)",
"auto_theme": "Lean scéim dathanna an chórais",
"light_theme": "Solas",
"dark_theme": "Dorcha",
"triliumnext": "Lean scéim dathanna an chórais",
"triliumnext-light": "Solas",
"triliumnext-dark": "Dorcha",
"layout": "Leagan Amach",
"layout-vertical-title": "Ingearach",
"layout-horizontal-title": "Cothrománach",
"layout-vertical-description": "tá barra lainseála ar chlé (réamhshocraithe)",
"layout-horizontal-description": "Tá barra an lainseálaí faoin mbarra cluaisín, tá an barra cluaisín lánleithead anois."
"layout-horizontal-description": "Tá barra an lainseálaí faoin mbarra cluaisín, tá an barra cluaisín lánleithead anois.",
"modern_themes": "Nua-Aimseartha",
"legacy_themes": "Oidhreacht",
"custom_themes": "Saincheaptha"
},
"ui-performance": {
"title": "Feidhmíocht",
"enable-motion": "Cumasaigh aistrithe agus beochana",
"enable-shadows": "Cumasaigh scáthanna",
"enable-backdrop-effects": "Cumasaigh éifeachtaí cúlra do bhiachláir, fuinneoga aníos agus painéil",
"enable-smooth-scroll": "Cumasaigh scrollú réidh",
"app-restart-required": "(tá atosú an fheidhmchláir ag teastáil chun an t-athrú a chur i bhfeidhm)"
"enable-motion": "Aistrithe agus beochana",
"enable-shadows": "Scáthanna",
"enable-backdrop-effects": "Éifeachtaí cúlra do bhiachláir, fuinneoga aníos agus painéil",
"enable-smooth-scroll": "Scrolláil réidh",
"app-restart-required": "Éilíonn atosú an aip"
},
"zoom_factor": {
"title": "Fachtóir Súmáil (leagan deisce amháin)",
@@ -1201,11 +1209,13 @@
"code_auto_read_only_size": {
"title": "Méid Uathoibríoch Léite Amháin",
"description": "Is é méid uathoibríoch nótaí inléite amháin an méid tar éis a dtaispeánfar nótaí i mód inléite amháin (ar chúiseanna feidhmíochta).",
"label": "Méid inléite amháin uathoibríoch (nótaí cóid)",
"label": "Méid inléite amháin uathoibríoch",
"unit": "carachtair"
},
"code-editor-options": {
"title": "Eagarthóir"
"title": "Eagarthóir",
"tab_width": "Leithead an chluaisín",
"tab_width_unit": "spásanna"
},
"code_mime_types": {
"title": "Cineálacha MIME atá ar fáil sa roghchlár anuas",
@@ -1247,61 +1257,70 @@
"batch_ocr_error": "Earráid le linn próiseála baisce: {{error}}"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Am Teorann Scriosadh Ceangaltáin",
"attachment_auto_deletion_description": "Scriostar ceangaltáin go huathoibríoch (agus scriostar iad) mura ndéantar tagairt dóibh ina nóta a thuilleadh tar éis tréimhse ama socraithe.",
"erase_attachments_after": "Scrios ceangaltáin neamhúsáidte tar éis:",
"manual_erasing_description": "Is féidir leat scriosadh a spreagadh de láimh freisin (gan an t-am críochnaithe a shainmhínítear thuas a chur san áireamh):",
"erase_unused_attachments_now": "Scrios nótaí ceangaltáin neamhúsáidte anois",
"unused_attachments_erased": "Scriosadh ceangaltáin neamhúsáidte."
"attachment_erasure_timeout": "Ceangaltáin Neamhúsáidte",
"erase_attachments_after": "Scrios ceangaltáin neamhúsáidte ina dhiaidh sin",
"manual_erasing_description": "Spreag scriosadh de láimh, ag neamhaird den am scoir thuas.",
"erase_unused_attachments_now": "Scrios ceangaltáin neamhúsáidte anois",
"unused_attachments_erased": "Scriosadh ceangaltáin neamhúsáidte.",
"description": "Meastar nach n-úsáidtear ceangaltáin nach ndéantar tagairt dóibh a thuilleadh in aon nóta agus is féidir iad a scriosadh go huathoibríoch tar éis tréimhse ama.",
"erase_attachments_after_description": "Am sula scriostar ceangaltáin neamhúsáidte go buan."
},
"network_connections": {
"network_connections_title": "Naisc Líonra",
"check_for_updates": "Seiceáil le haghaidh nuashonruithe go huathoibríoch"
"network_connections_title": "Líonra",
"check_for_updates": "Seiceáil le haghaidh nuashonruithe go huathoibríoch",
"check_for_updates_description": "Seiceálann sé le haghaidh leaganacha nua ar GitHub agus taispeánann sé fógra sa roghchlár domhanda nuair a bhíonn sé ar fáil."
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Am Scriosadh Nótaí",
"note_erasure_description": "Ní dhéantar nótaí scriosta (agus tréithe, athbhreithnithe...) a mharcáil ach mar scriosta ar dtús agus is féidir iad a aisghabháil ón dialóg Nótaí Le Déanaí. Tar éis tamaill, déantar nótaí scriosta a \"scriosadh\" rud a chiallaíonn nach féidir a n-ábhar a aisghabháil a thuilleadh. Ligeann an socrú seo duit fad na tréimhse idir an nóta a scriosadh agus a scriosadh a chumrú.",
"erase_notes_after": "Scrios nótaí tar éis:",
"manual_erasing_description": "Is féidir leat scriosadh a spreagadh de láimh freisin (gan an t-am críochnaithe a shainmhínítear thuas a chur san áireamh):",
"note_erasure_timeout_title": "Nótaí Scriosta",
"erase_notes_after": "Scrios nótaí ina dhiaidh",
"manual_erasing_description": "Spreag scriosadh de láimh, ag neamhaird den am scoir thuas.",
"erase_deleted_notes_now": "Scrios nótaí scriosta anois",
"deleted_notes_erased": "Tá nótaí scriosta scriosta."
"deleted_notes_erased": "Tá nótaí scriosta scriosta.",
"description": "Ní dhéantar nótaí scriosta a mharcáil ach mar scriosta ar dtús agus is féidir iad a aisghabháil ó Nótaí Le Déanaí. Tar éis tamaill, scriostar go buan iad.",
"erase_notes_after_description": "An t-am sula scriostar nótaí scriosta go buan."
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "Eatramh Léirmheasa ar Nóta",
"note_revisions_snapshot_description": "Is é an t-eatramh pictiúr athbhreithnithe nóta an t-am ina dhiaidh a chruthófar athbhreithniú nóta nua don nóta. Féach <doc>vicí</doc> le haghaidh tuilleadh eolais.",
"snapshot_time_interval_label": "Eatramh ama pictiúr athbhreithnithe nóta:"
"snapshot_time_interval_label": "Eatramh pictiúr",
"note_revisions_snapshot_description_short": "An t-am a gcruthófar athbhreithniú nóta nua ina dhiaidh."
},
"revisions_snapshot_limit": {
"note_revisions_snapshot_limit_title": "Teorainn ar Ghrianghraf Athbhreithnithe Nóta",
"note_revisions_snapshot_limit_description": "Tagraíonn an teorainn ar líon na n-athbhreithnithe nótaí don líon uasta athbhreithnithe is féidir a shábháil do gach nóta. Ciallaíonn -1 gan aon teorainn, ciallaíonn 0 scriosadh na hathbhreithnithe go léir. Is féidir leat an líon uasta athbhreithnithe a shocrú do nóta aonair tríd an lipéad #versioningLimit.",
"snapshot_number_limit_label": "Teorainn líon na n-íomhánna athbhreithnithe nóta:",
"snapshot_number_limit_label": "Uasmhéid athbhreithnithe",
"snapshot_number_limit_unit": "léargais",
"erase_excess_revision_snapshots": "Scrios na léargais athbhreithnithe breise anois",
"erase_excess_revision_snapshots_prompt": "Scriosadh na léargais bhreise athbhreithnithe."
"erase_excess_revision_snapshots_prompt": "Scriosadh na léargais bhreise athbhreithnithe.",
"note_revisions_snapshot_limit_description_short": "Uasmhéid athbhreithnithe in aghaidh an nóta. Úsáid -1 le haghaidh neamhtheoranta, 0 le díchumasú.",
"erase_excess_revision_snapshots_description": "Scrios athbhreithnithe a sháraíonn an teorainn do na nótaí uile."
},
"search_engine": {
"title": "Inneall Cuardaigh",
"custom_search_engine_info": "Éilíonn inneall cuardaigh saincheaptha go socrófar ainm agus URL araon. Mura socraítear ceachtar acu seo, úsáidfear DuckDuckGo mar an t-inneall cuardaigh réamhshocraithe.",
"predefined_templates_label": "Teimpléid inneall cuardaigh réamhshainithe",
"custom_search_engine_info": "Úsáidtear é seo agus téacs roghnaithe á chuardach ar an ngréasán. Mura bhfuil sé cumraithe, úsáidfear DuckDuckGo.",
"predefined_templates_label": "Réamhshocruithe",
"bing": "Bing",
"baidu": "Baidu",
"duckduckgo": "DuckDuckGo",
"google": "Google",
"custom_name_label": "Ainm innill chuardaigh saincheaptha",
"custom_name_placeholder": "Saincheap ainm an innill chuardaigh",
"custom_url_label": "Ba chóir go mbeadh {keyword} san áireamh mar áitchoinneálaí don téarma cuardaigh i URL inneall cuardaigh saincheaptha.",
"custom_url_placeholder": "Saincheap URL an innill chuardaigh",
"save_button": "Sábháil"
"custom_name_label": "Ainm",
"custom_name_placeholder": "Ainm an innill chuardaigh",
"custom_url_label": "URL",
"custom_url_placeholder": "URL inneall cuardaigh",
"save_button": "Sábháil",
"custom_url_description": "Úsáid {keyword} mar áitchoinneálaí don téarma cuardaigh."
},
"tray": {
"title": "Tráidire an Chórais",
"enable_tray": "Cumasaigh an tráidire (ní mór Trilium a atosú le go dtiocfaidh an t-athrú seo i bhfeidhm)"
"enable_tray": "Deilbhín tráidire",
"enable_tray_description": "Caithfear Trilium a atosú chun go dtiocfaidh an t-athrú seo i bhfeidhm."
},
"heading_style": {
"title": "Stíl Ceannteidil",
"title": "Stíl ceannteidil",
"plain": "Simplí",
"underline": "Folínigh",
"markdown": "Stíl marcála síos"
"markdown": "Stíl marcála síos",
"description": "Stíl amhairc do cheannteidil i nótaí téacs."
},
"highlights_list": {
"title": "Liosta Buaicphointí",
@@ -1325,14 +1344,16 @@
"text_auto_read_only_size": {
"title": "Méid Uathoibríoch Léite Amháin",
"description": "Is é méid uathoibríoch nótaí inléite amháin an méid tar éis a dtaispeánfar nótaí i mód inléite amháin (ar chúiseanna feidhmíochta).",
"label": "Méid inléite amháin uathoibríoch (nótaí téacs)",
"label": "Méid inléite amháin uathoibríoch",
"unit": "carachtair"
},
"custom_date_time_format": {
"title": "Formáid Dáta/Am Saincheaptha",
"title": "Formáid dáta/ama",
"description": "Saincheap formáid an dáta agus an ama a chuirtear isteach trí <shortcut /> nó an barra uirlisí. Féach ar <doc>doiciméid Day.js</doc> le haghaidh na gcomharthaí formáide atá ar fáil.",
"format_string": "Formáid teaghrán:",
"formatted_time": "Dáta/am formáidithe:"
"format_string": "Formáid teaghrán",
"formatted_time": "Dáta/am formáidithe",
"description_short": "Saincheap formáid an dáta agus an ama a chuirtear isteach tríd an mbarra uirlisí.",
"preview": "Réamhamharc: {{preview}}"
},
"i18n": {
"title": "Logánú",
@@ -1347,20 +1368,19 @@
"sunday": "Dé Domhnaigh",
"first-week-of-the-year": "An chéad seachtain den bhliain",
"first-week-contains-first-day": "Tá an chéad lá den bhliain sa chéad seachtain",
"first-week-contains-first-thursday": "Tá an chéad Déardaoin den bhliain sa chéad seachtain",
"first-week-contains-first-thursday": "Tá an chéad Déardaoin sa chéad seachtain (ISO 8601)",
"first-week-has-minimum-days": "Tá an chéad seachtain ag an íosmhéid laethanta",
"min-days-in-first-week": "Íosmhéid laethanta sa chéad seachtain",
"first-week-info": "Tá an chéad seachtain ina bhfuil an chéad Déardaoin den bhliain bunaithe ar chaighdeán <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Dfhéadfadh sé go mbeadh dúblach le Nótaí Seachtaine atá ann cheana féin mar thoradh ar athrú roghanna na chéad seachtaine agus ní dhéanfar na Nótaí Seachtaine atá ann cheana a nuashonrú dá réir.",
"first-week-warning": "Dfhéadfadh sé go mbeadh dúblaigh le Nótaí Seachtaine atá ann cheana féin mar thoradh ar athrú seo.",
"formatting-locale": "Formáid dáta agus uimhreach",
"formatting-locale-auto": "Bunaithe ar theanga an fheidhmchláir"
},
"backup": {
"automatic_backup": "Cúltaca uathoibríoch",
"automatic_backup_description": "Is féidir le Trilium cúltaca den bhunachar sonraí a dhéanamh go huathoibríoch:",
"enable_daily_backup": "Cumasaigh cúltaca laethúil",
"enable_weekly_backup": "Cumasaigh cúltaca seachtainiúil",
"enable_monthly_backup": "Cumasaigh cúltaca míosúil",
"enable_daily_backup": "Cúltaca laethúil",
"enable_weekly_backup": "Cúltaca seachtainiúil",
"enable_monthly_backup": "Cúltaca míosúil",
"backup_recommendation": "Moltar an cúltaca a choinneáil casta air, ach is féidir leis seo moill a chur ar thosú feidhmchlár le bunachair shonraí móra agus/nó gléasanna stórála mall.",
"backup_now": "Cúltaca anois",
"backup_database_now": "Cúltaca bunachar sonraí anois",
@@ -1368,7 +1388,9 @@
"date-and-time": "Dáta & am",
"path": "Cosán",
"database_backed_up_to": "Tá cúltaca déanta den bhunachar sonraí chuig {{backupFilePath}}",
"no_backup_yet": "gan aon chúltaca fós"
"no_backup_yet": "gan aon chúltaca fós",
"download": "Íoslódáil",
"title": "Cúltaca"
},
"etapi": {
"title": "ETAPI",
@@ -1403,18 +1425,22 @@
"new_password": "Pasfhocal nua",
"new_password_confirmation": "Deimhniú pasfhocail nua",
"change_password": "Athraigh an focal faire",
"protected_session_timeout": "Am Teorann Seisiúin Chosanta",
"protected_session_timeout_description": "Is tréimhse ama í an t-am scoir seisiúin chosanta a scriostar an seisiún cosanta ó chuimhne an bhrabhsálaí ina dhiaidh. Déantar é seo a thomhas ón idirghníomhaíocht dheireanach le nótaí cosanta. Féach",
"protected_session_timeout": "Seisiún faoi Chosaint",
"protected_session_timeout_description": "Am neamhghníomhaíochta sula nglanfar an seisiún ó chuimhne an bhrabhsálaí. Féach",
"wiki": "vicí",
"for_more_info": "le haghaidh tuilleadh eolais.",
"protected_session_timeout_label": "Am scoir seisiúin faoi chosaint:",
"protected_session_timeout_label": "Dún seisiún go huathoibríoch ina dhiaidh sin",
"reset_confirmation": "Trí an focal faire a athshocrú caillfidh tú rochtain go deo ar do nótaí cosanta go léir atá ann cheana féin. An bhfuil tú cinnte gur mhaith leat an focal faire a athshocrú?",
"reset_success_message": "Athshocraíodh an focal faire. Socraigh focal faire nua le do thoil",
"change_password_heading": "Athraigh Pasfhocal",
"set_password_heading": "Socraigh Pasfhocal",
"set_password": "Socraigh Pasfhocal",
"password_mismatch": "Ní hionann pasfhocail nua.",
"password_changed_success": "Athraíodh an focal faire. Athlódálfar Trilium tar éis duit brúigh OK."
"password_changed_success": "Athraíodh an focal faire. Athlódálfar Trilium tar éis duit brúigh OK.",
"change_password_description": "Nuashonraigh do phasfhocal reatha",
"reset_password": "Athshocraigh an focal faire",
"reset_password_description": "Caill rochtain ar nótaí faoi chosaint go buan",
"cancel": "Cealaigh"
},
"multi_factor_authentication": {
"title": "Fíordheimhniú Ilfhachtóireach",
@@ -1477,19 +1503,19 @@
"related_description": "Cumraigh teangacha seiceála litrithe agus foclóir saincheaptha."
},
"sync_2": {
"config_title": "Cumraíocht Sioncrónaithe",
"server_address": "Seoladh sampla an fhreastalaí",
"timeout": "Am scoir sioncrónaithe",
"proxy_label": "Sioncrónaigh freastalaí seachfhreastalaí (roghnach)",
"note": "Nóta",
"note_description": "Má fhágann tú an socrú seachfhreastalaí bán, úsáidfear seachfhreastalaí an chórais (baineann sé le tógáil deisce/leictreon amháin).",
"special_value_description": "Luach speisialta eile is ea <code>noproxy</code> a chuireann iallach neamhaird a dhéanamh fiú ar an seachfhreastalaí córais agus a thugann meas ar <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"config_title": "Freastalaí Sioncrónaithe",
"server_address": "Seoladh an fhreastalaí",
"timeout": "Am críochnaithe nasc",
"proxy_label": "Freastalaí seachfhreastalaí",
"save": "Sábháil",
"help": "Cabhair",
"test_title": "Tástáil Sioncrónaithe",
"test_description": "Déanfaidh sé seo tástáil ar an nasc agus ar an gcroitheadh láimhe leis an bhfreastalaí sioncrónaithe. Mura bhfuil an freastalaí sioncrónaithe tosaithe, socróidh sé seo é chun sioncrónú leis an doiciméad áitiúil.",
"test_title": "Tástáil Ceangal",
"test_description": "Déan tástáil ar an nasc leis an bhfreastalaí sioncrónaithe. Mura ndéantar é a thosú, socróidh sé seo sioncrónú.",
"test_button": "Tástáil sioncrónaithe",
"handshake_failed": "Theip ar chroitheadh láimhe an fhreastalaí sioncrónaithe, earráid: {{message}}"
"handshake_failed": "Theip ar chroitheadh láimhe an fhreastalaí sioncrónaithe, earráid: {{message}}",
"timeout_description": "Am fanacht sula dtugann tú suas ar nasc mall.",
"server_address_description": "URL an fhreastalaí Trilium le sioncrónú leis.",
"proxy_description": "Fág bán chun seachfhreastalaí córais a úsáid (deasc amháin). Bain úsáid as \"noproxy\" chun na seachfhreastalaithe go léir a sheachaint."
},
"api_log": {
"close": "Dún"
@@ -1592,7 +1618,8 @@
"new-feature": "Nua",
"collections": "Bailiúcháin",
"spreadsheet": "Scarbhileog",
"llm-chat": "Comhrá AI"
"llm-chat": "Comhrá AI",
"markdown": "Markdown"
},
"protect_note": {
"toggle-on": "Cosain an nóta",
@@ -1675,7 +1702,7 @@
"note_detail": {
"could_not_find_typewidget": "Níorbh fhéidir typeWidget a aimsiú don chineál '{{type}}'",
"printing": "Priontáil ar siúl...",
"printing_pdf": "Ag easpórtáil go PDF ar siúl...",
"printing_pdf": "Réamhamharc priontála á ullmhú...",
"print_report_title": "Tuarascáil a phriontáil",
"print_report_collection_content_one": "Níorbh fhéidir nóta {{count}} sa bhailiúchán a phriontáil mar nach dtacaítear leo nó mar go bhfuil siad faoi chosaint.",
"print_report_collection_content_two": "Níorbh fhéidir {{count}} nótaí sa bhailiúchán a phriontáil mar nach dtacaítear leo nó mar go bhfuil siad faoi chosaint.",
@@ -1757,7 +1784,9 @@
"entrypoints": {
"note-revision-created": "Cruthaíodh athbhreithniú nóta.",
"note-executed": "Nóta curtha i gcrích.",
"sql-error": "Tharla earráid agus fiosrúchán SQL á fhorghníomhú: {{message}}"
"sql-error": "Tharla earráid agus fiosrúchán SQL á fhorghníomhú: {{message}}",
"save-named-revision-title": "Sábháil athbhreithniú ainmnithe",
"save-named-revision-message": "Cuir isteach ainm don athbhreithniú seo (fág folamh mura bhfuil ainm ar bith ann):"
},
"branches": {
"cannot-move-notes-here": "Ní féidir nótaí a bhogadh anseo.",
@@ -1803,7 +1832,10 @@
"theme_none": "Gan aon aibhsiú comhréire",
"theme_group_light": "Téamaí éadroma",
"theme_group_dark": "Téamaí dorcha",
"copy_title": "Cóipeáil chuig an ghearrthaisce"
"copy_title": "Cóipeáil chuig an ghearrthaisce",
"click_to_copy": "Cliceáil chun cóipeáil",
"tab_width": "Leithead an chluaisín",
"tab_width_unit": "spásanna"
},
"classic_editor_toolbar": {
"title": "Formáidiú"
@@ -1822,7 +1854,8 @@
"title": "Seasta",
"description": "Feictear uirlisí eagarthóireachta sa chluaisín ribín \"Formáidiú\"."
},
"multiline-toolbar": "Taispeáin an barra uirlisí ar illínte mura n-oireann sé."
"multiline-toolbar": "Taispeáin an barra uirlisí ar illínte mura n-oireann sé",
"toolbar_style": "Stíl an bharra uirlisí"
}
},
"electron_context_menu": {
@@ -1889,7 +1922,7 @@
"days": "Laethanta"
},
"share": {
"title": "Socruithe Comhroinnte",
"title": "Comhroinn",
"redirect_bare_domain": "Atreoraigh fearann lom chuig an leathanach Comhroinnte",
"redirect_bare_domain_description": "Atreoraigh úsáideoirí gan ainm chuig an leathanach Comhroinnte in ionad Logáil Isteach a thaispeáint",
"show_login_link": "Taispeáin nasc Logála Isteach sa téama Comhroinnte",
@@ -1953,12 +1986,12 @@
},
"editorfeatures": {
"title": "Gnéithe",
"emoji_completion_enabled": "Cumasaigh uath-chomhlánú Emoji",
"emoji_completion_description": "Más cumasaithe é, is féidir emojis a chur isteach i dtéacs go héasca trí `:` a chlóscríobh, agus ainm emoji ina dhiaidh sin.",
"note_completion_enabled": "Cumasaigh uath-chríochnú nótaí",
"note_completion_description": "Más cumasaithe é, is féidir naisc chuig nótaí a chruthú trí `@` a chlóscríobh agus teideal an nóta ina dhiaidh sin.",
"slash_commands_enabled": "Cumasaigh orduithe slaise",
"slash_commands_description": "Más cumasaithe é, is féidir orduithe eagarthóireachta amhail briseadh líne nó ceannteidil a chur isteach a athrú trí `/` a chlóscríobh."
"emoji_completion_enabled": "Uath-chomhlánú emoji",
"emoji_completion_description": "Uath-líonadh emoji Is féidir emojis a chur isteach i dtéacs go héasca trí `:` a chlóscríobh, agus ainm emoji ina dhiaidh sin.",
"note_completion_enabled": "Uath-chomhlánú nótaí",
"note_completion_description": "Is féidir naisc chuig nótaí a chruthú trí `@` a chlóscríobh agus teideal an nóta ina dhiaidh sin.",
"slash_commands_enabled": "Orduithe slaise",
"slash_commands_description": "Is féidir orduithe eagarthóireachta amhail briseadh líne nó ceannteidil a chur isteach a athrú trí `/` a chlóscríobh."
},
"table_view": {
"new-row": "Sraith nua",
@@ -2062,7 +2095,9 @@
"related_code_notes": "Scéim dathanna le haghaidh nótaí cóid",
"ui": "Comhéadan úsáideora",
"ui_old_layout": "Leagan amach sean",
"ui_new_layout": "Leagan amach nua"
"ui_new_layout": "Leagan amach nua",
"ui_layout_style": "Stíl leagan amach",
"ui_layout_orientation": "Treoshuíomh an bharra lainseálaí"
},
"units": {
"percentage": "%"
@@ -2161,7 +2196,19 @@
"note_paths_many": "{{count}} cosáin",
"note_paths_other": "{{count}} cosáin",
"note_paths_title": "Cosáin nótaí",
"code_note_switcher": "Athraigh mód teanga"
"code_note_switcher": "Athraigh mód teanga",
"tab_width": "Leithead an Chluaisín: {{width}}",
"tab_width_title": "Athraigh leithead an chluaisín",
"tab_width_spaces": "{{count}} spásanna",
"tab_width_spaces_short": "Spásanna: {{width}}",
"tab_width_tabs": "Cluaisíní: {{width}}",
"tab_width_use_default": "Úsáid an réamhshocrú ({{width}})",
"tab_width_use_default_style": "Úsáid réamhshocraithe ({{style}})",
"tab_width_display_header": "Leithead taispeána",
"tab_width_reindent_header": "Ath-eangaigh ábhar go",
"tab_width_style_header": "Líon isteach ag baint úsáide as",
"tab_width_style_spaces": "Spásanna",
"tab_width_style_tabs": "Cluaisíní"
},
"attributes_panel": {
"title": "Tréithe Nóta"
@@ -2328,7 +2375,8 @@
"note_context_disabled": "Cliceáil chun an nóta reatha a chur san áireamh i gcomhthéacs",
"no_provider_message": "Níl aon soláthraí AI cumraithe. Cuir ceann leis chun comhrá a thosú.",
"add_provider": "Cuir Soláthraí AI leis",
"sources_summary": "{{count}} foinsí ó {{sites}} suíomhanna"
"sources_summary": "{{count}} foinsí ó {{sites}} suíomhanna",
"stop": "Stop"
},
"sidebar_chat": {
"title": "Comhrá AI",
@@ -2392,7 +2440,11 @@
"web_search": "Cuardach gréasáin",
"note_in_parent": "<Note/> i <Parent/>",
"get_attachment": "Faigh ceangaltán",
"get_attachment_content": "Léigh ábhar an cheangail"
"get_attachment_content": "Léigh ábhar an cheangail",
"rename_note": "Athainmnigh an nóta",
"delete_note": "Scrios nóta",
"move_note": "Bog nóta",
"clone_note": "Clónáil nóta"
}
},
"ocr": {
@@ -2410,5 +2462,126 @@
"processing_complete": "Próiseáil OCR críochnaithe.",
"text_filtered_low_confidence": "Bhraith OCR téacs le muinín {{confidence}}%, ach caitheadh leis é mar is é {{threshold}}% an tairseach íosta atá agat.",
"open_media_settings": "Oscail Socruithe"
},
"database": {
"title": "Bunachar Sonraí"
},
"search": {
"title": "Cuardaigh",
"fuzzy_matching_label": "Caoinfhulaingt clóscríofa sa chuardach",
"fuzzy_matching_description": "Bíonn tionchar aige ar chuardach tapa agus ar chuardach iomlán. Faightear focail chomhchosúla nuair nach leor na meaitseáil chruinne.",
"autocomplete_fuzzy_label": "Caoinfhulaingt clóscríofa in uathchríochnú",
"autocomplete_fuzzy_description": "Bíonn tionchar aige ar léim-go-nóta agus ar roghnóirí nótaí. Níos moille ach glactar le clóscríobh."
},
"text_editor": {
"title": "Eagarthóir"
},
"link": {
"failed_to_open": "Theip ar oscailt an nasc '{{- href}}': {{- message}}"
},
"print_preview": {
"title": "Réamhamharc priontála",
"close": "Dún",
"save": "Sábháil mar PDF",
"print": "Priontáil",
"export_pdf": "Easpórtáil mar PDF",
"system_print": "Priontáil ag baint úsáide as dialóg an chórais",
"destination": "Ceann Scríbe",
"destination_pdf": "Sábháil mar PDF",
"destination_printers": "Printéirí",
"destination_default": "Réamhshocrú",
"orientation": "Treoshuíomh",
"portrait": "Portráid",
"landscape": "Tírdhreach",
"page_size": "Méid leathanaigh",
"scale": "Scála",
"margins": "Imill",
"render_error": "Ní féidir PDF a rindreáil leis na socruithe reatha. Seiceáil na corrlaigh agus an scála le do thoil.",
"margins_default": "Réamhshocrú",
"margins_none": "Dada",
"margins_minimum": "Íosmhéid",
"margins_custom": "Saincheaptha",
"margin_top": "Barr",
"margin_right": "Ar dheis",
"margin_bottom": "Bun",
"margin_left": "Ar chlé",
"page_ranges": "Leathanaigh",
"page_ranges_hint": "Fág folamh chun na leathanaigh go léir a phriontáil.",
"page_ranges_invalid": "Formáid neamhbhailí. Úsáid m.sh. 1-5, 8, 11-13.",
"page_ranges_placeholder": "m.sh. 1-5, 8, 11-13"
},
"revisions": {
"note_revisions": "Athbhreithnithe Nótaí",
"delete_all_revisions": "Scrios gach athbhreithniú ar an nóta seo",
"delete_all_button": "Scrios gach athbhreithniú",
"help_title": "Cabhair le hathbhreithnithe nótaí",
"confirm_delete_all": "Ar mhaith leat gach athbhreithniú ar an nóta seo a scriosadh?",
"no_revisions": "Gan aon athbhreithnithe don nóta seo go fóill...",
"restore_button": "Athchóirigh",
"highlight_changes": "Aibhsigh athruithe",
"diff_on": "Taispeáin an difríocht",
"diff_off": "Taispeáin ábhar",
"diff_on_hint": "Cliceáil chun difríocht foinse an nóta a thaispeáint",
"diff_off_hint": "Cliceáil chun ábhar an nóta a thaispeáint",
"diff_not_available": "Níl an difríocht ar fáil.",
"confirm_restore": "Ar mhaith leat an t-athbhreithniú seo a athbhunú? Scríobhfaidh sé seo teideal agus ábhar reatha an nóta leis an athbhreithniú seo.",
"delete_button": "Scrios",
"confirm_delete": "Ar mhaith leat an t-athbhreithniú seo a scriosadh?",
"revisions_deleted": "Scriosadh athbhreithnithe nótaí.",
"revision_restored": "Tá athbhreithniú an nóta athchóirithe.",
"revision_deleted": "Scriosadh athbhreithniú an nóta.",
"snapshot_interval": "Eatramh Léirmheasa ar Nóta: {{seconds}}s.",
"maximum_revisions": "Teorainn maidir le hathbhreithniú nóta: {{number}}.",
"save_revision_now": "Sábháil athbhreithniú anois",
"save_named_revision": "Sábháil athbhreithniú ainmnithe...",
"snapshot_header": "Léargas athbhreithnithe nóta",
"snapshot_interval_value": "Eatramh: {{seconds}}s",
"snapshot_limit_value": "Teorainn: {{number}}",
"settings": "Socruithe Athbhreithnithe Nóta",
"menu_tooltip": "Roghanna athbhreithnithe",
"download_button": "Íoslódáil",
"mime": "MIME: ",
"file_size": "Méid comhaid:",
"preview_not_available": "Níl réamhamharc ar fáil don chineál nóta seo.",
"save_revision": "Sábháil athbhreithniú",
"save_revision_tooltip": "Sábháil pictiúr den nóta reatha de láimh",
"description_placeholder": "Ainmnigh an t-athbhreithniú seo",
"revision_saved": "Tá athbhreithniú an nóta sábháilte.",
"edit_description": "Cuir ainm in eagar",
"description_updated": "Tá ainm an athbhreithnithe nuashonraithe.",
"source_auto": "Uath-shábháil",
"source_manual": "Sábháil de láimh",
"source_etapi": "ETAPI",
"source_llm": "LLM",
"source_restore": "Athchóirigh",
"source_unknown": "Roghbhlúire",
"date_today": "Inniu",
"date_yesterday": "Inné",
"date_this_week": "An tseachtain seo",
"date_this_month": "An mhí seo",
"source_description_auto": "Sábháilte go huathoibríoch ag an gcóras ag eatraimh rialta",
"source_description_manual": "Sábháilte de láimh ag an úsáideoir",
"source_description_etapi": "Cruthaithe tríd an API Seachtrach Trilium",
"source_description_llm": "Cruthaithe ag an gcúntóir AI",
"source_description_restore": "Sábháilte roimh athchóiriú an athbhreithnithe roimhe seo",
"source_description_unknown": "Foinse gan fáil"
},
"auto_link_attribute_list": {
"title": "Tréithe an Chórais"
},
"revisions_snapshot": {
"title": "Athbhreithnithe Nótaí"
},
"launcher_button_context_menu": {
"remove_from_launch_bar": "Bain den bharra lainseála"
},
"display_mode": {
"source": "Radharc foinse",
"split": "Radharc scoilte",
"preview": "Réamhamharc"
},
"common": {
"save": "Sábháil",
"cancel": "Cealaigh"
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "ट्रिलियम नोट्स के बारें में",
"build_date": "निर्माण की तारीख:",
"app_version": "ऐप वर्ज़न:",
"db_version": "DB वर्ज़न:",
"build_revision": "बिल्ड रिविज़न:",
"homepage": "मुखपृष्ठ:",
"sync_version": "सिंक वर्शन:",
"data_directory": "डेटा डायरेक्टरी:"
},
"toast": {
@@ -283,33 +276,6 @@
"undelete_link": "वापस लाएं",
"confirm_undelete": "क्या आप इस नोट और इसके सब-नोट्स को वापस लाना चाहते हैं?"
},
"revisions": {
"note_revisions": "नोट रिविज़न",
"delete_all_revisions": "इस नोट के सभी रिविज़न डिलीट करें",
"delete_all_button": "सभी रिविज़न डिलीट करें",
"help_title": "नोट रिविज़न पर मदद",
"confirm_delete_all": "क्या आप इस नोट के सभी रिविज़न डिलीट करना चाहते हैं?",
"no_revisions": "इस नोट के लिए अभी तक कोई रिविज़न नहीं है..।",
"restore_button": "रिस्टोर करें",
"diff_on": "Diff दिखाएं",
"diff_off": "कंटेंट दिखाएं",
"diff_on_hint": "नोट सोर्स का अंतर (diff) देखने के लिए क्लिक करें",
"diff_off_hint": "नोट कंटेंट देखने के लिए क्लिक करें",
"diff_not_available": "Diff उपलब्ध नहीं है।",
"confirm_restore": "क्या आप इस रिविज़न को रिस्टोर करना चाहते हैं? इससे नोट का मौजूदा टाइटल और कंटेंट इस रिविज़न से बदल जाएगा।",
"delete_button": "डिलीट करें",
"confirm_delete": "क्या आप इस रिविज़न को डिलीट करना चाहते हैं?",
"revisions_deleted": "नोट रिविज़न डिलीट कर दिए गए हैं।",
"revision_restored": "नोट रिविज़न रिस्टोर कर दिया गया है।",
"revision_deleted": "नोट रिविज़न डिलीट कर दिया गया है।",
"snapshot_interval": "नोट रिविज़न स्नैपशॉट अंतराल: {{seconds}}s।",
"maximum_revisions": "नोट रिविज़न स्नैपशॉट लिमिट: {{number}}।",
"settings": "नोट रिविज़न सेटिंग्स",
"download_button": "डाउनलोड करें",
"mime": "MIME: ",
"file_size": "फ़ाइल साइज़:",
"preview_not_available": "इस नोट टाइप के लिए प्रिव्यू उपलब्ध नहीं है।"
},
"sort_child_notes": {
"sort_children_by": "सब-नोट्स को इसके अनुसार सॉर्ट करें..।",
"sorting_criteria": "सॉर्टिंग का आधार",
@@ -1107,7 +1073,6 @@
},
"database_integrity_check": {
"title": "डेटाबेस इंटीग्रिटी चेक (Database Integrity Check)",
"description": "यह चेक करेगा कि डेटाबेस SQLite लेवल पर खराब तो नहीं हुआ है। डेटाबेस के साइज़ के हिसाब से इसमें कुछ समय लग सकता है।",
"check_button": "डेटाबेस इंटीग्रिटी चेक करें",
"checking_integrity": "डेटाबेस इंटीग्रिटी चेक की जा रही है..।",
"integrity_check_succeeded": "इंटीग्रिटी चेक सफल रहा - कोई समस्या नहीं मिली।",
@@ -1145,10 +1110,7 @@
"note_tree_font": "नोट ट्री फ़ॉन्ट",
"note_detail_font": "नोट डिटेल फ़ॉन्ट",
"monospace_font": "मोनोस्पेस (कोड) फ़ॉन्ट",
"note_tree_and_detail_font_sizing": "ध्यान दें कि ट्री और डिटेल फ़ॉन्ट का साइज़ मुख्य फ़ॉन्ट साइज़ के हिसाब से होता है।",
"not_all_fonts_available": "हो सकता है कि लिस्ट में दिए गए सभी फ़ॉन्ट्स आपके सिस्टम पर न हों।",
"apply_font_changes": "फ़ॉन्ट के बदलाव लागू करने के लिए, यहाँ क्लिक करें",
"reload_frontend": "फ्रंटेंड रीलोड करें",
"generic-fonts": "सामान्य फ़ॉन्ट्स",
"sans-serif-system-fonts": "Sans-serif सिस्टम फ़ॉन्ट्स",
"serif-system-fonts": "Serif सिस्टम फ़ॉन्ट्स",
@@ -1238,7 +1200,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "अटैचमेंट मिटाने का समय (Erasure Timeout)",
"attachment_auto_deletion_description": "अगर अटैचमेंट का उनके नोट में कोई लिंक नहीं बचता, तो वे तय समय के बाद अपने-आप डिलीट (और मिटा) दिए जाते हैं।",
"erase_attachments_after": "इतने समय बाद बिना इस्तेमाल वाले अटैचमेंट्स मिटाएं:",
"manual_erasing_description": "आप इसे खुद भी मिटा सकते हैं (बिना ऊपर दिए समय का इंतज़ार किए):",
"erase_unused_attachments_now": "बिना इस्तेमाल वाले अटैचमेंट नोट्स अभी मिटाएं",
@@ -1250,7 +1211,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "नोट मिटाने का समय (Erasure Timeout)",
"note_erasure_description": "डिलीट किए गए नोट्स (और एट्रीब्यूट्स, रिवीजन्स...) पहले सिर्फ 'डिलीट' मार्क किए जाते हैं और उन्हें 'Recent Notes' से वापस लाया जा सकता है। कुछ समय बाद ये नोट्स 'मिटा' (erase) दिए जाते हैं जिसके बाद इन्हें वापस नहीं लाया जा सकता। यह सेटिंग डिलीट और मिटाने के बीच के समय को तय करती है।",
"erase_notes_after": "इतने समय बाद नोट्स मिटाएं:",
"manual_erasing_description": "आप नोट्स को खुद भी मिटा सकते हैं (बिना ऊपर दिए समय का इंतज़ार किए):",
"erase_deleted_notes_now": "डिलीट किए गए नोट्स अभी मिटाएं",
@@ -1340,7 +1300,6 @@
"first-week-contains-first-thursday": "पहले हफ्ते में साल का पहला गुरुवार शामिल है",
"first-week-has-minimum-days": "पहले हफ्ते में कम-से-कम इतने दिन हों",
"min-days-in-first-week": "पहले हफ्ते में न्यूनतम दिन",
"first-week-info": "\"पहले हफ्ते में साल का पहला गुरुवार\" ISO 8601 स्टैण्डर्ड पर आधारित है।",
"first-week-warning": "पहले हफ्ते की सेटिंग्स बदलने से पुराने 'Week Notes' में गड़बड़ी हो सकती है।",
"formatting-locale": "तारीख और नंबर फॉर्मेट",
"formatting-locale-auto": "ऐप की भाषा के अनुसार"
@@ -1465,9 +1424,6 @@
"server_address": "सर्वर एड्रेस (Address)",
"timeout": "सिंक समय-सीमा (Timeout)",
"proxy_label": "सिंक प्रॉक्सी सर्वर (वैकल्पिक)",
"note": "नोट",
"note_description": "अगर आप प्रॉक्सी खाली छोड़ते हैं, तो सिस्टम प्रॉक्सी का इस्तेमाल होगा।",
"special_value_description": "एक खास वैल्यू <code>noproxy</code> भी है जो सिस्टम प्रॉक्सी को नज़रअंदाज़ करने के लिए मजबूर करती है।",
"save": "सेव करें",
"help": "मदद",
"test_title": "सिंक टेस्ट",

View File

@@ -1,13 +1,6 @@
{
"about": {
"title": "A Trilium Notes-ról",
"homepage": "Kezdőlap:",
"app_version": "Alkalmazás verziója:",
"db_version": "Adatbázis verzió:",
"sync_version": "Verzió szinkronizálás :",
"build_revision": "Build revízió:",
"data_directory": "Adatkönyvtár:",
"build_date": "Build dátum:"
"data_directory": "Adatkönyvtár:"
},
"toast": {
"critical-error": {

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Tentang Trilium Notes",
"homepage": "Halaman utama:",
"app_version": "Versi Aplikasi:",
"db_version": "Versi DB:",
"sync_version": "Versi sinkronisasi:",
"build_date": "Tanggal pembuatan:",
"build_revision": "Revisi pembuatan:",
"data_directory": "Direktori data:"
},
"toast": {

View File

@@ -1,13 +1,6 @@
{
"about": {
"app_version": "Versione dell'app:",
"db_version": "Versione DB:",
"sync_version": "Versione Sync:",
"data_directory": "Cartella dati:",
"title": "Informazioni su Trilium Notes",
"build_date": "Data della build:",
"build_revision": "Revisione della build:",
"homepage": "Homepage:"
"data_directory": "Cartella dati:"
},
"toast": {
"critical-error": {
@@ -90,12 +83,22 @@
"delete_notes": {
"close": "Chiudi",
"delete_all_clones_description": "Elimina anche tutti i cloni (può essere ripristinato nella sezione cambiamenti recenti)",
"erase_notes_description": "L'eliminazione normale (soft) marca le note come eliminate e potranno essere recuperate entro un certo lasso di tempo (dalla finestra dei cambiamenti recenti). Selezionando questa opzione le note si elimineranno immediatamente e non sarà possibile recuperarle.",
"erase_notes_description": "Cancella immediatamente le note invece di effettuare una cancellazione temporanea. Questa operazione non può essere annullata e comporterà il riavvio dell'applicazione.",
"erase_notes_warning": "Elimina le note in modo permanente (non potrà essere disfatto), compresi tutti i cloni. Ciò forzerà un nuovo caricamento dell'applicazione.",
"cancel": "Annulla",
"notes_to_be_deleted": "Le seguenti note saranno eliminate ({{notesCount}})",
"notes_to_be_deleted": "Note da eliminare ({{notesCount}})",
"no_note_to_delete": "Nessuna nota sarà eliminata (solo i cloni).",
"broken_relations_to_be_deleted": "Le seguenti relazioni saranno interrotte ed eliminate ({{relationCount}})"
"broken_relations_to_be_deleted": "Relazioni interrotte ({{relationCount}})",
"title": "Eliminazione note",
"clones_label": "Cloni",
"delete_clones_description_one": "Elimina anche {{count}} altro clone. L'operazione può essere annullata nella pagina delle modifiche recenti.",
"delete_clones_description_many": "Elimina anche {{count}} altri cloni. L'operazione può essere annullata nella pagina delle modifiche recenti.",
"delete_clones_description_other": "Elimina anche {{count}} altri cloni. L'operazione può essere annullata nella pagina delle modifiche recenti.",
"erase_notes_label": "Elimina definitivamente",
"table_note_with_relation": "Nota relativa a",
"table_relation": "Relazione",
"table_points_to": "Punti verso (eliminato)",
"delete": "Eliminazione"
},
"info": {
"okButton": "OK",
@@ -460,7 +463,8 @@
"enable_daily_backup": "Abilita i backup giornalieri",
"no_backup_yet": "Ancora nessuna archiviazione",
"automatic_backup": "Backup Automatico",
"automatic_backup_description": "Trilium può eseguire automaticamente il backup del database:"
"automatic_backup_description": "Trilium può eseguire automaticamente il backup del database:",
"download": "Scarica"
},
"backend_log": {
"refresh": "Aggiorna"
@@ -475,7 +479,6 @@
"check_button": "Controllo dell'integrità del database",
"checking_integrity": "Controllo dell'integrità del database in corso...",
"title": "Controllo di Integrità del database",
"description": "Controllerà che il database non sia corrotto a livello SQLite. Può durare un po' di tempo, a seconda della grandezza del DB.",
"integrity_check_failed": "Controllo di integrità fallito: {{results}}",
"integrity_check_succeeded": "Controllo di integrità riuscito: nessun problema riscontrato."
},
@@ -497,12 +500,10 @@
"save": "Salva",
"help": "Aiuto",
"server_address": "Indirizzo dell'istanza del server",
"note": "Nota",
"note_description": "Se si lascia vuota l'impostazione del proxy, verrà utilizzato il proxy di sistema (valido solo per le build desktop/electron).",
"special_value_description": "Un altro valore speciale è <code>noproxy</code> che forza l'ignoramento anche del proxy di sistema e rispetta <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"test_description": "Questo testerà la connessione e l'handshake con il server di sincronizzazione. Se il server di sincronizzazione non è inizializzato, questo lo imposterà per la sincronizzazione con il documento locale.",
"test_button": "Test di sincronizzazione",
"handshake_failed": "Handshake del server di sincronizzazione non riuscito, errore: {{message}}"
"handshake_failed": "Handshake del server di sincronizzazione non riuscito, errore: {{message}}",
"timeout_description": "Quanto tempo aspettare prima di rinunciare con una connessione lenta. Aumenta questo intervallo se hai una rete instabile."
},
"search_engine": {
"save_button": "Salva",
@@ -647,7 +648,6 @@
"first-week-contains-first-thursday": "La prima settimana contiene il primo giovedì dell'anno",
"first-week-has-minimum-days": "La prima settimana ha giorni ridotti",
"min-days-in-first-week": "Giorni minimi nella prima settimana",
"first-week-info": "La prima settimana che contiene il primo giovedì dell'anno si basa su <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> standard.",
"first-week-warning": "La modifica delle opzioni della prima settimana può causare duplicati con le note settimanali esistenti e queste ultime non verranno aggiornate di conseguenza.",
"formatting-locale": "Formato data e numero",
"formatting-locale-auto": "In base alla lingua dell'applicazione",
@@ -695,7 +695,8 @@
"box_size_small": "piccola (~ 10 righe)",
"box_size_medium": "media (~ 30 righe)",
"box_size_full": "completa (la casella mostra il testo completo)",
"button_include": "Includi nota"
"button_include": "Includi nota",
"box_size_expandable": "espandibile (nascosto per impostazione predefinita)"
},
"jump_to_note": {
"search_placeholder": "Cerca una nota per nome oppure digita > per i comandi...",
@@ -737,33 +738,6 @@
"undelete_link": "ripristinare",
"confirm_undelete": "Vuoi ripristinare questa nota e le sue sotto-note?"
},
"revisions": {
"note_revisions": "Note Revisioni",
"delete_all_revisions": "Elimina tutte le revisioni di questa nota",
"delete_all_button": "Elimina tutte le revisioni",
"help_title": "Aiuto sulle revisioni delle note",
"confirm_delete_all": "Vuoi eliminare tutte le revisioni di questa nota?",
"no_revisions": "Ancora nessuna revisione per questa nota...",
"restore_button": "Ripristina",
"diff_on": "Mostra differenze",
"diff_off": "Mostra contenuto",
"diff_on_hint": "Clicca per mostrare la fonte della nota diff",
"diff_off_hint": "Clicca per visualizzare il contenuto della nota",
"diff_not_available": "Diff non è disponibile.",
"confirm_restore": "Vuoi ripristinare questa revisione? Questo sovrascriverà il titolo e il contenuto attuali della nota con questa revisione.",
"delete_button": "Elimina",
"confirm_delete": "Vuoi eliminare questa revisione?",
"revisions_deleted": "Le revisioni delle note sono state eliminate.",
"revision_restored": "La revisione della nota è stata ripristinata.",
"revision_deleted": "La revisione della nota è stata eliminata.",
"snapshot_interval": "Nota Intervallo di revisione istantanea: {{seconds}}.",
"maximum_revisions": "Nota Limite istantaneo di revisione: {{number}}.",
"settings": "Nota Impostazioni di revisione",
"download_button": "Scarica",
"mime": "MIME: ",
"file_size": "Dimensione del file:",
"preview_not_available": "L'anteprima non è disponibile per questo tipo di nota."
},
"sort_child_notes": {
"sort_children_by": "Ordina i bambini per...",
"sorting_criteria": "Criteri di ordinamento",
@@ -1244,7 +1218,10 @@
"expand_first_level": "Espandi figli diretti",
"expand_nth_level": "Espandi {{depth}} livelli",
"expand_all_levels": "Espandi tutti i livelli",
"hide_child_notes": "Nascondi note secondarie nell'albero"
"hide_child_notes": "Nascondi note secondarie nell'albero",
"open_all_in_tabs": "Apri tutto",
"open_all_in_tabs_tooltip": "Apri tutti i risultati in nuove schede",
"open_all_confirm": "Verranno aperte {{count}} note in nuove schede. Vuoi continuare?"
},
"edited_notes": {
"no_edited_notes_found": "Nessuna nota modificata per questo giorno...",
@@ -1298,7 +1275,8 @@
"collapse": "Ritorna alle dimensioni normali",
"title": "Nota Mappa",
"fix-nodes": "Fissare i nodi",
"link-distance": "Distanza del collegamento"
"link-distance": "Distanza del collegamento",
"too-many-notes": "Questo sottoalbero contiene {{count}} note, un numero superiore al limite di {{max}} che può essere visualizzato nella mappa delle note."
},
"note_paths": {
"title": "Percorsi delle note",
@@ -1455,10 +1433,7 @@
"note_tree_font": "Carattere dell'albero delle note",
"note_detail_font": "Nota Dettaglio Carattere",
"monospace_font": "Monospace (codice) Font",
"note_tree_and_detail_font_sizing": "Si noti che le dimensioni dei caratteri dell'albero e dei dettagli sono relative all'impostazione della dimensione del carattere principale.",
"not_all_fonts_available": "Non tutti i font elencati potrebbero essere disponibili sul tuo sistema.",
"apply_font_changes": "Per applicare le modifiche al carattere, fare clic su",
"reload_frontend": "ricarica frontend",
"generic-fonts": "Caratteri generici",
"sans-serif-system-fonts": "Caratteri di sistema sans-serif",
"serif-system-fonts": "Caratteri di sistema Serif",
@@ -1564,7 +1539,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Timeout cancellazione allegato",
"attachment_auto_deletion_description": "Gli allegati vengono eliminati (e cancellati) automaticamente se non vengono più menzionati nella nota dopo un timeout definito.",
"erase_attachments_after": "Cancella gli allegati non utilizzati dopo:",
"manual_erasing_description": "È anche possibile attivare la cancellazione manualmente (senza considerare il timeout definito sopra):",
"erase_unused_attachments_now": "Cancella subito le note degli allegati non utilizzati",
@@ -1576,7 +1550,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Timeout cancellazione nota",
"note_erasure_description": "Le note eliminate (e gli attributi, le revisioni...) vengono inizialmente contrassegnate come eliminate ed è possibile recuperarle dalla finestra di dialogo Note recenti. Dopo un certo periodo di tempo, le note eliminate vengono \"cancellate\", il che significa che il loro contenuto non è più recuperabile. Questa impostazione consente di configurare l'intervallo di tempo tra l'eliminazione e la cancellazione definitiva della nota.",
"erase_notes_after": "Cancella le note dopo:",
"manual_erasing_description": "È anche possibile attivare la cancellazione manualmente (senza considerare il timeout definito sopra):",
"erase_deleted_notes_now": "Cancella subito le note eliminate",
@@ -1897,7 +1870,8 @@
"theme_none": "Nessuna evidenziazione della sintassi",
"theme_group_light": "Temi chiari",
"theme_group_dark": "Temi scuri",
"copy_title": "Copia negli appunti"
"copy_title": "Copia negli appunti",
"click_to_copy": "Clicca per copiare"
},
"classic_editor_toolbar": {
"title": "Formattazione"
@@ -2298,7 +2272,8 @@
"note_context_disabled": "Clicca per includere la nota corrente nel contesto",
"no_provider_message": "Non è stato configurato alcun fornitore di IA. Aggiungine uno per iniziare a chattare.",
"add_provider": "Aggiungi un fornitore di IA",
"sources_summary": "{{count}} fonti provenienti da {{sites}} siti"
"sources_summary": "{{count}} fonti provenienti da {{sites}} siti",
"stop": "Stop"
},
"sidebar_chat": {
"title": "Chat AI",
@@ -2348,7 +2323,11 @@
"web_search": "Ricerca sul web",
"note_in_parent": "<Note/> in <Parent/>",
"get_attachment": "Scarica l'allegato",
"get_attachment_content": "Leggi il contenuto dell'allegato"
"get_attachment_content": "Leggi il contenuto dell'allegato",
"rename_note": "Rinomina nota",
"delete_note": "Elimina nota",
"move_note": "Sposta nota",
"clone_note": "Clona nota"
}
},
"ocr": {
@@ -2380,5 +2359,12 @@
"linkBidirectional": "Collegamento bidirezionale",
"clickTips": "Clicca sul nodo di destinazione",
"summary": "Sommario"
},
"search": {
"title": "Cerca",
"fuzzy_matching_label": "Tolleranza agli errori di battitura nella ricerca",
"fuzzy_matching_description": "Si applica alla ricerca rapida e alla ricerca completa. Trova parole simili quando non ci sono corrispondenze esatte.",
"autocomplete_fuzzy_label": "Tolleranza agli errori di battitura nel completamento automatico",
"autocomplete_fuzzy_description": "Influisce sui comandi \"Vai alla nota\" e sui selettori di note. È più lento, ma tollera gli errori di digitazione."
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Trilium Notesについて",
"homepage": "ホームページ:",
"app_version": "アプリのバージョン:",
"db_version": "データベースのバージョン:",
"sync_version": "同期のバージョン:",
"build_date": "Build の日時:",
"build_revision": "Build のバージョン:",
"data_directory": "データの場所:"
},
"toast": {
@@ -41,7 +34,9 @@
"help_on_links": "リンクに関するヘルプ",
"search_note": "ノート名で検索",
"link_title_mirrors": "リンクタイトルはノートタイトルの変更を反映します",
"link_title_arbitrary": "リンクタイトルは自由に変更可能"
"link_title_arbitrary": "リンクタイトルは自由に変更可能",
"anchor": "アンカー(任意)",
"anchor_none": "なし(ノートへのリンク)"
},
"branch_prefix": {
"save": "保存",
@@ -106,13 +101,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": "ノートは削除されません(クローンのみ)。",
"cancel": "キャンセル",
"close": "閉じる",
"broken_relations_to_be_deleted": "次のリレーション ({{relationCount}})は壊れているので消去されます"
"broken_relations_to_be_deleted": "壊れたリレーション ({{relationCount}})",
"title": "ノートを削除",
"clones_label": "クローン",
"delete_clones_description_other": "他の {{count}} 件のクローンも削除します。最近の変更履歴から元に戻すことができます。",
"erase_notes_label": "完全に消去",
"table_note_with_relation": "リレーションがあるノート",
"table_relation": "リレーション",
"table_points_to": "参照先 (削除済み)",
"delete": "削除"
},
"calendar": {
"mon": "月",
@@ -175,11 +178,10 @@
"monday": "月曜日",
"first-week-of-the-year": "年の最初の週",
"first-week-contains-first-day": "最初の週には、元日が含まれる",
"first-week-contains-first-thursday": "最初の週には、その年の最初の木曜日が含まれる",
"first-week-contains-first-thursday": "最初の週には、最初の木曜日が含まれるISO 8601",
"first-week-has-minimum-days": "最初の週は最低日数",
"min-days-in-first-week": "最初の週の最低日数",
"first-week-info": "最初の週は、その年の最初の木曜日を含む週を指し、<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>規格に基づいています。",
"first-week-warning": "最初の週のオプションを変更すると、既存のウィークノートと重複する可能性があり、既存のウィークノートはそれに応じて更新されません。",
"first-week-warning": "この設定を変更すると、既存のウィークノートと重複が発生する可能性があります。",
"formatting-locale": "日付と数値のフォーマット",
"formatting-locale-auto": "アプリケーションの言語に基づいて",
"tuesday": "火曜日",
@@ -484,7 +486,13 @@
"export_as_image": "画像としてエクスポート",
"export_as_image_png": "PNG (raster)",
"export_as_image_svg": "SVG (vector)",
"view_ocr_text": "OCR テキストを表示"
"view_ocr_text": "OCR テキストを表示",
"word_wrap": "行の折り返し",
"word_wrap_auto": "自動",
"word_wrap_auto_description": "グローバル設定に従う",
"word_wrap_on": "オン",
"word_wrap_off": "オフ",
"save_named_revision": "名前を付けて変更履歴を保存..."
},
"command_palette": {
"export_note_title": "ノートをエクスポート",
@@ -603,7 +611,8 @@
"collections": "コレクション",
"ai-chat": "AI チャット",
"spreadsheet": "スプレッドシート",
"llm-chat": "AI チャット"
"llm-chat": "AI チャット",
"markdown": "Markdown"
},
"edited_notes": {
"no_edited_notes_found": "この日の編集されたノートはまだありません...",
@@ -647,33 +656,6 @@
"upload_success": "新しい画像の変更がアップロードされました。",
"upload_failed": "新しい画像の変更のアップロードに失敗しました: {{message}}"
},
"revisions": {
"download_button": "ダウンロード",
"delete_button": "削除",
"note_revisions": "ノートの変更履歴",
"delete_all_revisions": "このノートの変更履歴をすべて削除",
"delete_all_button": "変更履歴をすべて削除",
"help_title": "変更履歴のヘルプ",
"confirm_delete_all": "このノートのすべての変更履歴を削除しますか?",
"no_revisions": "このノートに変更履歴はまだありません...",
"restore_button": "復元",
"confirm_restore": "この変更を復元しますか?現在のノートのタイトルとコンテンツはこの変更で上書きされます。",
"confirm_delete": "この変更履歴を削除しますか?",
"revisions_deleted": "ノートの変更履歴は削除されました。",
"revision_restored": "ノートの変更が復元されました。",
"revision_deleted": "ノートの変更履歴は削除されました。",
"settings": "ノートの変更履歴の設定",
"file_size": "ファイルサイズ:",
"preview_not_available": "このノートタイプではプレビューは利用できません。",
"diff_on": "差分を表示",
"diff_off": "内容を表示",
"diff_on_hint": "クリックしてノートソースとの差分を表示",
"diff_off_hint": "クリックしてノートの内容を表示",
"diff_not_available": "差分は利用できません。",
"snapshot_interval": "ノートの変更履歴の記録間隔: {{seconds}} 秒。",
"maximum_revisions": "ノートの変更履歴の記録制限: {{number}}.",
"mime": "MIME: "
},
"attachments_actions": {
"download": "ダウンロード",
"open_externally": "外部で開く",
@@ -809,7 +791,8 @@
"label_note": "ノート",
"box_size_small": "スモール (~ 10 行)",
"box_size_medium": "ミディアム (~ 30 行)",
"box_size_full": "フル (ボックスに全文が表示されます)"
"box_size_full": "フル (ボックスに全文が表示されます)",
"box_size_expandable": "展開可能 (デフォルトでは折りたたまれています)"
},
"ancestor": {
"placeholder": "ノート名で検索",
@@ -841,20 +824,21 @@
"filling_entity_changes": "エンティティ変更行を入力中...",
"sync_rows_filled_successfully": "同期行が正常に入力されました",
"finished-successfully": "同期が正常に完了しました。",
"failed": "同期に失敗しました: {{message}}"
"failed": "同期に失敗しました: {{message}}",
"force_full_sync_label": "強制的な完全同期",
"force_full_sync_description": "同期サーバーとの完全同期を実行し、すべての変更を再アップロードします。",
"fill_entity_changes_label": "エンティティの変更を反映",
"fill_entity_changes_description": "エンティティの変更履歴を再構築します。同期処理で一部の変更が反映されていない場合に使用してください。"
},
"fonts": {
"fonts": "フォント",
"main_font": "インフォント",
"main_font": "インターフェース テキスト",
"font_family": "フォントファミリー",
"size": "サイズ",
"note_tree_font": "ノートツリーフォント",
"note_detail_font": "ノート詳細フォント",
"monospace_font": "等幅(コード)フォント",
"note_tree_and_detail_font_sizing": "ツリーと詳細のフォントサイズは、メインのフォントサイズに対して相対的であることに注意してください。",
"not_all_fonts_available": "リストされているすべてのフォントが、お使いのシステムで利用できるとは限りません。",
"apply_font_changes": "フォントの変更を適用するには、クリックしてください",
"reload_frontend": "フロントエンドをリロード",
"note_tree_font": "ノートツリー テキスト",
"note_detail_font": "ドキュメント テキスト",
"monospace_font": "等幅フォント",
"not_all_fonts_available": "リストにあるすべてのフォントが、お使いのシステムで利用できるとは限りません",
"generic-fonts": "一般的なフォント",
"sans-serif-system-fonts": "サンセリフのシステムフォント",
"serif-system-fonts": "セリフのシステムフォント",
@@ -864,7 +848,12 @@
"sans-serif": "サンセリフ",
"monospace": "等幅",
"system-default": "システムのデフォルト",
"theme_defined": "テーマが定義されました"
"theme_defined": "テーマが定義されました",
"custom_fonts": "カスタムフォントを使用",
"preview": "プレビュー",
"monospace_font_description": "コードノートとコードブロックに使用されます",
"size_relative_to_general": "サイズは一般的なフォントサイズを基準としています",
"apply_changes": "変更を適用するには再読み込みしてください"
},
"max_content_width": {
"title": "コンテンツ幅",
@@ -874,20 +863,23 @@
"centerContent": "コンテンツを中央に配置"
},
"theme": {
"title": "アプリのテーマ",
"theme_label": "テーマ",
"title": "ユーザーインターフェース",
"theme_label": "アプリケーションのテーマ",
"override_theme_fonts_label": "テーマのフォントを上書き",
"auto_theme": "レガシー(システムの配色に従う",
"light_theme": "レガシー(ライト",
"dark_theme": "レガシー(ダーク",
"triliumnext": "Triliumシステムの配色に従う",
"triliumnext-light": "Triliumライト",
"triliumnext-dark": "Triliumダーク",
"auto_theme": "システムの配色に従う",
"light_theme": "ライト",
"dark_theme": "ダーク",
"triliumnext": "システムの配色に従う",
"triliumnext-light": "ライト",
"triliumnext-dark": "ダーク",
"layout": "レイアウト",
"layout-vertical-title": "垂直",
"layout-horizontal-title": "水平",
"layout-vertical-description": "ランチャーバーは左側(デフォルト)",
"layout-horizontal-description": "ランチャーバーはタブバーの下にあり、タブバーは全幅に。"
"layout-horizontal-description": "ランチャーバーはタブバーの下にあり、タブバーは全幅に。",
"modern_themes": "モダン",
"legacy_themes": "レガシー",
"custom_themes": "カスタム"
},
"vim_key_bindings": {
"use_vim_keybindings_in_code_notes": "Vimキーバインド",
@@ -924,27 +916,30 @@
},
"search_engine": {
"title": "検索エンジン",
"custom_search_engine_info": "カスタム検索エンジンは、名前とURLの両方を設定する必要があります。どちらも設定されていない場合、DuckDuckGoがデフォルトの検索エンジンとして使用されます。",
"predefined_templates_label": "定義済みの検索エンジンのテンプレート",
"custom_search_engine_info": "選択したテキストをウェブ上で検索する際に使用します。設定されていない場合、DuckDuckGo が使用されます。",
"predefined_templates_label": "プリセット",
"bing": "Bing",
"baidu": "Baidu",
"duckduckgo": "DuckDuckGo",
"google": "Google",
"custom_name_label": "カスタム検索エンジンの名前",
"custom_name_placeholder": "カスタム検索エンジンの名前",
"custom_url_label": "カスタム検索エンジンのURLには、検索語句のプレースホルダーとして {keyword} を含める必要があります。",
"custom_url_placeholder": "検索エンジンの URL をカスタマイズ",
"save_button": "保存"
"custom_name_label": "名前",
"custom_name_placeholder": "検索エンジン",
"custom_url_label": "URL",
"custom_url_placeholder": "検索エンジンの URL",
"save_button": "保存",
"custom_url_description": "検索語句の代わりに {keyword} を使用してください。"
},
"tray": {
"title": "システムトレイ",
"enable_tray": "トレイを有効にする (この変更を適用にするには、Triliumを再起動する必要があります)"
"enable_tray": "トレイアイコン",
"enable_tray_description": "この変更を有効にするには、Trilium を再起動する必要があります。"
},
"heading_style": {
"title": "見出しのスタイル",
"plain": "プレーン",
"underline": "下線",
"markdown": "Markdownスタイル"
"markdown": "Markdownスタイル",
"description": "テキストノート内の見出しの表示スタイル。"
},
"highlights_list": {
"title": "ハイライトリスト",
@@ -973,20 +968,22 @@
"text_auto_read_only_size": {
"title": "自動読み取り専用のサイズ",
"description": "自動読み取り専用のノートサイズは、ノートが読み取り専用モード(パフォーマンス上の理由)で表示されるようになるサイズです。",
"label": "自動読み取り専用のサイズ(テキストノート)",
"label": "自動読み取り専用になるサイズ",
"unit": "文字"
},
"code_auto_read_only_size": {
"title": "自動読み取り専用のサイズ",
"description": "自動読み取り専用のノートサイズは、ノートが読み取り専用モード(パフォーマンス上の理由)で表示されるようになるサイズです。",
"unit": "文字",
"label": "自動読み取り専用のサイズ(コードノート)"
"label": "自動読み取り専用になるサイズ"
},
"custom_date_time_format": {
"title": "日付/時刻フォーマットのカスタム",
"title": "日付/時刻の形式",
"description": "<shortcut />またはツールバーから挿入される日付と時刻のフォーマットをカスタマイズする。 利用可能なトークンについては <doc>Day.js ドキュメント</doc> を参照してください。",
"format_string": "文字列形式:",
"formatted_time": "日付/時刻形式:"
"format_string": "書式文字列",
"formatted_time": "日付/時刻形式",
"description_short": "ツールバーから挿入する日付と時刻の形式をカスタマイズできます。",
"preview": "プレビュー: {{preview}}"
},
"backup": {
"automatic_backup": "自動バックアップ",
@@ -1002,7 +999,8 @@
"path": "パス",
"database_backed_up_to": "データベースは{{backupFilePath}}にバックアップされました",
"no_backup_yet": "バックアップがありません",
"download": "ダウンロード"
"download": "ダウンロード",
"title": "バックアップ"
},
"password": {
"wiki": "wiki",
@@ -1014,16 +1012,20 @@
"new_password_confirmation": "新パスワードの確認",
"change_password": "パスワードの変更",
"change_password_heading": "パスワードの変更",
"protected_session_timeout": "保護されたセッションのタイムアウト",
"protected_session_timeout_description": "保護されたセッションのタイムアウトは、保護されたセッションがブラウザのメモリから消去される時間です。これは、保護されたノートとの最後のやり取りから測定されます。参照",
"protected_session_timeout": "保護されたセッション",
"protected_session_timeout_description": "ブラウザのメモリからセッションが削除されるまでの非アクティブ時間。詳細はこちら",
"for_more_info": "詳細はこちら。",
"protected_session_timeout_label": "保護されたセッションのタイムアウト:",
"protected_session_timeout_label": "セッションが自動で終了するまでの時間",
"reset_confirmation": "パスワードをリセットすると、保護されているすべてのノートにアクセスできなくなります。本当にパスワードをリセットしますか?",
"reset_success_message": "パスワードがリセットされました。新しいパスワードを設定してください",
"set_password_heading": "パスワードの設定",
"set_password": "パスワードの設定",
"password_mismatch": "新しいパスワードが同じではありません。",
"password_changed_success": "パスワードが変更されました。OKを押すとTriliumがリロードされます。"
"password_changed_success": "パスワードが変更されました。OKを押すとTriliumがリロードされます。",
"change_password_description": "現在のパスワードを更新",
"reset_password": "パスワードをリセット",
"reset_password_description": "保護されたノートへのアクセス権を完全に失います",
"cancel": "キャンセル"
},
"spellcheck": {
"title": "スペルチェック",
@@ -1039,20 +1041,19 @@
"related_description": "スペルチェック対応言語とカスタム辞書を設定します。"
},
"sync_2": {
"config_title": "同期設定",
"server_address": "サーバーインスタンスのアドレス",
"timeout": "同期タイムアウト",
"proxy_label": "同期プロキシサーバー(任意)",
"note": "注",
"note_description": "プロキシ設定を空白のままにすると、システムプロキシが使用されます(デスクトップ/electronビルドにのみ適用されます。",
"special_value_description": "もう一つの特別な値は <code>noproxy</code> で、これはシステムプロキシさえも無視して、 <code>NODE_TLS_REJECT_UNAUTHORIZED</code> を尊重するように強制します。",
"config_title": "同期サーバー",
"server_address": "サーバーアドレス",
"timeout": "接続タイムアウト",
"proxy_label": "プロキシサーバー",
"save": "保存",
"help": "ヘルプ",
"test_title": "同期のテスト",
"test_description": "これは同期サーバの接続とハンドシェイクをテストします。同期サーバーが初期化されていない場合、ローカルドキュメントと同期するように設定します。",
"test_title": "接続テスト",
"test_description": "同期サーバーへの接続をテストします。初期化されていない場合は、同期の設定を行います。",
"test_button": "同期試行",
"handshake_failed": "同期サーバーのハンドシェイクに失敗しました。エラー: {{message}}",
"timeout_description": "同期接続が遅い場合に接続を諦めるまでの待機時間。ネットワークが不安定な場合は、この時間を長く設定してください。"
"timeout_description": "接続が遅い場合に接続を断念するまでの待機時間。",
"server_address_description": "同期先の Trilium サーバーの URL。",
"proxy_description": "システムのプロキシを使用する場合は空欄のままにしてください(デスクトップ版のみ)。すべてのプロキシをバイパスするには \"noproxy\" を使用してください。"
},
"api_log": {
"close": "閉じる"
@@ -1203,7 +1204,9 @@
"and_more": "...その他 {{count}} 件。",
"print_landscape": "PDF にエクスポートするときに、ページの向きを縦向きではなく横向きに変更します。",
"print_page_size": "PDF にエクスポートするときに、ページのサイズを変更します。サポートされる値: <code>A0</code>, <code>A1</code>, <code>A2</code>, <code>A3</code>, <code>A4</code>, <code>A5</code>, <code>A6</code>, <code>Legal</code>, <code>Letter</code>, <code>Tabloid</code>, <code>Ledger</code>。",
"textarea": "複数行テキスト"
"textarea": "複数行テキスト",
"print_scale": "PDF にエクスポートする際に、レンダリングされるコンテンツの縮尺を変更します。値の範囲は 0.110%)から 2200%)までで、デフォルト値は 1100%)です。",
"print_margins": "PDF に書き出す際に、ページ余白を設定します。<code>デフォルト</code>, <code>なし</code>, <code>最小</code>, または <code>上、右、下、左</code> のようなカスタム値をミリメートル単位で指定できます。"
},
"link_context_menu": {
"open_note_in_popup": "クイック編集",
@@ -1354,7 +1357,10 @@
"theme_none": "シンタックスハイライトなし",
"theme_group_light": "ライトテーマ",
"theme_group_dark": "ダークテーマ",
"copy_title": "クリップボードにコピー"
"copy_title": "クリップボードにコピー",
"click_to_copy": "クリックしてコピー",
"tab_width": "タブ幅",
"tab_width_unit": "スペース"
},
"editor": {
"title": "エディター"
@@ -1370,7 +1376,8 @@
"title": "固定",
"description": "編集ツールは「書式設定」のリボンタブに表示されます。"
},
"multiline-toolbar": "ツールバーが収まりきらない場合は複数行で表示する。"
"multiline-toolbar": "ツールバーが収まりきらない場合は複数行で表示",
"toolbar_style": "ツールバーのスタイル"
}
},
"electron_context_menu": {
@@ -1391,7 +1398,7 @@
"days": "日"
},
"share": {
"title": "共有設定",
"title": "共有",
"redirect_bare_domain": "ネイキッドドメインを共有ページにリダイレクト",
"redirect_bare_domain_description": "匿名のユーザーをログイン画面ではなく共有ページにリダイレクトします",
"show_login_link_description": "共有ページの下部にログインリンクを追加",
@@ -1436,12 +1443,12 @@
"message_macos": "TriliumNext は現在、Rosetta 2による翻訳環境で実行されています。つまり、Apple Silicon MacではIntel (x64)バージョンを使用していることになります。これはパフォーマンスとバッテリー寿命に重大な影響を及ぼします。"
},
"editorfeatures": {
"emoji_completion_enabled": "絵文字のオートコンプリートを有効",
"note_completion_enabled": "ノートのオートコンプリートを有効",
"emoji_completion_description": "有効にすると、「:」に続けて絵文字の名前を入力することで、テキストに絵文字を簡単に挿入できます。",
"note_completion_description": "有効にすると、「@」 に続けてノートのタイトルを入力することで、ノートへのリンクを作成できます。",
"slash_commands_enabled": "スラッシュコマンドを有効",
"slash_commands_description": "有効にすると、改行や見出しの挿入などの編集コマンドは、「/」 と入力して切り替えることができます。",
"emoji_completion_enabled": "絵文字のオートコンプリート",
"note_completion_enabled": "ノートのオートコンプリート",
"emoji_completion_description": "絵文字は \":\" の後に絵文字の名前を入力することで、テキストに絵文字を簡単に挿入できます。",
"note_completion_description": "ノートへのリンクは \"@\" の後にノートのタイトルを入力することで作成できます。",
"slash_commands_enabled": "スラッシュコマンド",
"slash_commands_description": "改行や見出しの挿入などの編集コマンドは \"/\" を入力して切り替えることができます。",
"title": "機能"
},
"table_context_menu": {
@@ -1580,11 +1587,11 @@
},
"database_anonymization": {
"title": "データベースの匿名化",
"full_anonymization": "完全匿名化",
"full_anonymization_description": "この操作により、データベースの新しいコピーが作成され、匿名化されます(すべてのノートの内容を削除し、構造と一部の非機密メタデータのみを残します)。これにより、個人データが漏洩する心配なく、デバッグ目的でオンライン共有できます。",
"full_anonymization": "完全匿名化",
"full_anonymization_description": "ノートの内容をすべて削除し、構造と機密性の低いメタデータのみを残したデータベースのコピーを作成します。問題のデバッグ時にオンライン共有しても安全です。",
"save_fully_anonymized_database": "完全に匿名化されたデータベースを保存",
"light_anonymization": "軽い匿名化",
"light_anonymization_description": "この操作により、データベースの新しいコピーが作成され、軽い匿名化が適用されます。具体的には、すべてのノートの内容のみが削除され、タイトル属性はそのまま残ります。さらに、カスタムJSフロントエンド/バックエンドスクリプトノートとカスタムウィジェットもそのまま残ります。これにより、問題のデバッグのためのコンテキストがより多く提供されます。",
"light_anonymization_description": "ノートの内容は削除しますが、タイトル属性、カスタムスクリプト/ウィジェットは残します。デバッグのためのコンテキストがより多く提供されます。",
"choose_anonymization": "完全に匿名化したデータベースを提供するか、軽く匿名化したデータベースを提供するかは、あなた自身が決めることができます。完全に匿名化されたDBであっても非常に有用ですが、場合によっては軽く匿名化されたDBの方がバグの特定と修正のプロセスを速めることができます。",
"save_lightly_anonymized_database": "軽く匿名化されたデータベースを保存",
"existing_anonymized_databases": "既存の匿名化データベース",
@@ -1593,18 +1600,22 @@
"error_creating_anonymized_database": "匿名化データベースの作成に失敗しました。詳細はバックエンドログを確認してください",
"successfully_created_fully_anonymized_database": "完全に匿名化されたデータベースを {{anonymizedFilePath}} に作成",
"successfully_created_lightly_anonymized_database": "軽く匿名化されたデータベースを {{anonymizedFilePath}} に作成",
"no_anonymized_database_yet": "匿名化されたデータベースはまだありません。"
"no_anonymized_database_yet": "匿名化されたデータベースはまだありません。",
"description": "問題のデバッグ時に開発者と共有するために、個人データを公開することなく、データベースの匿名化されたコピーを作成します。"
},
"database_integrity_check": {
"title": "データベースの整合性チェック",
"description": "これは、データベースがSQLiteレベルで破損がないかをチェックします。DBのサイズによっては時間がかかる場合があります。",
"check_button": "データベースの整合性をチェック",
"checking_integrity": "データベースの整合性をチェックしています...",
"integrity_check_succeeded": "整合性チェックに成功 - 問題は見つかりませんでした。",
"integrity_check_failed": "整合性チェックに失敗: {{results}}"
"integrity_check_failed": "整合性チェックに失敗: {{results}}",
"check_integrity_label": "データベースの整合性チェック",
"check_integrity_description": "SQLite レベルでデータベースが破損していないことを確認します。"
},
"code-editor-options": {
"title": "エディター"
"title": "エディター",
"tab_width": "タブ幅",
"tab_width_unit": "スペース"
},
"search_string": {
"title_column": "文字列検索:",
@@ -1748,14 +1759,18 @@
"find_and_fix_button": "一貫性の問題を見つけて修正する",
"finding_and_fixing_message": "一貫性の問題を見つけて修正中…",
"title": "一貫性をチェック",
"issues_fixed_message": "発見された可能性のある一貫性の問題はすべて修正されました。"
"issues_fixed_message": "発見された可能性のある一貫性の問題はすべて修正されました。",
"find_and_fix_label": "整合性の問題を検出して修正",
"find_and_fix_description": "データベース内のデータ整合性の問題をスキャンし、自動的に修復します。"
},
"vacuum_database": {
"title": "データベースのバキューム",
"description": "これによりデータベースが再構築され、通常はデータベースファイルのサイズが小さくなります。実際のデータは変更されません。",
"button_text": "データベースをバキューム",
"vacuuming_database": "データベースのバキュームを実行中...",
"database_vacuumed": "データベースのバキューム処理が完了しました"
"database_vacuumed": "データベースのバキューム処理が完了しました",
"vacuum_label": "データベースのバキューム",
"vacuum_description": "データベースを再構築してファイルサイズを削減します。データは変更されません。"
},
"ribbon": {
"promoted_attributes_message": "プロモート属性がノートに存在する場合、プロモート属性のリボンタブが自動的に開きます",
@@ -1763,12 +1778,12 @@
"widgets": "リボンウィジェット"
},
"ui-performance": {
"enable-motion": "トランジションとアニメーションを有効にする",
"enable-shadows": "影を有効にする",
"enable-backdrop-effects": "メニュー、ポップアップ、パネルの背景効果を有効にする",
"enable-motion": "画面遷移とアニメーション",
"enable-shadows": "影",
"enable-backdrop-effects": "メニュー、ポップアップ、パネルの背景効果",
"title": "パフォーマンス",
"enable-smooth-scroll": "スムーズスクロールを有効にする",
"app-restart-required": "(変更を有効にするにはアプリケーションの再起動が必要です"
"enable-smooth-scroll": "スムーズスクロール",
"app-restart-required": "アプリの再起動が必要です"
},
"code_mime_types": {
"title": "ドロップダウンで利用可能なMIMEタイプ",
@@ -1777,37 +1792,43 @@
"tooltip_code_note_syntax": "コードノート"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "添付ファイル消去のタイムアウト",
"attachment_auto_deletion_description": "定義されたタイムアウト後にノートによって参照されなくなった場合、添付ファイルは自動的に削除 (および消去) されます。",
"erase_attachments_after": "使用されていない添付ファイルを消去する期間:",
"manual_erasing_description": "手動で消去をトリガーすることもできます (上記で定義したタイムアウトを考慮せずに):",
"erase_unused_attachments_now": "使用されていない添付ノートを今すぐ消去",
"unused_attachments_erased": "使用されていない添付ファイルは削除されました。"
"attachment_erasure_timeout": "未使用の添付ファイル",
"erase_attachments_after": "未使用の添付ファイルを削除するまでの期間",
"manual_erasing_description": "上記のタイムアウト設定を無視して、手動で削除を実行する。",
"erase_unused_attachments_now": "未使用の添付ノートを今すぐ削除",
"unused_attachments_erased": "使用されていない添付ファイルは削除されました。",
"description": "どのノートからも参照されていない添付ファイルは未使用とみなされ、一定期間経過後に自動的に削除されま。",
"erase_attachments_after_description": "未使用の添付ファイルが完全に削除されるまでの時間。"
},
"network_connections": {
"network_connections_title": "ネットワーク接続",
"check_for_updates": "アップデートを自動的に確認する"
"network_connections_title": "ネットワーク",
"check_for_updates": "アップデートを自動的に確認する",
"check_for_updates_description": "GitHub で新しいバージョンをチェックし、利用可能な場合はグローバルメニューに通知を表示します。"
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "ノート消去のタイムアウト",
"note_erasure_description": "削除されたノート(および属性、変更履歴など)最初は削除済みとしてマークされるだけで、「最近の変更」ダイアログから復元できます。一定期間が経過すると、削除されたノートは「消去」され、内容は復元できなくなります。この設定では、ノートを削除してから消去するまでの期間を設定できます。",
"erase_notes_after": "ノートを消去する間隔:",
"manual_erasing_description": "手動で消去をトリガーすることもできます (上記で定義したタイムアウトを考慮せずに):",
"note_erasure_timeout_title": "削除されたノート",
"erase_notes_after": "ノートを削除するまでの期間",
"manual_erasing_description": "上記のタイムアウト設定を無視して、手動で削除を実行する。",
"erase_deleted_notes_now": "削除したノートを今すぐ消去",
"deleted_notes_erased": "削除されたノートは消去されました。"
"deleted_notes_erased": "削除されたノートは消去されました。",
"description": "削除されたノートは、最初は削除済みとしてマークされるだけで最近の変更から復元できます。一定期間が経過すると、完全に削除されます。",
"erase_notes_after_description": "削除されたノートが完全に削除されるまでの時間。"
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "ノートの変更履歴の記録間隔",
"note_revisions_snapshot_description": "ノートの変更履歴の記録間隔は、そのノートに対して新しい変更が作成されるまでの時間です。詳細については、<doc>wiki</doc> をご覧ください。",
"snapshot_time_interval_label": "ノートの変更履歴が記憶される時間:"
"snapshot_time_interval_label": "スナップショットの間隔",
"note_revisions_snapshot_description_short": "新しいノートの変更履歴が作成されるまでの時間。"
},
"revisions_snapshot_limit": {
"note_revisions_snapshot_limit_title": "ノートの変更履歴の記録制限",
"note_revisions_snapshot_limit_description": "ノートの変更履歴の記録制限とは、各ノートに保存できる変更履歴の最大数を指します。-1 は制限なし、0 はすべての変更履歴を削除することを意味します。#versioningLimit ラベルを使用して、1 つのノートの最大変更数を設定できます。",
"snapshot_number_limit_label": "ノートの変更履歴の記録数の制限:",
"snapshot_number_limit_label": "最大変更履歴数",
"snapshot_number_limit_unit": "スナップショット",
"erase_excess_revision_snapshots": "余分な変更履歴を今すぐ消去",
"erase_excess_revision_snapshots_prompt": "余分な変更履歴が消去されました。"
"erase_excess_revision_snapshots_prompt": "余分な変更履歴が消去されました。",
"note_revisions_snapshot_limit_description_short": "ノートごとの最大変更履歴数。無制限の場合は -1、無効にする場合は 0 を指定してください。",
"erase_excess_revision_snapshots_description": "すべてのノートで、制限を超えた変更履歴を削除します。"
},
"editability_select": {
"note_is_read_only": "ノートは読み取り専用ですが、ボタンをクリックすると編集できます。",
@@ -1831,7 +1852,7 @@
"note_detail": {
"could_not_find_typewidget": "タイプ {{type}} の typeWidget が見つかりませんでした",
"printing": "印刷中です...",
"printing_pdf": "PDF へのエクスポート中です...",
"printing_pdf": "印刷プレビューを準備中...",
"print_report_title": "レポートを印刷",
"print_report_collection_content_other": "コレクション内の {{count}} 件のノートは、サポートされていないか保護されているため、印刷できませんでした。",
"print_report_collection_details_button": "詳細を見る",
@@ -1851,7 +1872,9 @@
"entrypoints": {
"note-revision-created": "ノートの改訂版が作成されました。",
"sql-error": "SQL クエリの実行中にエラーが発生しました: {{message}}",
"note-executed": "ノートが実行されました。"
"note-executed": "ノートが実行されました。",
"save-named-revision-title": "名前を付けて変更履歴を保存",
"save-named-revision-message": "この変更履歴の名前を入力してください(名前なしの場合は空欄のままにしてください):"
},
"branches": {
"cannot-move-notes-here": "ここにノートを移動することはできません。",
@@ -1943,7 +1966,9 @@
"related_code_notes": "コードノートの配色",
"ui": "ユーザーインターフェース",
"ui_old_layout": "旧レイアウト",
"ui_new_layout": "新しいレイアウト"
"ui_new_layout": "新しいレイアウト",
"ui_layout_style": "レイアウトスタイル",
"ui_layout_orientation": "ランチャーバーの方向"
},
"units": {
"percentage": "%"
@@ -2115,7 +2140,19 @@
"code_note_switcher": "言語モードを変更",
"backlinks_other": "{{count}} バックリンク",
"attachments_other": "{{count}} 件の添付ファイル",
"note_paths_other": "{{count}} 個のパス"
"note_paths_other": "{{count}} 個のパス",
"tab_width": "タブ幅: {{width}}",
"tab_width_title": "タブ幅を変更",
"tab_width_spaces": "{{count}} スペース",
"tab_width_spaces_short": "スペース: {{width}}",
"tab_width_tabs": "タブ: {{width}}",
"tab_width_use_default": "デフォルトを使用 ({{width}})",
"tab_width_use_default_style": "デフォルトを使用 ({{style}})",
"tab_width_display_header": "表示幅",
"tab_width_reindent_header": "コンテンツのインデントを再設定",
"tab_width_style_header": "インデントを使用",
"tab_width_style_spaces": "スペース",
"tab_width_style_tabs": "タブ"
},
"breadcrumb": {
"hoisted_badge": "ホイスト",
@@ -2274,7 +2311,8 @@
"note_context_disabled": "クリックして現在のノートをコンテキストに含める",
"no_provider_message": "AI プロバイダーが設定されていません。チャットを開始するには、プロバイダーを追加してください。",
"add_provider": "AI プロバイダーを追加",
"sources_summary": "{{count}} 件のソースを {{sites}} サイトから取得"
"sources_summary": "{{count}} 件のソースを {{sites}} サイトから取得",
"stop": "停止"
},
"sidebar_chat": {
"title": "AI チャット",
@@ -2338,7 +2376,11 @@
"web_search": "Web 検索",
"note_in_parent": "<Note/> を <Parent/>",
"get_attachment": "添付ファイルを取得",
"get_attachment_content": "添付ファイルの内容を読み取る"
"get_attachment_content": "添付ファイルの内容を読み取る",
"rename_note": "ノート名を変更",
"delete_note": "ノートを削除",
"move_note": "ノートを移動",
"clone_note": "ノートをクローン"
}
},
"ocr": {
@@ -2356,5 +2398,126 @@
"processing_complete": "OCR 処理が完了しました。",
"text_filtered_low_confidence": "OCR は {{confidence}}% の信頼度でテキストを検出しましたが、最小しきい値が {{threshold}}% であるため、破棄されました。",
"open_media_settings": "設定を開く"
},
"database": {
"title": "データベース"
},
"search": {
"title": "検索",
"fuzzy_matching_label": "検索時の入力ミス許容度",
"fuzzy_matching_description": "クイック検索とフル検索に影響します。完全一致しない場合でも類似語を検索します。",
"autocomplete_fuzzy_label": "オートコンプリート時の入力ミス許容度",
"autocomplete_fuzzy_description": "ノートへのジャンプとノートの選択に影響します。処理速度は低下しますが、入力ミスを許容します。"
},
"text_editor": {
"title": "エディター"
},
"link": {
"failed_to_open": "'{{- href}}' のリンクを開けなせんでした: {{- message}}"
},
"print_preview": {
"title": "印刷プレビュー",
"close": "閉じる",
"save": "PDF として保存",
"orientation": "向き",
"portrait": "縦向き",
"landscape": "横向き",
"page_size": "ページサイズ",
"scale": "縮尺",
"margins": "余白",
"render_error": "現在の設定では PDF を生成できません。余白と縮尺を確認してください。",
"margins_default": "デフォルト",
"margins_none": "なし",
"margins_minimum": "最小",
"margins_custom": "カスタム",
"margin_top": "上",
"margin_right": "右",
"margin_bottom": "下",
"margin_left": "左",
"page_ranges": "ページ",
"page_ranges_hint": "全ページを印刷する場合は空欄のままにしてください。",
"page_ranges_invalid": "無効な形式です。例: 1-5, 8, 11-13 のように指定してください。",
"page_ranges_placeholder": "例: 1-5, 8, 11-13",
"print": "印刷",
"export_pdf": "PDF としてエクスポート",
"system_print": "システムダイアログを使用して印刷",
"destination": "出力先",
"destination_pdf": "PDF として保存",
"destination_printers": "プリンター",
"destination_default": "デフォルト"
},
"revisions": {
"note_revisions": "ノートの変更履歴",
"delete_all_revisions": "このノートのすべての変更履歴を削除",
"delete_all_button": "すべての変更履歴を削除",
"help_title": "ノートの変更履歴に関するヘルプ",
"confirm_delete_all": "このノートのすべての変更履歴を削除しますか?",
"no_revisions": "このノートにはまだ変更履歴がありません...",
"restore_button": "復元",
"diff_on": "差分を表示",
"diff_off": "内容を表示",
"diff_on_hint": "クリックしてノートのソース差分を表示",
"diff_off_hint": "クリックしてノートの内容を表示",
"diff_not_available": "差分は利用できません。",
"confirm_restore": "この変更履歴を復元しますか? 復元すると、ノートの現在のタイトルと内容がこの変更履歴で上書きされます。",
"delete_button": "削除",
"confirm_delete": "この変更履歴を削除しますか?",
"revisions_deleted": "ノートの変更履歴が削除されました。",
"revision_restored": "ノートの変更履歴が復元されました。",
"revision_deleted": "ノートの変更履歴が削除されました。",
"snapshot_interval": "ノートの変更履歴スナップショット間隔: {{seconds}} 秒。",
"maximum_revisions": "ノートの変更履歴スナップショット制限: {{number}}。",
"settings": "ノートの変更履歴設定",
"download_button": "ダウンロード",
"mime": "MIME: ",
"file_size": "ファイルサイズ:",
"preview_not_available": "このノートタイプではプレビューは利用できません。",
"highlight_changes": "変更箇所をハイライト",
"save_revision_now": "今すぐ変更履歴を保存",
"save_named_revision": "名前を付けた変更履歴を保存...",
"snapshot_header": "ノートの変更履歴スナップショット",
"snapshot_interval_value": "間隔: {{seconds}} 秒",
"snapshot_limit_value": "制限: {{number}}",
"menu_tooltip": "変更履歴オプション",
"save_revision": "変更履歴を保存",
"save_revision_tooltip": "現在のノートのスナップショットを手動で保存",
"description_placeholder": "この変更履歴に名前を付ける",
"revision_saved": "ノートの変更履歴が保存されました。",
"edit_description": "名前を編集",
"description_updated": "変更履歴名が更新されました。",
"source_auto": "自動保存",
"source_manual": "手動保存",
"source_etapi": "ETAPI",
"source_llm": "LLM",
"source_restore": "復元",
"source_unknown": "スナップショット",
"date_today": "今日",
"date_yesterday": "昨日",
"date_this_week": "今週",
"date_this_month": "今月",
"source_description_auto": "システムにより定期的に自動保存",
"source_description_manual": "ユーザーにより手動保存",
"source_description_etapi": "外部 Trilium API 経由で作成",
"source_description_llm": "AI アシスタントにより作成",
"source_description_restore": "以前の変更履歴を復元する前に保存しました",
"source_description_unknown": "ソースが利用できません"
},
"revisions_snapshot": {
"title": "ノートの変更履歴"
},
"launcher_button_context_menu": {
"remove_from_launch_bar": "ランチャーバーから削除"
},
"display_mode": {
"source": "ソースビュー",
"split": "分割ビュー",
"preview": "プレビュー"
},
"auto_link_attribute_list": {
"title": "システム属性"
},
"common": {
"save": "保存",
"cancel": "キャンセル"
}
}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Trilium Notes에 대해서",
"homepage": "홈페이지:",
"app_version": "앱 버전:",
"db_version": "DB 버전:",
"sync_version": "동기화 버전:",
"build_date": "빌드 날짜:",
"build_revision": "빌드 리비전:",
"data_directory": "데이터 경로:"
},
"toast": {

View File

@@ -1,13 +1,6 @@
{
"about": {
"title": "Om Trilium Notes",
"app_version": "App versjon:",
"db_version": "DB versjon:",
"sync_version": "Synk versjon:",
"build_date": "Byggdato:",
"build_revision": "Bygg versjon:",
"data_directory": "Datamappe:",
"homepage": "Hjemmeside:"
"data_directory": "Datamappe:"
},
"experimental_features": {
"new_layout_description": "Prøv det nye grensesnittet for et mer moderne utseende og forbedret brukervenlighet. Det må påregnes betydelige endringer i kommende versjoner."

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Over Trilium Notes",
"homepage": "Homepagina:",
"app_version": "App versie:",
"db_version": "DB Versie:",
"sync_version": "Sync Versie:",
"build_date": "Build datum:",
"build_revision": "Build revisie:",
"data_directory": "Gegevensmap:"
},
"toast": {

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "O Trilium Notes",
"homepage": "Strona domowa:",
"app_version": "Wersja aplikacji:",
"db_version": "Wersja bazy danych:",
"sync_version": "Wersja synchronizacji:",
"build_date": "Data kompilacji:",
"build_revision": "Rewizja:",
"data_directory": "Katalog danych:"
},
"toast": {
@@ -795,33 +788,6 @@
"undelete_link": "przywróć",
"confirm_undelete": "Czy chcesz przywrócić tę notatkę i jej pod-notatki?"
},
"revisions": {
"note_revisions": "Wersje notatki",
"delete_all_revisions": "Usuń wszystkie wersje tej notatki",
"delete_all_button": "Usuń wszystkie wersje",
"help_title": "Pomoc dotycząca wersji notatki",
"confirm_delete_all": "Czy chcesz usunąć wszystkie wersje tej notatki?",
"no_revisions": "Brak wersji dla tej notatki...",
"restore_button": "Przywróć",
"diff_on": "Pokaż różnice",
"diff_off": "Pokaż treść",
"diff_on_hint": "Kliknij, aby pokazać różnice w źródle notatki",
"diff_off_hint": "Kliknij, aby pokazać treść notatki",
"diff_not_available": "Różnice nie są dostępne.",
"confirm_restore": "Czy chcesz przywrócić tę wersję? Spowoduje to nadpisanie obecnego tytułu i treści notatki tą wersją.",
"delete_button": "Usuń",
"confirm_delete": "Czy chcesz usunąć tę wersję?",
"revisions_deleted": "Wersje notatki zostały usunięte.",
"revision_restored": "Wersja notatki została przywrócona.",
"revision_deleted": "Wersja notatki została usunięta.",
"snapshot_interval": "Interwał zrzutu wersji notatki: {{seconds}}s.",
"maximum_revisions": "Limit zrzutów wersji notatki: {{number}}.",
"settings": "Ustawienia wersji notatki",
"download_button": "Pobierz",
"mime": "MIME: ",
"file_size": "Rozmiar pliku:",
"preview_not_available": "Podgląd nie jest dostępny dla tego typu notatki."
},
"sort_child_notes": {
"sort_children_by": "Sortuj elementy podrzędne według...",
"sorting_criteria": "Kryteria sortowania",
@@ -1317,7 +1283,6 @@
},
"database_integrity_check": {
"title": "Sprawdzanie integralności bazy danych",
"description": "To sprawdzi, czy baza danych nie jest uszkodzona na poziomie SQLite. Może to zająć trochę czasu, w zależności od rozmiaru bazy danych.",
"check_button": "Sprawdź integralność bazy danych",
"checking_integrity": "Sprawdzanie integralności bazy danych...",
"integrity_check_succeeded": "Sprawdzanie integralności powiodło się - nie znaleziono problemów.",
@@ -1349,10 +1314,7 @@
"note_tree_font": "Czcionka drzewa notatek",
"note_detail_font": "Czcionka szczegółów notatki",
"monospace_font": "Czcionka o stałej szerokości (kod)",
"note_tree_and_detail_font_sizing": "Zauważ, że rozmiar czcionki drzewa i szczegółów jest względny do ustawienia rozmiaru głównej czcionki.",
"not_all_fonts_available": "Nie wszystkie wymienione czcionki mogą być dostępne w twoim systemie.",
"apply_font_changes": "Aby zastosować zmiany czcionek, kliknij na",
"reload_frontend": "przeładuj frontend",
"generic-fonts": "Czcionki ogólne",
"sans-serif-system-fonts": "Systemowe czcionki bezszeryfowe",
"serif-system-fonts": "Systemowe czcionki szeryfowe",
@@ -1442,7 +1404,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Limit czasu wymazywania załączników",
"attachment_auto_deletion_description": "Załączniki są automatycznie usuwane (i wymazywane), jeśli nie są już powiązane z ich notatką po określonym czasie.",
"erase_attachments_after": "Wymaż nieużywane załączniki po:",
"manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania zdefiniowanego powyżej limitu czasu):",
"erase_unused_attachments_now": "Wymaż nieużywane załączniki teraz",
@@ -1454,7 +1415,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Limit czasu wymazywania notatek",
"note_erasure_description": "Usunięte notatki (oraz atrybuty, wersje...) są początkowo tylko oznaczane jako usunięte i możliwe jest ich odzyskanie z okna Ostatnie notatki. Po pewnym czasie usunięte notatki są \"wymazywane\", co oznacza, że ich zawartość nie jest już możliwa do odzyskania. To ustawienie pozwala skonfigurować długość okresu między usunięciem a wymazaniem notatki.",
"erase_notes_after": "Wymaż notatki po:",
"manual_erasing_description": "Możesz również wywołać wymazywanie ręcznie (bez uwzględniania zdefiniowanego powyżej limitu czasu):",
"erase_deleted_notes_now": "Wymaż usunięte notatki teraz",
@@ -1544,7 +1504,6 @@
"first-week-contains-first-thursday": "Pierwszy tydzień zawiera pierwszy czwartek roku",
"first-week-has-minimum-days": "Pierwszy tydzień ma minimalną liczbę dni",
"min-days-in-first-week": "Minimalna liczba dni w pierwszym tygodniu",
"first-week-info": "Pierwszy tydzień zawiera pierwszy czwartek roku bazuje na standardzie <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Zmiana opcji pierwszego tygodnia może spowodować duplikację istniejących notatek tygodniowych, a istniejące notatki tygodniowe nie zostaną odpowiednio zaktualizowane.",
"formatting-locale": "Format daty i liczb",
"formatting-locale-auto": "Na podstawie języka aplikacji"
@@ -1669,9 +1628,6 @@
"server_address": "Adres instancji serwera",
"timeout": "Limit czasu synchronizacji",
"proxy_label": "Serwer proxy synchronizacji (opcjonalnie)",
"note": "Uwaga",
"note_description": "Jeśli pozostawisz ustawienie proxy puste, zostanie użyte proxy systemowe (dotyczy tylko wersji desktop/electron).",
"special_value_description": "Inną wartością specjalną jest <code>noproxy</code>, która wymusza ignorowanie nawet proxy systemowego i respektuje <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Zapisz",
"help": "Pomoc",
"test_title": "Test synchronizacji",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Sobre o Trilium Notes",
"app_version": "Versão da App:",
"homepage": "Página inicial:",
"db_version": "Versão da base de dados:",
"sync_version": "Versão de sincronização:",
"build_date": "Data de compilação:",
"build_revision": "Revisão da compilação:",
"data_directory": "Diretório de dados:"
},
"toast": {
@@ -267,33 +260,6 @@
"undelete_link": "Restaurar",
"confirm_undelete": "Deseja restaurar esta nota e as suas subnotas?"
},
"revisions": {
"note_revisions": "Versões da nota",
"delete_all_revisions": "Apagar todas as versões desta nota",
"delete_all_button": "Apagar todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"confirm_delete_all": "Quer apagar todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",
"confirm_restore": "Deseja restaurar esta versão? Isto irá substituir o título e o conteúdo atuais da nota por esta versão.",
"delete_button": "Apagar",
"confirm_delete": "Deseja apagar esta versão?",
"revisions_deleted": "As versões da nota foram removidas.",
"revision_restored": "A versão da nota foi restaurada.",
"revision_deleted": "A versão da nota foi apagada.",
"snapshot_interval": "Intervalo de captura das versões da nota: {{seconds}}s.",
"maximum_revisions": "Limite de capturas das versões da nota: {{number}}.",
"settings": "Configurações de versões da nota",
"download_button": "Descarregar",
"mime": "MIME: ",
"file_size": "Tamanho do ficheiro:",
"preview_not_available": "A visualização não está disponível para este tipo de nota.",
"diff_on": "Mostrar diferenças",
"diff_off": "Mostrar conteúdos",
"diff_on_hint": "Carregar para mostrar diferenças da fonte da nota",
"diff_off_hint": "Carregar para mostrar conteúdos da nota",
"diff_not_available": "Diferenças não disponível."
},
"sort_child_notes": {
"sort_children_by": "Ordenar notas filhas por...",
"sorting_criteria": "Critérios de ordenação",
@@ -1088,7 +1054,6 @@
},
"database_integrity_check": {
"title": "Verificação de Integridade da Base de Dados",
"description": "Isto verificará se a base de dados não está corrompida no nível SQLite. Pode levar algum tempo, dependendo do tamanho da base de dados.",
"check_button": "Verificar integridade da base de dados",
"checking_integrity": "A verificar integridade da base de dados…",
"integrity_check_succeeded": "Verificação de integridade bem sucedida - nenhum problema encontrado.",
@@ -1120,10 +1085,7 @@
"note_tree_font": "Fonte da Árvore de Notas",
"note_detail_font": "Fonte Padrão da Nota",
"monospace_font": "Fonte Monospace (código)",
"note_tree_and_detail_font_sizing": "Note que o tamanho da fonte da árvore e dos pormenores é relativo à configuração principal do tamanho de fonte.",
"not_all_fonts_available": "Nem todas as fontes listadas podem estar disponíveis no seu sistema.",
"apply_font_changes": "Para aplicar as alterações de fonte, clique em",
"reload_frontend": "recarregar frontend",
"generic-fonts": "Fontes genéricas",
"sans-serif-system-fonts": "Fontes sem serifa de sistema",
"serif-system-fonts": "Fontes serifadas de sistema",
@@ -1213,7 +1175,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Tempo Limite para Apagar um Anexo",
"attachment_auto_deletion_description": "Os anexos são automaticamente apagados (e apagados) se já não forem referenciados pela sua nota após um tempo definido.",
"erase_attachments_after": "Apagar anexos não utilizados após:",
"manual_erasing_description": "Também pode ativar a apagar manualmente (sem considerar o timeout definido acima):",
"erase_unused_attachments_now": "Apagar anexos não utilizados agora",
@@ -1225,7 +1186,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Tempo Limite para Apagar uma Nota",
"note_erasure_description": "Notas apagadas (e atributos, revisões...) inicialmente são apenas marcadas como apagadas e é possível recuperá-las a partir do diálogo de Notas Recentes. Depois de um tempo, as notas apagadas são \"apagadas\", o que significa que o seu conteúdo já não é recuperável. Esta configuração permite configurar o período entre apagar e apagar a nota.",
"erase_notes_after": "Apagar notas após:",
"manual_erasing_description": "Também pode ativar a apagar manualmente (sem considerar o timeout definido acima):",
"erase_deleted_notes_now": "Apagar as notas apagadas agora",
@@ -1310,7 +1270,6 @@
"first-week-contains-first-thursday": "Primeira semana que contenha a primeira quinta-feira do ano",
"first-week-has-minimum-days": "Primeira semana que contenha um mínimo de dias",
"min-days-in-first-week": "Mínimo de dias da primeira semana",
"first-week-info": "Primeira semana que contenha a primeira Quinta-feira do ano é baseado na <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Alterar as opções de primeira semana pode causar duplicidade nas Notas Semanais existentes e estas Notas não serão atualizadas de acordo.",
"formatting-locale": "Formato de data e número",
"tuesday": "Terça-feira",
@@ -1439,9 +1398,6 @@
"server_address": "Endereço da instância do Servidor",
"timeout": "Tempo limite da sincronização",
"proxy_label": "Servidor proxy para sincronização (opcional)",
"note": "Nota",
"note_description": "Se deixar a configuração de proxy em branco, o proxy do sistema será usado (aplica-se apenas à versão desktop/Electron).",
"special_value_description": "Outro valor especial é <code>noproxy</code>, que força a ignorar até mesmo o proxy do sistema e respeita <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Gravar",
"help": "Ajuda",
"test_title": "Teste de Sincronização",

View File

@@ -7,13 +7,6 @@
"copy_title": "Copiar para a área de transferência"
},
"about": {
"title": "Sobre o Trilium Notes",
"homepage": "Página inicial:",
"app_version": "Versão do App:",
"db_version": "Versão do banco de dados:",
"sync_version": "Versão de sincronização:",
"build_date": "Data de compilação:",
"build_revision": "Revisão da compilação:",
"data_directory": "Diretório de dados:"
},
"toast": {
@@ -273,33 +266,6 @@
"undelete_link": "Restaurar",
"confirm_undelete": "Você deseja restaurar esta nota e suas subnotas?"
},
"revisions": {
"note_revisions": "Versões da nota",
"delete_all_revisions": "Excluir todas as versões desta nota",
"delete_all_button": "Excluir todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"confirm_delete_all": "Você quer excluir todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",
"confirm_restore": "Deseja restaurar esta versão? Isso irá substituir o título e o conteúdo atuais da nota por esta versão.",
"delete_button": "Excluir",
"confirm_delete": "Deseja excluir esta versão?",
"revisions_deleted": "As versões da nota foram removidas.",
"revision_restored": "A versão da nota foi restaurada.",
"revision_deleted": "A versão da nota foi excluída.",
"snapshot_interval": "Intervalo de captura das versões da nota: {{seconds}}s.",
"maximum_revisions": "Limite de capturas das versões da nota: {{number}}.",
"settings": "Configurações de versões da nota",
"download_button": "Download",
"mime": "MIME: ",
"file_size": "Tamanho do arquivo:",
"preview_not_available": "A visualização não está disponível para este tipo de nota.",
"diff_on": "Exibir diferença",
"diff_off": "Exibir conteúdo",
"diff_on_hint": "Clique para exibir a diferença de fonte da nota",
"diff_off_hint": "Clique para exibir o conteúdo da nota",
"diff_not_available": "A diferença não está disponível."
},
"sort_child_notes": {
"sort_children_by": "Ordenar notas filhas por...",
"sorting_criteria": "Critérios de ordenação",
@@ -1138,8 +1104,7 @@
"checking_integrity": "Verificando integridade do banco de dados…",
"integrity_check_succeeded": "Verificação de integridade bem sucedida - nenhum problema encontrado.",
"integrity_check_failed": "Verificação de integridade falhou: {{results}}",
"title": "Verificação de Integridade do Banco de Dados",
"description": "Isso verificará se o banco de dados não está corrompido no nível SQLite. Pode levar algum tempo, dependendo do tamanho do banco de dados."
"title": "Verificação de Integridade do Banco de Dados"
},
"sync": {
"title": "Sincronizar",
@@ -1168,8 +1133,6 @@
"note_detail_font": "Fonte Padrão da Nota",
"monospace_font": "Fonte Monospace (código)",
"not_all_fonts_available": "Nem todas as fontes listadas podem estar disponíveis em seu sistema.",
"apply_font_changes": "Para aplicar as alterações de fonte, clique em",
"reload_frontend": "recarregar frontend",
"generic-fonts": "Fontes genéricas",
"sans-serif-system-fonts": "Fontes sem serifa de sistema",
"serif-system-fonts": "Fontes serifadas de sistema",
@@ -1178,8 +1141,7 @@
"serif": "Serifa",
"sans-serif": "Sem Serifa",
"monospace": "Monoespaçado",
"system-default": "Padrão do Sistema",
"note_tree_and_detail_font_sizing": "Note que o tamanho da fonte da árvore e dos detalhes é relativo à configuração principal do tamanho de fonte."
"system-default": "Padrão do Sistema"
},
"max_content_width": {
"title": "Largura do Conteúdo",
@@ -1289,7 +1251,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Tempo Limite para Exclusão de um Anexo",
"attachment_auto_deletion_description": "Os anexos são automaticamente excluídos (e apagados) se não forem mais referenciados por sua nota após um tempo definido.",
"erase_attachments_after": "Apagar anexos não utilizados após:",
"manual_erasing_description": "Você também pode ativar a exclusão manualmente (sem considerar o timeout definido acima):",
"erase_unused_attachments_now": "Apagar anexos não utilizados agora",
@@ -1301,7 +1262,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Tempo Limite para Exclusão de uma Nota",
"note_erasure_description": "Notas excluídas (e atributos, revisões...) inicialmente são apenas marcadas como excluídas e é possível recuperá-las a partir do diálogo de Notas Recentes. Depois de um tempo, as notas excluídas são \"apagadas\", o que significa que seu conteúdo não é mais recuperável. Esta configuração permite configurar o período entre excluir e apagar a nota.",
"erase_notes_after": "Apagar notas após:",
"manual_erasing_description": "Você também pode ativar a exclusão manualmente (sem considerar o timeout definido acima):",
"erase_deleted_notes_now": "Apague as notas excluídas agora",
@@ -1386,7 +1346,6 @@
"first-week-contains-first-thursday": "Primeira semana que contenha a primeira quinta-feira do ano",
"first-week-has-minimum-days": "Primeira semana contendo um mínimo de dias",
"min-days-in-first-week": "Mínimo de dias da primeira semana",
"first-week-info": "Primeira semana que contenha a primeira Quinta-feira do ano é baseado na <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Alterar as opções de primeira semana pode causar duplicidade nas Notas Semanais existentes e estas Notas não serão atualizadas de acordo.",
"formatting-locale": "Formato de data e número",
"tuesday": "Terça-feira",
@@ -1948,9 +1907,6 @@
"server_address": "Endereço da instância do Servidor",
"timeout": "Tempo limite da sincronização",
"proxy_label": "Servidor proxy para sincronização (opcional)",
"note": "Nota",
"note_description": "Se você deixar a configuração de proxy em branco, o proxy do sistema será usado (aplica-se apenas à versão desktop/Electron).",
"special_value_description": "Outro valor especial é <code>noproxy</code>, que força a ignorar até mesmo o proxy do sistema e respeita <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Salvar",
"help": "Ajuda",
"test_title": "Teste de Sincronização",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Despre Trilium Notes",
"homepage": "Site web:",
"app_version": "Versiune aplicație:",
"db_version": "Versiune bază de date:",
"sync_version": "Versiune sincronizare:",
"build_date": "Data compilării:",
"build_revision": "Revizia compilării:",
"data_directory": "Directorul de date:"
},
"abstract_bulk_action": {
@@ -74,7 +67,6 @@
"will_be_deleted_soon": "Acest atașament va fi șters automat în curând"
},
"attachment_erasure_timeout": {
"attachment_auto_deletion_description": "Atașamentele se șterg automat (permanent) dacă nu sunt referențiate de către notița lor părinte după un timp prestabilit de timp.",
"attachment_erasure_timeout": "Perioadă de ștergere a atașamentelor",
"erase_attachments_after": "Șterge atașamentele neutilizate după:",
"erase_unused_attachments_now": "Elimină atașamentele șterse acum",
@@ -433,7 +425,6 @@
"database_integrity_check": {
"check_button": "Verifică integritatea bazei de date",
"checking_integrity": "Se verifică integritatea bazei de date...",
"description": "Se va verifica să nu existe coruperi ale bazei de date la nivelul SQLite. Poate dura ceva timp, în funcție de dimensiunea bazei de date.",
"integrity_check_failed": "Probleme la verificarea integrității: {{results}}",
"integrity_check_succeeded": "Verificarea integrității a fost făcută cu succes și nu a fost identificată nicio problemă.",
"title": "Verificarea integrității bazei de date"
@@ -575,16 +566,13 @@
"upload_success": "Noua revizie a fișierului a fost încărcată cu succes."
},
"fonts": {
"apply_font_changes": "Pentru a aplica schimbările de font, click pe",
"font_family": "Familia de fonturi",
"fonts": "Fonturi",
"main_font": "Fontul principal",
"monospace_font": "Fontul monospace (pentru cod)",
"not_all_fonts_available": "Nu toate fonturile listate aici pot fi disponibile pe acest sistem.",
"note_detail_font": "Fontul pentru detaliile notițelor",
"note_tree_and_detail_font_sizing": "Dimensiunea arborelui și a fontului pentru detalii este relativă la dimensiunea fontului principal.",
"note_tree_font": "Fontul arborelui de notițe",
"reload_frontend": "reîncarcă interfața",
"size": "Mărime",
"theme_defined": "Definit de temă",
"generic-fonts": "Fonturi generice",
@@ -715,7 +703,6 @@
"first-week-contains-first-thursday": "Prima săptămână conține prima zi de joi din an",
"first-week-has-minimum-days": "Prima săptămână are numărul minim de zile",
"min-days-in-first-week": "Numărul minim de zile pentru prima săptămână",
"first-week-info": "Opțiunea de prima săptămână conține prima zi de joi din an este bazată pe standardul <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Schimbarea opțiunii primei săptămâni poate cauza duplicate cu notițele săptămânale existente deoarece acestea nu vor fi actualizate retroactiv.",
"tuesday": "Marți",
"wednesday": "Miercuri",
@@ -890,7 +877,6 @@
"erase_deleted_notes_now": "Elimină notițele șterse acum",
"erase_notes_after": "Elimină notițele șterse după:",
"manual_erasing_description": "Se poate rula o eliminare manuală (fără a lua în considerare timpul definit mai sus):",
"note_erasure_description": "Notițele șterse (precum și atributele, reviziile) sunt prima oară doar marcate drept șterse și este posibil să fie recuperate din ecranul Notițe recente. După o perioadă de timp, notițele șterse vor fi „eliminate”, caz în care conținutul lor nu se poate recupera. Această setare permite configurarea duratei de timp dintre ștergerea și eliminarea notițelor.",
"note_erasure_timeout_title": "Timpul de eliminare automată a notițelor șterse"
},
"note_info_widget": {
@@ -1090,33 +1076,6 @@
"rename_relation_from": "Redenumește relația din",
"to": "În"
},
"revisions": {
"confirm_delete": "Doriți ștergerea acestei revizii?",
"confirm_delete_all": "Doriți ștergerea tuturor reviziilor acestei notițe?",
"confirm_restore": "Doriți restaurarea acestei revizii? Acest lucru va suprascrie titlul și conținutul curent cu cele ale acestei revizii.",
"delete_all_button": "Șterge toate reviziile",
"delete_all_revisions": "Șterge toate reviziile acestei notițe",
"delete_button": "Şterge",
"download_button": "Descarcă",
"file_size": "Dimensiune fișier:",
"help_title": "Informații despre reviziile notițelor",
"mime": "MIME: ",
"no_revisions": "Nu există încă nicio revizie pentru această notiță...",
"note_revisions": "Revizii ale notiței",
"preview_not_available": "Nu este disponibilă o previzualizare pentru acest tip de notiță.",
"restore_button": "Restaurează",
"revision_deleted": "Revizia notiței a fost ștearsă.",
"revision_restored": "Revizia notiței a fost restaurată.",
"revisions_deleted": "Notița reviziei a fost ștearsă.",
"maximum_revisions": "Numărul maxim de revizii pentru notița curentă: {{number}}.",
"settings": "Setări revizii ale notițelor",
"snapshot_interval": "Intervalul de creare a reviziilor pentru notițe: {{seconds}}s.",
"diff_on": "Evidențiază diferențele",
"diff_off": "Afișează conținutul",
"diff_on_hint": "Clic pentru a afișa diferențele față de revizia anterioară, la nivel de cod sursă",
"diff_off_hint": "Clic pentru a afișa întregul conținut al reviziei",
"diff_not_available": "Diferențele nu pot fi evidențiate."
},
"revisions_button": {
"note_revisions": "Revizii ale notiței"
},
@@ -1254,12 +1213,9 @@
"config_title": "Configurația sincronizării",
"handshake_failed": "Comunicarea cu serverul de sincronizare a eșuat, eroare: {{message}}",
"help": "Informații",
"note": "Notiță",
"note_description": "Dacă lăsați câmpul de proxy necompletat, proxy-ul de sistem va fi utilizat (se aplică doar pentru aplicația desktop).",
"proxy_label": "Server-ul proxy utilizat pentru sincronizare (opțional)",
"save": "Salvează",
"server_address": "Adresa instanței de server",
"special_value_description": "O altă valoare specială este <code>noproxy</code> ce ignoră proxy-ul de sistem și respectă <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"test_button": "Probează sincronizarea",
"test_description": "Această opțiune va testa conexiunea și comunicarea cu serverul de sincronizare. Dacă serverul de sincronizare nu este inițializat, acest lucru va rula și o sincronizare cu documentul local.",
"test_title": "Probează sincronizarea",

View File

@@ -1,13 +1,6 @@
{
"about": {
"app_version": "Версия приложения:",
"db_version": "Версия базы данных:",
"sync_version": "Версия синхронизации:",
"build_date": "Дата сборки:",
"build_revision": "Номер сборки:",
"data_directory": "Каталог с данными:",
"title": "О Trilium Notes",
"homepage": "Домашняя страница:"
"data_directory": "Каталог с данными:"
},
"toast": {
"critical-error": {
@@ -77,18 +70,28 @@
},
"delete_notes": {
"close": "Закрыть",
"erase_notes_description": "Обычное (мягкое) удаление только отмечает заметки как удалённые, и их можно восстановить (в диалоговом окне последних изменений) в течение определённого времени. Если выбрать этот параметр, заметки будут удалены немедленно, и восстановить их будет невозможно.",
"erase_notes_description": "Стереть заметки немедленно вместо мягкого удаления. Это действие необратимо и вызовет перезагрузку приложения.",
"delete_all_clones_description": "Удалить также все клоны (можно отменить в последних изменениях)",
"erase_notes_warning": "Удалить заметки без возможности восстановления, включая все клоны. Это приведёт к принудительной перезагрузке приложения.",
"notes_to_be_deleted": "Следующие заметки будут удалены ({{notesCount}})",
"notes_to_be_deleted": "Заметки, подлежащие удалению ({{notesCount}})",
"no_note_to_delete": "Заметка не будет удалена (только клоны).",
"broken_relations_to_be_deleted": "Следующие отношения будут разорваны и удалены ({{relationCount}})",
"cancel": "Отмена"
"broken_relations_to_be_deleted": "Разорванные отношения ({{relationCount}})",
"cancel": "Отмена",
"title": "Удалить заметки",
"clones_label": "Клоны",
"delete_clones_description_one": "Также удалить {{count}} другой клон. Можно отменить в последних изменениях.",
"delete_clones_description_few": "Также удалить {{count}} других клона. Можно отменить в последних изменениях.",
"delete_clones_description_many": "Также удалить {{count}} других клонов. Можно отменить в последних изменениях.",
"erase_notes_label": "Стереть навсегда",
"table_note_with_relation": "Заметка с отношением",
"table_relation": "Отношение",
"table_points_to": "Указывает на (удалено)",
"delete": "Удалить"
},
"database_anonymization": {
"light_anonymization_description": "Это действие создаст новую копию базы данных и выполнит её лёгкую анонимизацию — в частности, будет удалён только контент всех заметок, но заголовки и атрибуты останутся. Кроме того, будут сохранены пользовательские заметки, содержащие JavaScript-скрипты frontend/backend и пользовательские виджеты. Это даёт больше контекста для отладки проблем.",
"light_anonymization_description": "Создает копию с удалением содержимого заметок, но заголовками, атрибутами и пользовательскими скриптами/виджетами. Даёт больше контекста для отладки.",
"choose_anonymization": "Вы можете самостоятельно решить, хотите ли вы предоставить полностью или частично анонимизированную базу данных. Даже полностью анонимизированная база данных очень полезна, однако в некоторых случаях частично анонимизированная база данных может ускорить процесс выявления и исправления ошибок.",
"full_anonymization_description": "Это действие создаст новую копию базы данных и анонимизирует ее (удалит все содержимое заметок и оставит только структуру и некоторые неконфиденциальные метаданные) для совместного использования в Интернете в целях отладки без опасения утечки ваших личных данных.",
"full_anonymization_description": "Создает копию базы данных с удалением всего содержимого заметок, оставляя только структуру и неконфиденциальные метаданные. Безопасно для обмена в сети при отладке проблем.",
"title": "Анонимизация базы данных",
"full_anonymization": "Полная анонимизация",
"light_anonymization": "Легкая анонимизация",
@@ -136,20 +139,23 @@
"title": "Языки контента"
},
"theme": {
"theme_label": "Тема",
"theme_label": "Тема приложения",
"override_theme_fonts_label": "Переопределить шрифты темы",
"triliumnext": "Trilium (следует системной цветовой схеме)",
"triliumnext-light": "Trilium (Светлая)",
"triliumnext-dark": "Trilium (Темная)",
"title": "Тема приложения",
"triliumnext": "Использовать цветовую схему системы",
"triliumnext-light": "Светлая",
"triliumnext-dark": "Тёмная",
"title": "Пользовательский интерфейс",
"layout": "Макет",
"layout-vertical-title": "Вертикальный",
"layout-horizontal-title": "Горизонтальный",
"auto_theme": "Legacy (следует системной цветовой схеме)",
"light_theme": "Legacy (светлая)",
"dark_theme": "Legacy (темная)",
"auto_theme": "Использовать цветовую схему системы",
"light_theme": "Светлая",
"dark_theme": "Тёмная",
"layout-horizontal-description": "панель запуска находится под панелью вкладок, панель вкладок теперь занимает всю ширину.",
"layout-vertical-description": "панель запуска находится слева (по умолчанию)"
"layout-vertical-description": "панель запуска находится слева (по умолчанию)",
"modern_themes": "Современные",
"legacy_themes": "Устаревшие",
"custom_themes": "Пользовательские"
},
"tasks": {
"due": {
@@ -369,33 +375,6 @@
"deleted_notes_message": "Удаленные заметки были стерты окончательно.",
"confirm_undelete": "Вы хотите восстановить эту заметку и ее подзаметки?"
},
"revisions": {
"restore_button": "Восстановить",
"delete_button": "Удалить",
"note_revisions": "Версии заметки",
"delete_all_revisions": "Удалить все версии этой заметки",
"delete_all_button": "Удалить все версии",
"help_title": "Помощь по версиям заметок",
"confirm_delete_all": "Вы хотите удалить все версии этой заметки?",
"confirm_restore": "Хотите восстановить эту версию? Текущее название и содержание заметки будут перезаписаны этой версией.",
"confirm_delete": "Вы хотите удалить эту версию?",
"revisions_deleted": "Версии заметки были удалены.",
"revision_restored": "Версия заметки была восстановлена.",
"revision_deleted": "Версия заметки была удалена.",
"download_button": "Скачать",
"file_size": "Размер файла:",
"preview_not_available": "Предпосмотр недоступен для заметки этого типа.",
"mime": "MIME: ",
"settings": "Настройка версионирования заметок",
"no_revisions": "У этой заметки еще нет версий...",
"snapshot_interval": "Интервал создания версии заметки: {{seconds}} с.",
"maximum_revisions": "Максимальное количество версий заметки: {{number}}.",
"diff_on": "Сравнить",
"diff_off": "Показать содержимое",
"diff_on_hint": "Отобразить сравнение исходного кода заметки",
"diff_off_hint": "Отобразить контент заметки",
"diff_not_available": "Сравнение недоступно."
},
"sort_child_notes": {
"sort_children_by": "Сортировать дочерние заметки по...",
"sorting_criteria": "Критерии сортировки",
@@ -1065,7 +1044,10 @@
"expand_nth_level": "Развернуть уровни: {{depth}} шт.",
"expand_first_level": "Развернуть прямые дочерние уровни",
"expand_tooltip": "Разщвернуть дочерние элементы этой коллекции (на один уровень вложенности). Для получения дополнительных параметров нажмите стрелку справа.",
"hide_child_notes": "Скрыть дочерние заметки в дереве"
"hide_child_notes": "Скрыть дочерние заметки в дереве",
"open_all_in_tabs": "Открыть все",
"open_all_in_tabs_tooltip": "Открыть все результаты в новых вкладках",
"open_all_confirm": "Это откроет заметки ({{count}}) в новых вкладках. Продолжить?"
},
"edited_notes": {
"deleted": "(удалено)",
@@ -1236,23 +1218,24 @@
"size": "Размер",
"serif": "С засечками",
"monospace": "Моноширинный",
"main_font": "Основной шрифт",
"main_font": "Текст интерфейса",
"font_family": "Семейство шрифтов",
"reload_frontend": "перезагрузить интерфейс",
"sans-serif": "Без засечек",
"system-default": "Системный по умолчанию",
"theme_defined": "Определяется темой",
"generic-fonts": "Стандартные шрифты",
"note_tree_font": "Шрифт дерева заметок",
"note_detail_font": "Шрифт заметки",
"monospace_font": "Моноширинный шрифт (для кода)",
"note_tree_font": "Текст дерева заметок",
"note_detail_font": "Текст документа",
"monospace_font": "Моноширинный текст",
"sans-serif-system-fonts": "Системные шрифты без засечек",
"serif-system-fonts": "Системные шрифты с засечками",
"monospace-system-fonts": "Моноширинные системные шрифты",
"handwriting-system-fonts": "Шрифты системы рукописного ввода",
"note_tree_and_detail_font_sizing": "Обратите внимание, что размер шрифта дерева и детальной страницы зависит от настройки размера основного шрифта.",
"apply_font_changes": "Чтобы применить изменения шрифта, нажмите",
"not_all_fonts_available": "Не все перечисленные шрифты могут быть доступны в вашей системе."
"not_all_fonts_available": "Не все перечисленные шрифты могут быть доступны в вашей системе",
"preview": "Предпросмотр",
"monospace_font_description": "Используется для заметок кода и блоков кода",
"size_relative_to_general": "Размер относительно общего размера шрифта",
"apply_changes": "Перезагрузить, чтобы применить изменения"
},
"max_content_width": {
"max_width_unit": "пикселей",
@@ -1272,11 +1255,14 @@
"images": {
"images_section_title": "Изображения",
"max_image_dimensions_unit": "пикселей",
"download_images_automatically": "Автоматическая загрузка изображений для использования в автономном режиме.",
"download_images_description": "Вставленный HTML-код может содержать ссылки на онлайн-изображения. Trilium найдет эти ссылки и загрузит изображения, чтобы они были доступны офлайн.",
"enable_image_compression": "Включить сжатие изображений",
"max_image_dimensions": "Максимальная ширина/высота изображения (размер изображения будет изменен, если он превысит этот параметр).",
"jpeg_quality_description": "Качество JPEG (10 — худшее качество, 100 — наилучшее качество, рекомендуется 50 — 85)"
"download_images_automatically": "Автоматическая загрузка изображений",
"download_images_description": "Скачивать изображения указанные в вставленном HTML-коде, чтобы они были доступны офлайн.",
"enable_image_compression": "Сжатие изображений",
"max_image_dimensions": "Максимальные размеры изображения",
"jpeg_quality_description": "Рекомендуемый диапазон - 5085. Более низкие значения уменьшают размер файла, более высокие - сохраняют детализацию.",
"enable_image_compression_description": "Сжимать и изменять размер изображений при их загрузке или вставке.",
"max_image_dimensions_description": "Размер изображений, превышающих этот размер, будет изменен автоматически.",
"jpeg_quality": "Качество JPEG"
},
"search_engine": {
"bing": "Bing",
@@ -1322,7 +1308,6 @@
"first-week-contains-first-thursday": "Первая неделя содержит первый четверг года",
"first-week-has-minimum-days": "Первая неделя имеет минимальное количество дней",
"min-days-in-first-week": "Минимальное количество дней в первой неделе",
"first-week-info": "Первая неделя содержит первый четверг года в соответствии со стандартом <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Изменение параметров первой недели может привести к дублированию существующих недельных заметок, и существующие недельные заметки не будут обновлены соответствующим образом.",
"formatting-locale": "Формат даты и числа",
"formatting-locale-auto": "Выбирать на основе языка приложения",
@@ -1416,14 +1401,11 @@
"no_results": "Не найдено ярлыков, соответствующих '{{filter}}'"
},
"sync_2": {
"note": "Заметка",
"save": "Сохранить",
"help": "Помощь",
"config_title": "Настройка синхронизации",
"server_address": "Адрес экземпляра сервера",
"proxy_label": "Прокси-сервер (необязательно)",
"note_description": "Если оставить настройки прокси-сервера пустыми, будет использоваться системный прокси-сервер (применимо только к сборкам Desktop/Electron).",
"special_value_description": "Еще одно специальное значение - <code>noproxy</code>, которое заставляет игнорировать даже системный прокси и учитывает <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"timeout": "Тайм-аут синхронизации",
"test_description": "Это проверит подключение и подтверждение связи с сервером синхронизации. Если сервер синхронизации не инициализирован, он будет настроен на синхронизацию с локальным документом.",
"test_title": "Тест синхронизации",
@@ -1574,7 +1556,7 @@
"unit": "символов",
"title": "Автоматическое переключение в режим \"только для чтения\"",
"description": "Максимальный размер заметки до переключения в режим только для чтения — это размер, после которого заметки будут отображаться в режиме «только для чтения» (из соображений производительности).",
"label": "Максимальный размер заметки до переключения в режим только для чтения (заметки с кодом)"
"label": "Максимальный размер заметки до переключения в режим только для чтения"
},
"inherited_attribute_list": {
"title": "Унаследованные атрибуты",
@@ -1632,14 +1614,16 @@
"note_already_in_diagram": "Заметка \"{{title}}\" уже есть на диаграмме.",
"connection_exists": "Связь '{{name}}' между этими заметками уже существует.",
"specify_new_relation_name": "Укажите новое имя связи (допустимые символы: буквы, цифры, двоеточие и подчеркивание):",
"start_dragging_relations": "Начните перетягивать отношения отсюда на другую заметку."
"start_dragging_relations": "Начните перетягивать отношения отсюда на другую заметку.",
"rename_relation": "Переименовать отношение"
},
"vacuum_database": {
"title": "Уменьшение размера файла базы данных",
"description": "Это приведет к перестройке базы данных, что, скорее всего, уменьшит размер её файла. Данные не будут изменены.",
"button_text": "Уменьшить размер файла базы данных",
"vacuuming_database": "Уменьшение размера файла базы данных...",
"database_vacuumed": "База данных была перестроена"
"database_vacuumed": "База данных была перестроена",
"vacuum_label": "Уменьшить размер файла базы данных"
},
"vim_key_bindings": {
"use_vim_keybindings_in_code_notes": "Сочетания клавиш Vim",
@@ -1757,17 +1741,18 @@
},
"database_integrity_check": {
"title": "Проверка целостности базы данных",
"description": "Это позволит проверить базу данных на предмет повреждений на уровне SQLite. Это может занять некоторое время в зависимости от размера базы данных.",
"check_button": "Проверить целостность базы данных",
"checking_integrity": "Проверка целостности базы данных...",
"integrity_check_succeeded": "Проверка целостности прошла успешно - проблем не обнаружено.",
"integrity_check_failed": "Проверка целостности завершена с ошибками: {{results}}"
"integrity_check_failed": "Проверка целостности завершена с ошибками: {{results}}",
"check_integrity_label": "Проверить целостность базы данных"
},
"consistency_checks": {
"find_and_fix_button": "Найти и устранить проблемы целостности",
"finding_and_fixing_message": "Поиск и устранение проблем целостности...",
"title": "Проверки целостности",
"issues_fixed_message": "Все обнаруженные проблемы с согласованностью теперь устранены."
"issues_fixed_message": "Все обнаруженные проблемы с согласованностью теперь устранены.",
"find_and_fix_label": "Найти и устранить проблемы целостности"
},
"call_to_action": {
"next_theme_message": "В настоящее время вы используете старую тему оформления. Хотите попробовать новую тему?",
@@ -1815,7 +1800,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Срок окончательного удаления заметок",
"note_erasure_description": "Удалённые заметки (и атрибуты, версии и т.д.) сначала помечаются как удалённые, и их можно восстановить из диалогового окна «Недавние заметки». По истечении определённого времени удалённые заметки «стираются», то есть их содержимое больше не подлежит восстановлению. Этот параметр позволяет настроить длительность периода между пометкой на удаление и окончательным удалением заметки.",
"erase_notes_after": "Стереть заметки после:",
"manual_erasing_description": "Вы также можете запустить стирание вручную (без учета срока, определенного выше):",
"erase_deleted_notes_now": "Окончательно удалить заметки, помеченные к удалению сейчас",
@@ -1823,7 +1807,6 @@
},
"attachment_erasure_timeout": {
"erase_unused_attachments_now": "Удалить неиспользуемые вложения прямо сейчас",
"attachment_auto_deletion_description": "Вложения автоматически удаляются, если в заметке на них больше не ссылаются по истечении определенного времени.",
"attachment_erasure_timeout": "Тайм-аут удаления вложения",
"erase_attachments_after": "Удалять неиспользуемые вложения через:",
"unused_attachments_erased": "Неиспользуемые вложения были удалены.",
@@ -2006,11 +1989,11 @@
},
"ui-performance": {
"title": "Производительность",
"enable-motion": "Включить визуальные эффекты и анимации",
"enable-shadows": "Включить тени",
"enable-backdrop-effects": "Включить эффекты размытия фона меню, всплывающих окон и панелей",
"enable-smooth-scroll": "Включить плавную прокрутку",
"app-restart-required": "(для вступления изменений в силу требуется перезапуск приложения)"
"enable-motion": "Визуальные эффекты и анимации",
"enable-shadows": "Тени",
"enable-backdrop-effects": "Эффекты размытия фона меню, всплывающих окон и панелей",
"enable-smooth-scroll": "Плавная прокрутку",
"app-restart-required": "Требуется перезапуск приложения"
},
"collections": {
"rendering_error": "Невозможно отобразить содержимое из-за ошибки."
@@ -2311,6 +2294,15 @@
"delete_provider_confirmation": "Вы уверены, что желаете удалить провайдера \"{{name}}\"?",
"api_key": "Ключ API",
"api_key_placeholder": "Введите ваш ключ API",
"cancel": "Отмена"
"cancel": "Отмена",
"tools": {
"clone_note": "Клонировать заметку",
"move_note": "Переместить заметку",
"delete_note": "Удалить заметку",
"rename_note": "Переименовать заметку"
}
},
"database": {
"title": "База данных"
}
}

View File

@@ -1,9 +1 @@
{
"about": {
"title": "Podrobnosti Trilium Notes",
"homepage": "Domača stran:",
"app_version": "Verzija aplikacije:",
"db_version": "Verzija DB:",
"sync_version": "Verzija Sync:"
}
}
{}

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "O Trilium Belеškama",
"homepage": "Početna stranica:",
"app_version": "Verzija aplikacije:",
"db_version": "Verzija baze podataka:",
"sync_version": "Verzija sinhronizacije:",
"build_date": "Datum izgradnje:",
"build_revision": "Revizija izgradnje:",
"data_directory": "Direktorijum sa podacima:"
},
"toast": {
@@ -248,28 +241,6 @@
"undelete_link": "poništi brisanje",
"confirm_undelete": "Da li želite da poništite brisanje ove beleške i njenih podbeleški?"
},
"revisions": {
"note_revisions": "Revizije beleški",
"delete_all_revisions": "Obriši sve revizije ove beleške",
"delete_all_button": "Obriši sve revizije",
"help_title": "Pomoć za Revizije beleški",
"confirm_delete_all": "Da li želite da obrišete sve revizije ove beleške?",
"no_revisions": "Još uvek nema revizija za ovu belešku...",
"restore_button": "Vrati",
"confirm_restore": "Da li želite da vratite ovu reviziju? Ovo će prepisati trenutan naslov i sadržaj beleške sa ovom revizijom.",
"delete_button": "Obriši",
"confirm_delete": "Da li želite da obrišete ovu reviziju?",
"revisions_deleted": "Revizije beleške su obrisane.",
"revision_restored": "Revizija beleške je vraćena.",
"revision_deleted": "Revizija beleške je obrisana.",
"snapshot_interval": "Interval snimanja revizije beleške: {{seconds}}s.",
"maximum_revisions": "Ograničenje broja slika revizije beleške: {{number}}.",
"settings": "Podešavanja revizija beleški",
"download_button": "Preuzmi",
"mime": "MIME: ",
"file_size": "Veličina datoteke:",
"preview_not_available": "Pregled nije dostupan za ovaj tip beleške."
},
"sort_child_notes": {
"sort_children_by": "Sortiranje podbeleški po...",
"sorting_criteria": "Kriterijum za sortiranje",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "Om Trilium Notes",
"homepage": "Hemsida:",
"app_version": "App version:",
"db_version": "DB version:",
"sync_version": "Sync version:",
"build_date": "Bygg datum:",
"build_revision": "Bygg version:",
"data_directory": "Data sökväg:"
},
"toast": {

View File

@@ -1,13 +1,6 @@
{
"about": {
"homepage": "Anasayfa:",
"app_version": "Uygulama versiyonu:",
"db_version": "Veritabanı versiyonu:",
"title": "Trilium Notes Hakkında",
"sync_version": "Eşleştirme versiyonu:",
"data_directory": "Veri dizini:",
"build_date": "Derleme tarihi:",
"build_revision": "Derleme revizyonu:"
"data_directory": "Veri dizini:"
},
"branch_prefix": {
"save": "Kaydet",

View File

@@ -1,12 +1,5 @@
{
"about": {
"title": "關於 Trilium Notes",
"homepage": "項目主頁:",
"app_version": "程式版本:",
"db_version": "資料庫版本:",
"sync_version": "同步版本:",
"build_date": "編譯日期:",
"build_revision": "編譯版本:",
"data_directory": "資料目錄:"
},
"toast": {
@@ -41,7 +34,9 @@
"link_title_mirrors": "連結標題跟隨筆記標題變化",
"link_title_arbitrary": "連結標題可隨意修改",
"link_title": "連結標題",
"button_add_link": "新增連結"
"button_add_link": "新增連結",
"anchor": "錨點(可選)",
"anchor_none": "無(連結至筆記)"
},
"branch_prefix": {
"edit_branch_prefix": "編輯分支前綴",
@@ -89,13 +84,22 @@
},
"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}} 個其他克隆。此操作可在最近修改中撤銷。",
"delete_clones_description_other": "",
"erase_notes_label": "永久擦除",
"table_note_with_relation": "有關聯的筆記",
"table_relation": "關聯",
"table_points_to": "指向 (已刪除)",
"delete": "刪除"
},
"export": {
"export_note_title": "匯出筆記",
@@ -206,7 +210,8 @@
"box_size_small": "小型(顯示大約 10 行)",
"box_size_medium": "中型 (顯示大約30行)",
"box_size_full": "完整顯示(完整文字框)",
"button_include": "內嵌筆記"
"button_include": "內嵌筆記",
"box_size_expandable": "可展開(預設為摺疊狀態)"
},
"info": {
"modalTitle": "資訊消息",
@@ -267,33 +272,6 @@
"undelete_link": "取消刪除",
"confirm_undelete": "您確定要還原此筆記及其子筆記嗎?"
},
"revisions": {
"note_revisions": "筆記歷史版本",
"delete_all_revisions": "刪除此筆記的所有歷史版本",
"delete_all_button": "刪除所有歷史版本",
"help_title": "關於筆記歷史版本的說明",
"confirm_delete_all": "您是否要刪除此筆記的所有歷史版本?",
"no_revisions": "此筆記暫無歷史版本…",
"confirm_restore": "您是否要還原此歷史版本?這將使用此歷史版本覆寫筆記的目前標題和內容。",
"confirm_delete": "您是否要刪除此歷史版本?",
"revisions_deleted": "已刪除筆記歷史版本。",
"revision_restored": "已還原筆記歷史版本。",
"revision_deleted": "已刪除筆記歷史版本。",
"snapshot_interval": "筆記快照儲存間隔: {{seconds}}秒。",
"maximum_revisions": "目前筆記的最大歷史數量: {{number}}。",
"settings": "筆記歷史設定",
"download_button": "下載",
"mime": "MIME類型 ",
"file_size": "檔案大小:",
"preview_not_available": "無法預覽此類型的筆記。",
"restore_button": "還原",
"delete_button": "刪除",
"diff_on": "顯示差異",
"diff_off": "顯示內容",
"diff_on_hint": "點擊以顯示筆記原始碼差異",
"diff_off_hint": "點擊以顯示筆記內容",
"diff_not_available": "差異不可用。"
},
"sort_child_notes": {
"sort_children_by": "依…排序子筆記",
"sorting_criteria": "排序條件",
@@ -692,7 +670,7 @@
"export_note": "匯出筆記",
"delete_note": "刪除筆記",
"print_note": "列印筆記",
"save_revision": "儲存筆記歷史",
"save_revision": "儲存筆記修訂",
"convert_into_attachment_failed": "筆記 '{{title}}' 轉換失敗。",
"convert_into_attachment_successful": "筆記 '{{title}}' 已成功轉換為附件。",
"convert_into_attachment_prompt": "確定要將筆記 '{{title}}' 轉換為父級筆記的附件嗎?",
@@ -1094,7 +1072,6 @@
},
"database_integrity_check": {
"title": "資料庫完整性檢查",
"description": "檢查 SQLite 資料庫是否損壞。根據資料庫的大小,這可能會需要一些時間。",
"check_button": "檢查資料庫完整性",
"checking_integrity": "正在檢查資料庫完整性…",
"integrity_check_succeeded": "完整性檢查成功——未發現問題。",
@@ -1126,10 +1103,7 @@
"note_tree_font": "筆記樹字型",
"note_detail_font": "筆記內容字型",
"monospace_font": "等寬(程式碼)字型",
"note_tree_and_detail_font_sizing": "請注意,筆記樹字型和詳細字型的大小為相對於主字型大小設定。",
"not_all_fonts_available": "並非所有列出的字型都在您的系統上可用。",
"apply_font_changes": "要套用字型更改,請點擊",
"reload_frontend": "重新載入前端",
"generic-fonts": "通用字型",
"sans-serif-system-fonts": "無襯線系統字型",
"serif-system-fonts": "襯線系統字型",
@@ -1224,7 +1198,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "附件清理超時",
"attachment_auto_deletion_description": "如果附件在一段時間後不再被筆記引用,它們將被自動刪除(並被清理)。",
"manual_erasing_description": "您還可以手動觸發清理(而不考慮上述定義的超時時間):",
"erase_unused_attachments_now": "立即清理未使用的附件筆記",
"unused_attachments_erased": "已刪除未使用的附件。",
@@ -1236,7 +1209,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "筆記清理超時",
"note_erasure_description": "被刪除的筆記(以及屬性、歷史版本等)最初僅被標記為「刪除」,可以從「最近修改」對話方塊中還原它們。經過一段時間後,已刪除的筆記會被「清理」,這意味著它們的內容將無法被還原。此設定允許您設定從刪除到清除筆記之間的時間長度。",
"manual_erasing_description": "您還可以手動觸發清理(而不考慮上述定義的超時時間):",
"erase_deleted_notes_now": "立即清理已刪除的筆記",
"deleted_notes_erased": "已清理已刪除的筆記。",
@@ -1310,7 +1282,6 @@
"first-week-contains-first-thursday": "年度第一週包含第一個週四",
"first-week-has-minimum-days": "第一週有最少天數",
"min-days-in-first-week": "第一週的最少天數",
"first-week-info": "年度第一週包含第一個週四是基於 <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a> 標準。",
"first-week-warning": "變更第一週選項可能導致與現有的「週筆記」重複,現有的「週筆記」將不會相應更新。",
"formatting-locale": "日期和數字格式",
"tuesday": "週二",
@@ -1414,9 +1385,6 @@
"server_address": "伺服器地址",
"timeout": "同步超時(單位:毫秒)",
"proxy_label": "同步代理伺服器(可選)",
"note": "注意",
"note_description": "代理設定留空則使用系統代理(僅桌面版有效)。",
"special_value_description": "另一個特殊值是 <code>noproxy</code>,它強制忽略系統代理並遵守 <code>NODE_TLS_REJECT_UNAUTHORIZED</code>。",
"save": "儲存",
"help": "說明",
"test_title": "同步測試",
@@ -1467,7 +1435,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": "保護子階層",
@@ -2371,5 +2339,55 @@
"history": "對話歷史",
"recent_chats": "最近的對話",
"no_chats": "無先前的對話記錄"
},
"revisions": {
"note_revisions": "筆記歷史版本",
"delete_all_revisions": "刪除此筆記的所有歷史版本",
"delete_all_button": "刪除所有歷史版本",
"help_title": "關於筆記歷史版本的說明",
"confirm_delete_all": "您要刪除此筆記的所有歷史版本嗎?",
"no_revisions": "尚無此筆記的歷史版本...",
"restore_button": "還原",
"highlight_changes": "高亮變更",
"diff_on": "顯示差異",
"diff_off": "顯示內容",
"diff_on_hint": "點擊以顯示筆記來源差異",
"diff_off_hint": "點擊以顯示筆記內容",
"diff_not_available": "差異比較不可用。",
"confirm_restore": "您要還原此版本嗎?此操作將以該版本覆寫筆記目前的標題和內容。",
"delete_button": "刪除",
"confirm_delete": "您要刪除此版本嗎?",
"revisions_deleted": "筆記歷史版本已被刪除。",
"revision_restored": "筆記歷史版本已被還原。",
"revision_deleted": "筆記歷史版本已被刪除。",
"snapshot_interval": "筆記歷史版本快照間隔:{{seconds}} 秒。",
"maximum_revisions": "筆記歷史版本快照限制:{{number}}。",
"save_revision_now": "立即儲存修訂",
"save_named_revision": "儲存命名修訂…",
"snapshot_header": "筆記歷史版本快照",
"snapshot_interval_value": "間隔:{{seconds}} 秒",
"snapshot_limit_value": "限制:{{number}}",
"settings": "筆記歷史版本設定",
"menu_tooltip": "歷史版本選項",
"download_button": "下載",
"mime": "MIME 類型: ",
"file_size": "檔案大小:",
"preview_not_available": "此筆記類型不支援預覽功能。",
"save_revision": "儲存筆記修訂",
"save_revision_tooltip": "手動儲存目前筆記的快照",
"description_placeholder": "命名此歷史版本",
"revision_saved": "筆記修訂已儲存。",
"edit_description": "編輯名稱",
"description_updated": "歷史版本名稱已更新。",
"source_auto": "自動儲存",
"source_manual": "手動儲存",
"source_etapi": "ETAPI",
"source_llm": "大語言模型",
"source_restore": "還原",
"source_unknown": "快照",
"date_today": "今天",
"date_yesterday": "昨天",
"date_this_week": "這週",
"date_this_month": "這個月"
}
}

View File

@@ -0,0 +1,413 @@
{
"about": {
"data_directory": "سانلىق مەلۇمات مۇندەرىجىسى:"
},
"toast": {
"critical-error": {
"title": "ئېغىر خاتالىق",
"message": "قوللىنىشچان پروگراممىنىڭ قوزغىلىشىغا توسالغۇ بولىدىغان ئېغىر خاتالىق كۆرۈلدى:\n\n{{message}}\n\nبۇ ئادەتتە script نىڭ كۈتۈلمىگەن خاتالىقىدىن كېلىپ چىقىدۇ. پروگراممىنى بىخەتەر ھالەتتە (safe mode) قوزغىتىپ مەسىلىنى ھەل قىلىپ بېقىڭ。"
},
"widget-error": {
"title": "كىچىك زاپچاسلار دەسلەپكى قەدەمدە مەغلۇپ بولدى",
"message-custom": "ID نومۇرى \"{{id}}\"، تېمىسى \"{{title}}\" بولغان خاتىرىدىن كەلگەن ئۆزلەشتۈرۈلگەن ۋىجېت (Custom widget) تۆۋەندىكى سەۋەب تۈپەيلىدىن قوزغىتىلمىدى:\n\n{{message}}",
"message-unknown": "نامەلۇم كىچىك زاپچاسلار تۆۋەندىكى سەۋەبلەر تۈپەيلىدىن دەسلەپكى قەدەمدە بولالمايدۇ:\n\n{{message}}"
},
"bundle-error": {
"title": "scriptنى يۈكلەش مەغلۇپ بولدى",
"message": "scriptنى ئىجرا قىلغىلى بولمىدى:\n\n{{message}}"
},
"widget-list-error": {
"title": "serverدىن تىزىملىكىنى ئالغىلى بولمىدى"
},
"widget-render-error": {
"title": "ئۆزلەشتۈرۈلگەن React ۋىجېتىنى تەقدىم قىلىش (Render) مەغلۇپ بولدى"
},
"widget-missing-parent": "ئۆزگەرتىلگەن كىچىك زاپچاستا زۆرۈر بولغان’{{property}} خاسلىقى بەلگىلەنمىگەن.\n\nئەگەر بۇ سكريپت UI ئېلېمېنتلىرىسىز ئىجرا بولۇشقا مەجبۇر بولسا، \"#run=frontendStartup\" نى ئىشلىتىڭ.",
"open-script-note": "script خاتىرىنى ئېچىش",
"scripting-error": "Custom script خاتالىقى: {{title}}"
},
"add_link": {
"add_link": "ئۇلانما قوشۇش",
"help_on_links": "ئۇلانما ياردىمى",
"note": "خاتىرە",
"search_note": "خاتىرىنى نامى بويىچە ئىزدەش",
"link_title_mirrors": "ئۇلانما تېمىسى خاتىرىنىڭ ھازىرقى تېمىسى بىلەن ماس قەدەم بولىدۇ",
"link_title_arbitrary": "ئۇلانما تېمىسىنى خالىغانچە ئۆزگەرتىشكە بولىدۇ",
"link_title": "ئۇلانما تېمىسى",
"button_add_link": "ئۇلانما قوشۇش",
"anchor_none": "يوق (خاتىرىگە ئۇلاش)"
},
"branch_prefix": {
"edit_branch_prefix": "شاخچە ئالدى قوشۇمچىسىنى تەھرىرلەش",
"edit_branch_prefix_multiple": "{{count}} دانە شاخچىنىڭ ئالدى قوشۇمچىسىنى تەھرىرلەش",
"help_on_tree_prefix": "دەرەخ ئالدى قوشۇمچىسى ياردىمى",
"prefix": "ئالدى قوشۇمچە:· ",
"save": "ساقلاش",
"branch_prefix_saved": "شاخچە ئالدى قوشۇمچىسى ساقلاندى.",
"branch_prefix_saved_multiple": "{{count}} دانە شاخچىغا ئالدى قوشۇمچە ساقلاندى.",
"affected_branches": "تەسىرگە ئۇچرىغان شاخچىلار {{count}}:"
},
"bulk_actions": {
"bulk_actions": "تۈركۈملاپ بىر تەرەپ قىلىش",
"affected_notes": "تەسىرگە ئۇچرايدىغان خاتىرىلەر",
"include_descendants": "تاللانغان خاتىرىلەرنىڭ تارماق خاتىرىلىرىنى ئۆز ئىچىگە ئالسۇن",
"available_actions": "ئىشلەتكىلى بولىدىغان مەشغۇلاتلار",
"chosen_actions": "تاللانغان مەشغۇلاتلار",
"execute_bulk_actions": "تۈركۈملەپ بىر تەرەپ قىلىشنى ئىجرا قىلىش",
"bulk_actions_executed": "تۈركۈملەپ بىر تەرەپ قىلىش مۇۋەپپەقىيەتلىك تاماملاندى.",
"none_yet": "ھازىرچە مەشغۇلات يوق... ئۈستىدىكى مەشغۇلاتتىن تاللاڭ.",
"labels": "بەلگە",
"relations": "مۇناسىۋەتلەر",
"notes": "خاتىرىلەر",
"other": "باشقىلار"
},
"clone_to": {
"clone_notes_to": "خاتىرىلەرنى كۆچۈرۈش...",
"help_on_links": "ئۇلانما ياردىمى",
"notes_to_clone": "كۆچۈرۈلىدىغان خاتىرىلەر",
"target_parent_note": "نىشان تۈپ خاتىرە",
"search_for_note_by_its_name": "نامى بويىچە خاتىرە ئىزدەش",
"cloned_note_prefix_title": "كۆچۈرۈلگەن خاتىرىگە ئالدى قوشۇمچە بېرىلىدۇ",
"prefix_optional": "ئالدى قوشۇمچە (ئىختىيارىي)",
"clone_to_selected_note": "تاللانغان خاتىرىگە كۆچۈرۈش",
"no_path_to_clone_to": "كۆچۈرۈش يولى يوق.",
"note_cloned": "\"{{clonedTitle}}\" خاتىرە\"{{targetTitle}}\" غا كۆچۈرۈلدى"
},
"confirm": {
"confirmation": "جەزملەشتۈرۈش",
"cancel": "بىكار قىلىش",
"ok": "تامام",
"are_you_sure_remove_note": "\"{{title}}\" ناملىق خاتىرىنى مۇناسىۋەت خەرىتىسىدىن ئۆچۈرۈۋېتىشنى جەزملەشتۈرەمسىز؟ ",
"if_you_dont_check": "ئەگەر بۇنى تاللىمىسىڭىز، خاتىرە پەقەت مۇناسىۋەت خەرىتىسىدىنلا ئۆچۈرۈلىدۇ (خاتىرىنىڭ ئۆزى ئۆچۈرۈلمەيدۇ).",
"also_delete_note": "خاتىرىنىمۇ ئۆچۈرۈۋېتىش"
},
"delete_notes": {
"title": "خاتىرىلەرنى ئۆچۈرۈش",
"close": "ياپ",
"clones_label": "كۆچۈرۈلمىلەر",
"delete_clones_description_one": "يەنە {{count}} دانە باشقا كۆچۈرۈلمىنىمۇ ئۆچۈرىدۇ. يېقىنقى ئۆزگىرىشلەردىن ئەسلىگە كەلتۈرگىلى بولىدۇ.",
"delete_clones_description_other": "يەنە {{count}} دانە باشقا كۆچۈرۈلمىلەرنىمۇ ئۆچۈرىدۇ. يېقىنقى ئۆزگىرىشلەردىن ئەسلىگە كەلتۈرگىلى بولىدۇ.",
"delete_all_clones_description": "بارلىق كۆچۈرۈلمىلەرنىمۇ ئۆچۈرۈش (يېقىنقى ئۆزگىرىشلەردىن ئەسلىگە كەلتۈرگىلى بولىدۇ)",
"erase_notes_label": "مەڭگۈلۈك ئۆچۈرۈش",
"erase_notes_description": "يۇمشاق ئۆچۈرۈشنىڭ ئورنىغا خاتىرىنى دەرھال مەڭگۈلۈك ئۆچۈرىدۇ. بۇنى قايتۇرغىلى بولمايدۇ ۋە قوللىنىشنى قايتا يۈكلەيدۇ.",
"erase_notes_warning": "خاتىرىلەرنى مەڭگۈلۈك ئۆچۈرۈش (قايتۇرغىلى بولمايدۇ)، بارلىق كۆچۈرۈلمىلەرنىمۇ ئۆز ئىچىگە ئالىدۇ. بۇ قوللىنىشنى قايتا يۈكلەيدۇ.",
"notes_to_be_deleted": "ئۆچۈرۈلىدىغان خاتىرىلەر ({{notesCount}})",
"no_note_to_delete": "ھېچقانداق خاتىرە ئۆچۈرۈلمەيدۇ (پەقەت كۆچۈرۈلمىلەر).",
"broken_relations_to_be_deleted": "بۇزۇلغان مۇناسىۋەتلە ({{relationCount}})",
"table_note_with_relation": "مۇناسىۋەتلىك خاتىرە",
"table_relation": "مۇناسىۋەت",
"table_points_to": "ئورۇنغا ئۇلىنىدۇ(ئۆچۈرۈلگەن)",
"cancel": "بىكار قىلىش",
"delete": "ئۆچۈرۈش"
},
"export": {
"export_note_title": "خاتىرىنى چىقىرىش",
"close": "يېپىش",
"export_type_subtree": "بۇ خاتىرە ۋە ئۇنىڭ بارلىق تارماقلىرى",
"format_html": "HTML - بارلىق فورماتلارنى ساقلاپ قالىدىغان بولغاچقا تەۋسىيە قىلىنىدۇ",
"format_html_zip": "ZIP ئارخىپىدىكى HTML - بارلىق پىچىملارنى ساقلاپ قالىدىغان بولغاچقا، بۇ تاللاش تەۋسىيە قىلىنىدۇ.",
"format_markdown": "Markdown - بۇ كۆپ قىسىم فورماتلارنى ساقلاپ قالىدۇ.",
"format_opml": "OPML - پەقەت تېكىست ئۈچۈن ئىشلىتىلىدىغان پىلان (outliner) ئالماشتۇرۇش فورماتى. بۇنىڭغا فورماتلار، رەسىملەر ۋە ھۆججەتلەر كىرمەيدۇ.",
"opml_version_1": "OPML v1.0 - پەقەت ساپ تېكىستلا",
"opml_version_2": "HTML OPMLv2 - نىمۇ قوللايدۇ",
"export_type_single": "تارماقلىرىنى ئۆز ئىچىگە ئالمايدۇ، پەقەت مۇشۇ خاتىرىنىڭ ئۆزىلا",
"export": "چىقىرىش",
"choose_export_type": "ئالدى بىلەن چىقىرىش تۈرىنى تاللاڭ",
"export_status": "چىقىرىش ھالىتى",
"export_in_progress": "چىقىرىلىۋاتىدۇ: {{progressCount}}",
"export_finished_successfully": "چىقىرىش مۇۋەپپەقىيەتلىك تاماملاندى.",
"format_pdf": "PDF - بېسىپ چىقىرىش ياكى ھەمبەھرلەش مەقسىتىدە ئىشلىتىلىدۇ.",
"share-format": "توردا ئېلان قىلىش ئۈچۈن HTML - ھەمبەھرلەنگەن خاتىرىلەر بىلەن ئوخشاش تېمىنى ئىشلىتىدۇ، لېكىن تۇراقلىق تور بېكەت سۈپىتىدە ئېلان قىلىشقا بولىدۇ."
},
"help": {
"title": "ئاساسىي كۇنۇپكىلار",
"editShortcuts": "كۇنۇپكا تېزلەتمىلىرىنى تەھرىرلەش",
"noteNavigation": "خاتىرە يولباشچىسى",
"goUpDown": "خاتىرە تىزىملىكىدە يۇقىرى/تۆۋەنگە يۆتكىلىش",
"collapseExpand": "تۈرنى قاتلاش/يېيىش",
"notSet": "بېكىتىلمىگەن",
"goBackForwards": "تارىختا كەينىگە/ئالدىغا يۆتكىلىش",
"scrollToActiveNote": "نۆۋەتتىكى خاتىرىگە سىيرىپ بېرىش",
"jumpToParentNote": "تۈپ خاتىرىگە تېز يۆتكىلىش",
"collapseWholeTree": "بارلىق خاتىرە دەرىخىنى يىغىش",
"collapseSubTree": "تارماق تۈرلەرنى يىغىش",
"tabShortcuts": "بەتكۈچ تېزلەتمىلىرى",
"newTabNoteLink": "خاتىرە ئۇلىنىشىنى چەككەندە، خاتىرىنى يېڭى بەتكۈچتە ئېچىش",
"newTabWithActivationNoteLink": "خاتىرە ئۇلىنىشىنى يېڭى بەتكۈچتە ئېچىش ۋە ئاكتىپلاش",
"openEmptyTab": "بوش بەتكۈچ ئېچىش",
"creatingNotes": "خاتىرە قۇرۇش",
"createNoteAfter": "ئاكتىپ خاتىرىدىن كېيىن يېڭى خاتىرە قۇرۇش",
"createNoteInto": "ئاكتىپ خاتىرىنىڭ ئىچىگە يېڭى تارماق خاتىرە قۇرۇش",
"movingCloningNotes": "خاتىرە يۆتكەش / كۆچۈرۈش",
"moveNoteUpDown": "خاتىرىنى تىزىملىكتە ئاستىغا/ئۈستىگە يۆتكەش",
"moveNoteUpHierarchy": "خاتىرىنى دەرىجە بويىچە ئۈستىگە يۆتكەش",
"multiSelectNote": "ئۈستى/ئاستىدىكى خاتىرىلەرنى كۆپ تاللاش",
"selectAllNotes": "ھازىرقى دەرىجىدىكى بارلىق خاتىرىلەرنى تاللاش",
"selectNote": "خاتىرىنى تاللاش",
"cutNotes": "نۆۋەتتىكى خاتىرىنى (ياكى تاللانغانلارنى) كېسىپ چاپلاش تاختىسىغا ئېلىش (يۆتكەش ئۈچۈن ئىشلىتىلىدۇ)",
"pasteNotes": "خاتىرىنى ئاكتىپ خاتىرىنىڭ ئىچىگە تارماق خاتىرە قىلىپ چاپلاش",
"deleteNotes": "خاتىرە ياكى تارماق تۈرلەرنى ئۆچۈرۈش",
"editingNotes": "خاتىرىلەرنى تەھرىرلەش",
"createEditLink": "سىرتقى ئۇلانما قۇرۇش / تەھرىرلەش",
"createInternalLink": "ئىچكى ئۇلانما قۇرۇش",
"followLink": "نۇر بەلگىسى ئاستىدىكى ئۇلانمىغا ئەگىشىش",
"insertDateTime": "نۆۋەتتىكى ۋاقىت ۋە كۈننى قىستۇرۇش",
"jumpToTreePane": "خاتىرە تىزىملىكىگە ئۆتۈش ۋە ئاكتىپ خاتىرىنى كۆرسىتىش",
"markdownAutoformat": "Markdown شەكىللىك ئاپتوماتىك فورماتلاش",
"troubleshooting": "مەسىلە ھەل قىلىش",
"reloadFrontend": "Trilium نىڭ ئالدى يۈزىنى قايتا يۈكلەش",
"showDevTools": "تەتقىقاتچى قوراللىرىنى كۆرسىتىش",
"showSQLConsole": "SQL كونترول سۇپىسىنى كۆرسىتىش",
"other": "باشقىلار",
"quickSearch": "نۇر بەلگىسىنى تېز ئىزدەش رامكىسىغا يۆتكەش",
"inPageSearch": "بەت ئىچىدە ئىزدەش",
"showJumpToNoteDialog": "كۆرسىتىش<a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/note-navigation.html#jump-to-note\">\"بۇنىڭغا ئاتلاش\" سۆزلىشىش رامكىسى</a>",
"closeActiveTab": "ئاكتىپ بەتكۈچنى يېپىش",
"activateNextTab": "كېيىنكى بەتكۈچنى ئاكتىپلاش",
"activatePreviousTab": "ئالدىنقى بەتكۈچنى ئاكتىپلاش",
"editNoteTitle": "دەرەخسىمان خاتىرە تىزىملىكىدە، فوكۇس خاتىرە دەرىخىدىن خاتىرە ماۋزۇسىغا يۆتكىلىدۇ. Enter كۇنۇپكىسىنى باسسىڭىز فوكۇس خاتىرە ماۋزۇسىدىن تېكىست تەھرىرلىگۈچكە يۆتكىلىدۇ. <kbd>Ctrl+.</kbd> كۇنۇپكىسىنى باسسىڭىز فوكۇس تەھرىرلىگۈچتىن يەنە خاتىرە دەرىخىگە قايتىدۇ.",
"onlyInDesktop": "پەقەت Desktop نۇسخىسى (Electron build)",
"editBranchPrefix": "ئاكتىپ خاتىرە كوپىيىسىنىڭ تەھرىرلەش <a class=\"external\" href=\"https://triliumnext.github.io/Docs/Wiki/tree-concepts.html#prefix\">ئالدى قوشۇمچە</a>"
},
"import": {
"importIntoNote": "خاتىرىگە كىرگۈزۈش",
"chooseImportFile": "كىرگۈزىدىغان ھۆججەتنى تاللاش",
"importDescription": "تاللانغان ھۆججەت مەزمۇنلىرى تارماق خاتىرە سۈپىتىدە كىرگۈزۈلىدىغان ئورۇن",
"importZipRecommendation": "ZIP ھۆججىتىنى كىرگۈزگەندە، ھۆججەت قىسقۇچلارنىڭ ئورۇنلاشتۇرۇلۇشىغا ئاساسەن ئاپتوماتىك تارماق خاتىرىلەر قۇرۇلىدۇ.",
"options": "تاللانمىلار",
"safeImport": "بىخەتەر كىرگۈزۈش",
"shrinkImages": "«رەسىملەرنى كىچىكلىتىش",
"textImportedAsText": "ئۇچۇرى ئېنىق بولمىغان HTML، Markdown ۋە TXT لارنى تېكىست خاتىرىسىگە ئايلاندۇرۇش",
"replaceUnderscoresWithSpaces": "ئەكىرىلگەن خاتىرە ناملىرىدىكى ئاستى سىزىقلارنى بوشلۇققا ئالماشتۇرۇش",
"import": "كىرگۈزۈش",
"failed": "ئەكىرىش مەغلۇپ بولدى: {{message}}.",
"html_import_tags": {
"title": "HTML ئەكىرىش بەلگىلىرى",
"description": "خاتىرىلەرنى ئەكىرگەندە قايسى HTML بەلگىلىرىنى ساقلاپ قېلىشنى سەپلەڭ. بۇ تىزىملىكتە بولمىغان بەلگىلەر ئەكىرىش جەريانىدا ئۆچۈرۈۋېتىلىدۇ. بەزى بەلگىلەر (مەسىلەن 'script') بىخەتەرلىك ئۈچۈن ھەمىشە ئۆچۈرۈۋېتىلىدۇ.",
"placeholder": "ھەر بىر قۇرغا بىر HTML بەلگىسىدىن كىرگۈزۈڭ",
"reset_button": "ئەسلىدىكى تىزىملىككە ئەسلىگە قايتۇرۇش"
},
"import-status": "كىرگۈزۈش ھالىتى",
"in-progress": "ئەكىرىلىۋاتىدۇ: {{progress}}",
"successful": "كىرگۈزۈش مۇۋەپپەقىيەتلىك تاماملاندى.",
"explodeArchives": "<code>.zip</code>、<code>.enex</code> ۋە<code>.opml</code> ئارخىپ ھۆججەتلىرىنىڭ مەزمۇنىنى ئوقۇش.",
"codeImportedAsCode": "ئەگەر مېتا سانلىق مەلۇماتى ئېنىق بولمىسا، پەرقلەندۈرۈلگەن كود ھۆججىتىنى (مەسىلەن<code>.json</code>) كود خاتىرىسى سۈپىتىدە ئەكىرىش"
},
"include_note": {
"dialog_title": "خاتىرىنى ئۆز ئىچىگە ئېلىش",
"label_note": "خاتىرە",
"placeholder_search": "خاتىرىنى نامى بويىچە ئىزدەش",
"box_size_prompt": "ئۆز ئىچىگە ئالغان خاتىرىنىڭ رامكا چوڭلۇقى:",
"box_size_small": "كىچىك (10 قۇر ئەتراپىدا)",
"box_size_medium": "ئوتتۇراھال (30 قۇر ئەتراپىدا)",
"box_size_full": "تولۇق (رامكىدا پۈتۈن تېكىست كۆرسىتىلىدۇ)",
"box_size_expandable": "يېيىلىدىغان (ئەسلىدىكى ھالەتتە يىغىلغان)",
"button_include": "خاتىرىنى ئۆز ئىچىگە ئېلىش"
},
"info": {
"modalTitle": "ئۇچۇر ئۇقتۇرۇشى",
"closeButton": "تاقاش",
"okButton": "OK",
"copy_to_clipboard": "چاپلاش تاختىسىغا كۆچۈرۈش"
},
"jump_to_note": {
"search_placeholder": "خاتىرىنى نامى ياكى تىپى بويىچە ئىزدەڭ، بۇيرۇق ئۈچۈن >بەلگىسىنى كىرگۈزۈڭ...",
"search_button": "تولۇق تېكىست بويىچە ئىزدەش"
},
"markdown_import": {
"dialog_title": "Markdown نى كىرگۈزۈش",
"import_button": "كىرگۈزۈش",
"import_success": "Markdown مەزمۇنى ھۆججەتكە مۇۋەپپەقىيەتلىك كىرگۈزۈلدى."
},
"move_to": {
"dialog_title": "خاتىرىنى يۆتكەش...",
"notes_to_move": "يۆتكىلىدىغان خاتىرە",
"target_parent_note": "نىشان تۈپ خاتىرە",
"search_placeholder": "خاتىرىنى نامى بويىچە ئىزدەش",
"move_button": "تاللانغان خاتىرىگە يۆتكەش",
"error_no_path": "يۆتكىلىدىغان ئورۇن تېپىلمىدى。",
"move_success_message": "تاللانغان خاتىرە مۇشۇ يەرگە يۆتكەلدى "
},
"note_type_chooser": {
"change_path_prompt": "يېڭى خاتىرە قۇرۇش ئورنىنى ئۆزگەرتىش:",
"search_placeholder": "يولنى نامى بويىچە ئىزدەش (ئەسلى ھالىتى بېكىتىلمىگەن)",
"modal_title": "خاتىرە تۈرىنى تاللاش",
"modal_body": "يېڭى خاتىرە تۈرى ياكى template تاللاش:",
"builtin_templates": "ئىچكى Templates"
},
"password_not_set": {
"title": "مەخپىي نومۇر بېكىتىلمىگەن",
"body1": "قوغدىلىدىغان خاتىرىلەر ئىشلەتكۈچى مەخپىي نومۇرى بىلەن شىفىرلىنىدۇ، ئەمما مەخپىي نومۇر تېخى بېكىتىلمىگەن.",
"body2": "خاتىرىنى قوغداش ئۈچۈن، تۆۋەندىكى كۇنۇپكىنى بېسىپ «تاللانما» سۆزلىشىش رامكىسىنى ئېچىڭ ھەمدە مەخپىي نومۇر بېكىتىڭ.",
"go_to_password_options": "مەخپىي نومۇر تاللانمىسىغا يۆتكەش"
},
"prompt": {
"title": "ئەسكەرتىش",
"ok": "OK",
"defaultTitle": "ئەسكەرتىش"
},
"protected_session_password": {
"modal_title": "قوغدىلىدىغان session",
"help_title": "خاتىرىنى قوغداش ھەققىدىكى ياردەم",
"close_label": "تاقاش",
"form_label": "مەشغۇلاتنى داۋاملاشتۇرۇش ئۈچۈن، مەخپىي نومۇرنى كىرگۈزۈپ قوغدىلىدىغان session باشلىشىڭىز كېرەك:",
"start_button": "قوغدىلىدىغان sessionنى باشلاش"
},
"recent_changes": {
"title": "يېقىنقى ئۆزگىرىشلەر",
"erase_notes_button": "ئۆچۈرۈلگەن خاتىرىلەرنى ھازىرلا تۈپتىن يوقىتىش",
"deleted_notes_message": "ئۆچۈرۈلگەن خاتىرىلەر تۈپتىن يوقىتىلدى.",
"no_changes_message": "تېخى ھېچقانداق ئۆزگىرىش يوق...",
"undelete_link": "ئۆچۈرۈلگەننى ئەسلىگە كەلتۈرۈش",
"confirm_undelete": "بۇ خاتىرە ۋە ئۇنىڭ تارماق خاتىرىلىرىنى ئەسلىگە كەلتۈرۈشنى جەزملەشتۈرەمسىز؟"
},
"revisions": {
"note_revisions": "خاتىرە تەھرىرلىرى",
"delete_all_revisions": "بۇ خاتىرىنىڭ بارلىق تەھرىرلىرىنى ئۆچۈرۈش",
"delete_all_button": "بارلىق تەھرىرلەرنى ئۆچۈرۈش",
"help_title": "خاتىرە تەھرىرلىرى ھەققىدىكى ياردەم",
"confirm_delete_all": "بۇ خاتىرىنىڭ بارلىق تەھرىرلىرىنى ئۆچۈرۈشنى جەزملەشتۈرەمسىز؟",
"no_revisions": "بۇ خاتىرىنىڭ تېخى تەھرىرلەش خاتىرىسى يوق...",
"restore_button": "ئەسلىگە كەلتۈرۈش",
"highlight_changes": "ئۆزگىرىشلەرنى گەۋدىلەندۈرۈش",
"diff_on": "پەرقىنى كۆرسىتىش",
"diff_off": "مەزمۇننى كۆرسىتىش",
"diff_on_hint": "بۇ يەرنى چېكىپ خاتىرە مەنبەسىنىڭ پەرقىنى كۆرۈڭ",
"diff_off_hint": "بۇ يەرنى چېكىپ خاتىرە مەزمۇنىنى كۆرۈڭ",
"diff_not_available": "پەرقىنى كۆرسەتكىلى بولمايدۇ.",
"confirm_restore": "بۇ تەھرىرنى ئەسلىگە كەلتۈرۈشنى جەزملەشتۈرەمسىز؟ بۇ مەشغۇلات خاتىرىنىڭ نۆۋەتتىكى تېمىسى ۋە مەزمۇنىنى مۇشۇ تەھرىرگە ئالماشتۇرۇۋېتىدۇ.",
"delete_button": "ئۆچۈرۈش",
"confirm_delete": "بۇ تەھرىرنى ئۆچۈرۈشنى جەزملەشتۈرەمسىز؟",
"revisions_deleted": "خاتىرە تەھرىرلىرى ئۆچۈرۈلدى.",
"revision_restored": "خاتىرە تەھرىرى ئەسلىگە كەلتۈرۈلدى.",
"revision_deleted": "خاتىرە تەھرىرى ئۆچۈرۈلدى.",
"snapshot_interval": "خاتىرە تەھرىرى نۇسخىسىنى ساقلاش ئارىلىقى: {{seconds}} سېكۇنت.",
"maximum_revisions": "خاتىرە تەھرىرى نۇسخىسىنىڭ چەكلىمىسى: {{number}}.",
"save_revision_now": "تەھرىر نۇسخىسىنى ھازىر ساقلاش",
"save_named_revision": "ناملىق تەھرىر نۇسخىسىنى ساقلاش...",
"snapshot_header": "خاتىرە تەھرىرى نۇسخىسى",
"snapshot_interval_value": "ئارىلىقى: {{seconds}} سېكۇنت",
"snapshot_limit_value": "چەكلىمىسى: {{number}}",
"settings": "خاتىرە تەھرىرى تەڭشەكلىرى",
"menu_tooltip": "تەھرىر تاللانمىلىرى",
"download_button": "چۈشۈرۈش",
"mime": "MIME تىپى: ",
"file_size": "ھۆججەت چوڭلۇقى:",
"preview_not_available": "بۇ خىلدىكى خاتىرىنى ئالدىن كۆرگىلى بولمايدۇ.",
"save_revision": "تەھرىرنى ساقلاش",
"save_revision_tooltip": "نۆۋەتتىكى خاتىرىنىڭ نۇسخىسىنى قولدا ساقلاش",
"description_placeholder": "بۇ تەھرىرگە نام قويۇش",
"revision_saved": "خاتىرىنىڭ تەھرىر نۇسخىسى ساقلاندى.",
"edit_description": "نامىنى تەھرىرلەش",
"description_updated": "تەھرىر نامى يېڭىلاندى.",
"source_auto": "ئاپتوماتىك ساقلاش",
"source_manual": "قولدا ساقلاش",
"source_restore": "ئەسلىگە كەلتۈرۈش",
"date_today": "بۈگۈن",
"date_yesterday": "تۆنۈگۈن",
"date_this_week": "بۇ ھەپتە",
"date_this_month": "بۇ ئاي",
"source_description_auto": "سىستېما تەرىپىدىن قەرەللىك ئاپتوماتىك ساقلانغان",
"source_description_manual": "ئىشلەتكۈچى تەرىپىدىن قولدا ساقلانغان",
"source_description_etapi": "سىرتقى Trilium API ئارقىلىق قۇرۇلغان",
"source_description_llm": "AI ياردەمچىسى تەرىپىدىن قۇرۇلغان",
"source_description_restore": "ئىلگىرىكى تەھرىرنى ئەسلىگە كەلتۈرۈشتىن بۇرۇن ساقلانغان"
},
"sort_child_notes": {
"sort_children_by": "تارماق تۈرلەرنى تەرتىپلەش...",
"sorting_criteria": "تەرتىپلەش ئۆلچىمى",
"title": "ماۋزۇسى",
"date_created": "قۇرۇلغان ۋاقتى",
"date_modified": "ئۆزگەرتىلگەن ۋاقتى",
"sorting_direction": "تەرتىپلەش يۆنىلىشى",
"ascending": "ئۆرلەش تەرتىپى",
"descending": "تۆۋەنلەش تەرتىپى",
"folders": "ھۆججەت قىسقۇچى",
"sort_folders_at_top": "ھۆججەت قىسقۇچىنى ئالدىدا تەرتىپلەش",
"natural_sort": "تەبىئىي تەرتىپلەش",
"sort_with_respect_to_different_character_sorting": "ئوخشاش بولمىغان تىل ياكى رايونلارنىڭ ھەرپ تەرتىپى ۋە قائىدىسى بويىچە تەرتىپلەش.",
"natural_sort_language": "تىل بويىچە تەبىئىي تەرتىپلەش",
"the_language_code_for_natural_sort": "تەبىئىي تەرتىپلەشتە ئىشلىتىلىدىغان تىل كودى، مەسىلەن، خەنزۇچە ئۈچۈن «zh-CN».",
"sort": "تەرتىپلەش"
},
"upload_attachments": {
"upload_attachments_to_note": "قوشۇمچە ھۆججەتلەرنى خاتىرىگە يۈكلەش",
"choose_files": "ھۆججەتنى تاللاش",
"files_will_be_uploaded": "ھۆججەتلەر قوشۇمچە سۈپىتىدە {{noteTitle}} غا يۈكلىنىدۇ",
"options": "تاللانمىلار",
"shrink_images": "رەسىمنى كىچىكلىتىش",
"upload": "يۈكلەش",
"tooltip": "ئەگەر بۇ تاللانمىنى تاللىسىڭىز، Trilium يۈكلەنگەن رەسىملەرنى چوڭ-كىچىكلىكىنى تەڭشەش ۋە ئەلالاشتۇرۇش ئارقىلىق كىچىكلىتىشكە ئۇرۇنىدۇ، بۇ رەسىمنىڭ سۈپىتىگە تەسىر كۆرسىتىشى مۇمكىن. ئەگەر تاللانمىسا، رەسىملەر ئەسلىدىكى پېتى، ھېچقانداق ئۆزگەرتىشسىز يۈكلىنىدۇ."
},
"attribute_detail": {
"attr_detail_title": "خاسلىق تەپسىلات ماۋزۇسى",
"close_button_title": "ئۆزگەرتىشلەردىن ۋاز كېچىش ۋە تاقاش",
"attr_is_owned_by": "خاسلىق ئىگىسى",
"attr_name_title": "خاسلىق ئىسمى پەقەت ھەرپ-سانلار، ئىككى چېكىت (:) ۋە ئاستى سىزىقتىن (_) لا تەركىب تاپىدۇ",
"name": "نامى",
"value": "قىممىتى",
"target_note_title": "باغلىنىش بولسا مەنبە خاتىرە بىلەن نىشان خاتىرە ئوتتۇرىسىدىكى نام بېرىلگەن بىر خىل ئۇلىنىشتۇر.",
"target_note": "نىشان خاتىرە",
"promoted_title": "ئۆستۈرۈلگەن خاسلىق خاتىرىدە كۆرۈنەرلىك كۆرسىتىلىدۇ.",
"promoted": "ئۆستۈرۈلگەن",
"promoted_alias_title": "ئۆستۈرۈلگەن خاسلىقلار كۆرۈنمە يۈزىدە كۆرسىتىلىدىغان نام.",
"promoted_alias": "تەخەللۇس",
"multiplicity_title": "دەرىجىسى ئوخشاش ناملىق خاسلىقتىن قانچىنى قۇرغىلى بولىدىغانلىقىنى بەلگىلەيدۇ — ئەڭ كۆپ بولغاندا بىر ياكى بىردىن كۆپ.",
"multiplicity": "تەكرارلىقى",
"single_value": "يەككە قىممەت",
"multi_value": "كۆپ قىممەت",
"label_type_title": "بەلگە تىپى Trilium نىڭ بەلگە قىممىتىنى كىرگۈزۈشتە مۇۋاپىق كۆرۈنمە يۈزىنى تاللىشىغا ياردەم بېرىدۇ.",
"label_type": "تىپى",
"text": "تېكىست",
"textarea": "كۆپ قۇرلىق تېكىست",
"number": "سان",
"date": "چېسلا",
"date_time": "چېسلا ۋە ۋاقىت",
"time": "ۋاقىت",
"url": "تور ئادرېسى",
"precision_title": "قىممەت تەڭشەش كۆرۈنمە يۈزىدە، چېكىتتىن كېيىن قانچە خانىلىق سان كۆرسىتىلىشى .",
"precision": "ئېنىقلىقى",
"digits": "چېكىتتىن كېيىنكى خانە سانى",
"inverse_relation_title": "قايتۇرما مۇناسىۋەتنى بەلگىلەيدىغان تاللانما تەڭشەك. مەسىلەن: «دادا» ۋە «ئوغلان» بىر-بىرىگە قايتۇرما مۇناسىۋەتتۇر.",
"inverse_relation": "قايتۇرما مۇناسىۋەت",
"inheritable_title": "ۋارىسلىق قىلغىلى بولىدىغان خاسلىق شۇ دەرەخ قۇرۇلمىسى ئاستىدىكى بارلىق تارماقلارغا ۋارىسلىق قىلىنىدۇ.",
"inheritable": "ۋارىسلىق",
"save_and_close": "ساقلاش ۋە يېپىش <kbd>Ctrl+Enter</kbd>",
"delete": "ئۆچۈرۈش",
"related_notes_title": "مۇشۇ بەلگە قويۇلغان باشقا خاتىرىلەر",
"more_notes": "تېخىمۇ كۆپ خاتىرىلەر",
"label": "بەلگە تەپسىلاتى",
"label_definition": "بەلگە ئېنىقلىمىسى تەپسىلاتى",
"relation": "مۇناسىۋەت تەپسىلاتى",
"relation_definition": "مۇناسىۋەت ئېنىقلىمىسى تەپسىلاتى",
"disable_versioning": "ئاپتوماتىك نۇسخا باشقۇرۇشنى چەكلەيدۇ. بۇ چوڭ ھەجىملىك ئەمما مۇھىم بولمىغان خاتىرىلەرگە (مەسىلەن: قوليازما سىنارىيەسىدە ئىشلىتىلىدىغان چوڭ تىپتىكى JS ئامبارلىرىغا) ماس كېلىدۇ",
"calendar_root": "بۇ بەلگە كۈندىلىك خاتىرىلەرنىڭ يىلتىزىنى بەلگىلەيدۇ. پەقەت بىرلا خاتىرىگە مۇشۇ بەلگىنى قويۇش كېرەك.",
"archived": "مۇشۇ بەلگە قويۇلغان خاتىرىلەر ئىزدەش نەتىجىسىدە (شۇنداقلا «تېز ئۆتۈش»، «ئۇلانما قوشۇش» كۆزنىكى قاتارلىقلاردا) كۆرۈنمەيدۇ.",
"exclude_from_export": "خاتىرىلەر (ۋە ئۇنىڭ تارماق دەرەخلىرى) ھېچقانداق ئېكسپورت قىلىش مەشغۇلاتىغا كىرگۈزۈلمەيدۇ",
"run": "قوليازما script قايسى ھادىسىلەردە ئىجرا قىلىنىدىغانلىقىنى بەلگىلەيدۇ. تۆۋەندىكى قىممەتلەرنى تاللاشقا بولىدۇ:\n\n<ul>\n<li><strong>frontendStartup</strong> - Trilium ئالدى يۈزى قوزغالغاندا (ياكى يېڭىلانغاندا) ئىجرا قىلىنىدۇ، لېكىن كۆچمە تېلېفوننى ئۆز ئىچىگە ئالمايدۇ.</li>\n<li><strong>mobileStartup</strong> - Trilium ئالدى يۈزى كۆچمە تېلېفوندا قوزغالغاندا (ياكى يېڭىلانغاندا) ئىجرا قىلىنىدۇ.</li>\n<li><strong>backendStartup</strong> - Trilium ئارقا سۇپىسى قوزغالغاندا ئىجرا قىلىنىدۇ.</li>\n<li><strong>hourly</strong> - ھەر سائەتتە بىر قېتىم ئىجرا قىلىنىدۇ. سىز <code>runAtHour</code> قوشۇمچە بەلگىسىنى ئىشلىتىپ، كونكرېت قايسى سائەتتە ئىجرا قىلىنىدىغانلىقىنى بەلگىلىسىڭىز بولىدۇ.</li>\n<li><strong>daily</strong> - ھەر كۈنى بىر قېتىم ئىجرا قىلىنىدۇ.</li>\n</ul>",
"run_on_instance": "قايسى Trilium نۇسخىسىدا (instance) ئىجرا قىلىنىدىغانلىقىنى بەلگىلەيدۇ. ئەسلىدىكى تەڭشەكتە بارلىق نۇسخىلاردا ئىجرا قىلىنىدۇ.",
"run_at_hour": "قايسى سائەتتە ئىجرا قىلىنىدىغانلىقىنى بەلگىلەيدۇ. بۇنى <code>#run=hourly</code> بىلەن بىرلىكتە ئىشلىتىش كېرەك. بىر كۈندە كۆپ قېتىم ئىجرا قىلىش ئۈچۈن، بۇ بەلگىنى بىر نەچچە قېتىم تەكرار بەلگىلەشكە بولىدۇ.",
"disable_inclusion": "بۇ بەلگە قويۇلغان قوليازمىلار ئاساسىي قوليازما (parent script) ئىجرا قىلىنغاندا ئۇنىڭغا كىرگۈزۈلمەيدۇ.",
"sorted": "تارماق خاتىرىلەرنى ماۋزۇسىنىڭ ھەرىپ تەرتىپى بويىچە رەتلەيدۇ",
"sort_folders_first": "ھۆججەت قىسقۇچلار (تارماق خاتىرىسى بارلار) ئەڭ ئۈستىدە رەتلىنىشى كېرەك",
"top": "خاتىرىنى ئاساسىي خاتىرە (parent) ئىچىدە ئەڭ ئۈستىدە ساقلايدۇ (پەقەت رەتلەنگەن ئاساسىي خاتىرىلەرگىلا ماس كېلىدۇ)",
"hide_promoted_attributes": "بۇ خاتىرىدىكى كۆتۈرۈلگەن خاسلىقلارنى يوشۇرۇش",
"read_only": "تەھرىرلىگۈچنى «پەقەت ئوقۇش» ھالىتىگە تەڭشەيدۇ. بۇ پەقەت تېكىست ۋە كود تىپىدىكى خاتىرىلەرگىلا ماس كېلىدۇ.",
"auto_read_only_disabled": "تېكىست ياكى كود خاتىرىلىرى بەك چوڭ بولغاندا، ئاپتوماتىك «پەقەت ئوقۇش» ھالىتىگە تەڭشىلىدۇ. مۇشۇ بەلگىنى قوشۇش ئارقىلىق، شۇ خاتىرىنىڭ ئاپتوماتىك ئۆزگىرىش ئىقتىدارىنى چەكلەپ قويالايسىز",
"app_css": "Trilium غا يۈكلىنىدىغان CSS خاتىرىلىرىنى بەلگىلەيدۇ. بۇ ئارقىلىق Trilium نىڭ كۆرۈنۈش ئۇسلۇبىنى ئۆزگەرتىش ئىمكانىيىتىگە ئىگە بولىسىز.",
"app_theme": "Trilium نىڭ تولۇق ئۇسلۇب (Theme) CSSخاتىرىلىرىنى بەلگىلەيدۇ. بۇ خاتىرىلەر Trilium تەڭشىكىدىكى «تېما» تاللانمىلىرىدا كۆرۈنىدۇ.",
"app_theme_base": "TriliumNext ئۇسلۇبىنى ئاساس قىلىش ئۈچۈن، «next» قىلىپ تەڭشەڭ. بۇ كونا ئۇسلۇبتىكى ئاساسنىڭ ئورنىغا ئىشلىتىلىدۇ.",
"css_class": "مۇشۇ بەلگىنىڭ قىممىتى دەرەخسىمان قۇرۇلمىدىكى شۇ خاتىرىگە CSS class سۈپىتىدە قوشۇلىدۇ. بۇ يۇقىرى دەرىجىلىك ئۇسلۇب (theming) تەڭشەشلىرى ئۈچۈن ئىنتايىن پايدىلىق. بۇنى قېلىپ خاتىرىلىرى (template notes) ئىچىدە ئىشلىتىشكە بولىدۇ.",
"icon_class": "مۇشۇ بەلگىنىڭ قىممىتى دەرەخسىمان قۇرۇلمىدىكى سىنبەلگىگە CSS class قىلىپ قوشۇلىدۇ، بۇ خاتىرىلەرنى كۆرۈنۈش جەھەتتىن پەرقلەندۈرۈشكە ياردەم بېرىدۇ. مەسىلەن: bx bx-home؛ سىنبەلگىلەر boxicons دىن ئېلىنىدۇ. قېلىپ خاتىرىلىرى (template notes) ئىچىدە ئىشلىتىشكە بولىدۇ.",
"page_size": "خاتىرە تىزىملىكىنىڭ ھەر بىر بېتىدە كۆرۈنىدىغان تۈر سانى",
"widget": "بۇ خاتىرىنى Trilium نىڭ زاپچاس دەرىخىگە (component tree) قوشۇلىدىغان ئىختىيارىي كىچىك قورال (custom widget) قىلىپ بەلگىلەيدۇ",
"workspace": "بۇ خاتىرىنى «خىزمەت بوشلۇقى» قىلىپ بەلگىلەيدۇ، بۇ تېز سۈرەتتە شۇ قاتلامغا مەركەزلىشىش (hoisting) ئىمكانىيىتىنى يارىتىپ بېرىدۇ",
"workspace_icon_class": "بۇ خاتىرىگە مەركەزلەشكەندە (hoist قىلىنغاندا)، بەتكۈچتە (tab) كۆرۈنىدىغان box icon نىڭ CSS class نى بەلگىلەيدۇ",
"workspace_tab_background_color": "بۇ خاتىرىگە مەركەزلەشكەندە (hoist قىلىنغاندا)، خاتىرە بەتكۈچىدە (tab) ئىشلىتىلىدىغان CSS رەڭگىنى بەلگىلەيدۇ",
"workspace_calendar_root": "ھەر بىر خىزمەت بوشلۇقىنىڭ كالېندار ئاساسىي مۇندەرىجىسىنى بەلگىلەيدۇ",
"workspace_template": "يېڭى خاتىرە قۇرغاندا، بۇ قېلىپنى تاللاش تىزىملىكىدىن تاپقىلى بولىدۇ. ئەمما بۇ پەقەت مۇشۇ قېلىپنى ئۆز ئىچىگە ئالغان خىزمەت بوشلۇقىغا مەركەزلەشكەندە (hoist قىلىنغاندا) ئاندىن كۆرۈنىدۇ",
"search_home": "يېڭىدىن قۇرۇلغان ئىزدەش خاتىرىلىرى مۇشۇ خاتىرىنىڭ تارماق خاتىرىسى (تارماق تۈگۈنى) سۈپىتىدە قوشۇلىدۇ",
"workspace_search_home": "مۇشۇ خىزمەت بوشلۇقى خاتىرىسىنىڭ ھەرقانداق بىر يۇقىرى قاتلام تۈگۈنىگە مەركەزلەشكەندە (hoist قىلىنغاندا)، يېڭى ئىزدەش خاتىرىلىرى مۇشۇ خاتىرىنىڭ تارماق خاتىرىسى سۈپىتىدە قۇرۇلىدۇ",
"inbox": "يان تىزىملىكتىكى «يېڭى خاتىرە» كۇنۇپكىسى ئارقىلىق خاتىرە قۇرغاندا، سۈكۈتتىكى كىرىش ساندۇقى (inbox) ئورنىنى بەلگىلەيدۇ. يېڭى خاتىرە <code>#inbox</code> بەلگىسى قويۇلغان خاتىرىنىڭ تارماق خاتىرىسى سۈپىتىدە قۇرۇلىدۇ."
}
}

View File

@@ -20,14 +20,7 @@
"affected_branches": "Уражені гілки ({{count}}):"
},
"about": {
"app_version": "Версія програми:",
"db_version": "Версія БД:",
"build_date": "Дата збірки:",
"build_revision": "Ревізія збірки:",
"data_directory": "Каталог даних:",
"homepage": "Домашня сторінка:",
"title": "Про Trilium Notes",
"sync_version": "Версія синхронізації:"
"data_directory": "Каталог даних:"
},
"global_menu": {
"about": "Про Trilium Notes",
@@ -316,33 +309,6 @@
"undelete_link": "відновити",
"confirm_undelete": "Ви хочете відновити цю нотатку та її піднотатки?"
},
"revisions": {
"note_revisions": "Версії нотаток",
"delete_all_revisions": "Видалити всі версії цієї нотатки",
"delete_all_button": "Видалити всі версії",
"help_title": "Довідка щодо Версій нотаток",
"confirm_delete_all": "Ви хочете видалити всі версії цієї нотатки?",
"no_revisions": "Поки що немає версій цієї нотатки...",
"restore_button": "Відновити",
"confirm_restore": "Ви хочете відновити цю версію? Це замінить поточний заголовок та вміст нотатки цієї версії.",
"delete_button": "Видалити",
"confirm_delete": "Ви хочете видалити цю версію?",
"revisions_deleted": "Версії нотаток видалено.",
"revision_restored": "Версію нотатки відновлено.",
"revision_deleted": "Версію нотатки видалено.",
"snapshot_interval": "Інтервал знімків версій нотатки: {{seconds}}s.",
"maximum_revisions": "Ліміт знімків версій нотатки: {{number}}.",
"settings": "Налаштування Версії Нотатки",
"download_button": "Завантажити",
"mime": "МІМЕ: ",
"file_size": "Розмір файлу:",
"preview_not_available": "Попередній перегляд недоступний для цього типу нотатки.",
"diff_on": "Показати різницю",
"diff_off": "Показати вміст",
"diff_on_hint": "Натисніть, щоб показати різницю в джерелі нотатки",
"diff_off_hint": "Натисніть, щоб показати вміст нотатки",
"diff_not_available": "Різниця недоступна."
},
"include_note": {
"dialog_title": "Включити нотатку",
"label_note": "Нотатка",
@@ -1192,7 +1158,6 @@
},
"database_integrity_check": {
"title": "Перевірка цілісності Бази даних",
"description": "Це перевірить, чи не пошкоджена база даних на рівні SQLite. Це може зайняти деякий час, залежно від розміру бази даних.",
"check_button": "Перевірка цілісності бази даних",
"checking_integrity": "Перевірка цілісності бази даних...",
"integrity_check_succeeded": "Перевірка цілісності пройшла успішно — проблем не виявлено.",
@@ -1224,10 +1189,7 @@
"note_tree_font": "Шрифт Дерева нотатки",
"note_detail_font": "Шрифт деталей нотатки",
"monospace_font": "Monospace (кодовий) шрифт",
"note_tree_and_detail_font_sizing": "Зверніть увагу, що розмір шрифту дерева та деталей залежить від основного налаштування розміру шрифту.",
"not_all_fonts_available": "Не всі перелічені шрифти можуть бути доступні у вашій системі.",
"apply_font_changes": "Щоб застосувати зміни шрифту, натисніть на",
"reload_frontend": "перезавантажити інтерфейс",
"generic-fonts": "Загальні шрифти",
"sans-serif-system-fonts": "Системні шрифти Sans-serif",
"serif-system-fonts": "Системні шрифти Serif",
@@ -1366,7 +1328,6 @@
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "Тайм-аут стирання вкладень",
"attachment_auto_deletion_description": "Вкладення автоматично видаляються (і стираються), якщо на них більше не посилаються в нотатці після певного часу очікування.",
"erase_attachments_after": "Стерти невикористані вкладення після:",
"manual_erasing_description": "Ви також можете запустити стирання вручну (без урахування часу очікування, визначеного вище):",
"erase_unused_attachments_now": "Стерти невикористані вкладення нотаток зараз",
@@ -1378,7 +1339,6 @@
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "Тайм-аут стирання нотатки",
"note_erasure_description": "Видалені нотатки (а також атрибути, версії...) спочатку лише позначаються як видалені, і їх можна відновити з діалогового вікна Останні нотатки. Через певний проміжок часу видалені нотатки стираються, що означає, що їхній вміст більше не можна відновити. Цей параметр дозволяє налаштувати тривалість періоду між видаленням і стиранням нотатки.",
"erase_notes_after": "Стерти нотатки після:",
"manual_erasing_description": "Ви також можете запустити стирання вручну (без урахування часу очікування, визначеного вище):",
"erase_deleted_notes_now": "Стерти видалені нотатки зараз",
@@ -1463,7 +1423,6 @@
"first-week-contains-first-thursday": "Перший тиждень включає перший четвер року",
"first-week-has-minimum-days": "Перший тиждень має мінімальну кількість днів",
"min-days-in-first-week": "Мінімальна кількість днів у першому тижні",
"first-week-info": "Перший тиждень, що містить перший четвер року, базується на стандарті <a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Зміна параметрів першого тижня може призвести до дублювання з існуючими нотатками тижня, і існуючі нотатки тижня не будуть оновлені відповідно.",
"formatting-locale": "Формат дати & числа"
},
@@ -1748,9 +1707,6 @@
"server_address": "Адреса екземпляра сервера",
"timeout": "Тайм-аут синхронізації",
"proxy_label": "Синхронізація проксі-сервера (необов'язково)",
"note": "Нотатка",
"note_description": "Якщо залишити налаштування проксі-сервера порожнім, буде використано системний проксі-сервер (стосується лише збірки для ПК/електронної версії).",
"special_value_description": "Інше спеціальне значення — <code>noproxy</code>, яке змушує ігнорувати навіть системний проксі-сервер та враховує <code>NODE_TLS_REJECT_UNAUTHORIZED</code>.",
"save": "Зберегти",
"help": "Довідка",
"test_title": "Тест синхронізації",

View File

@@ -1,12 +1,5 @@
{
"about": {
"homepage": "Trang chủ:",
"title": "Về Trilium Notes",
"app_version": "Phiên bản:",
"db_version": "Phiên bản DB:",
"sync_version": "Phiên bản liên kết:",
"build_date": "Ngày build:",
"build_revision": "Xây dựng bản sửa đổi:",
"data_directory": "Đường dẫn dữ liệu:"
},
"add_link": {
@@ -69,10 +62,6 @@
"protected_session_password": {
"close_label": "Đóng"
},
"revisions": {
"restore_button": "Khôi phục",
"delete_button": "Xoá"
},
"upload_attachments": {
"options": "Tuỳ chọn"
},

View File

@@ -269,6 +269,8 @@ declare namespace Fancytree {
lazy: boolean;
/** Alternative description used as hover banner */
tooltip: string;
/** `<li>` 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 */

View File

@@ -1,3 +1,10 @@
declare module "htmldiff-js" {
const HtmlDiff: {
execute(oldHtml: string, newHtml: string): string;
};
export default HtmlDiff;
}
// TODO: Use real @types/ but that one generates a lot of errors.
declare module "draggabilly" {
type DraggabillyEventData = {};

View File

@@ -20,7 +20,8 @@ import tree from "../services/tree";
import { createImageSrcUrl, openInAppHelpFromUrl } from "../services/utils";
import { ViewTypeOptions } from "./collections/interface";
import ActionButton, { ActionButtonProps } from "./react/ActionButton";
import { useIsNoteReadOnly, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks";
import { ButtonGroup } from "./react/Button";
import { useIsNoteReadOnly, useNoteLabel, useNoteLabelBoolean, useTriliumEvent, useTriliumOption, useWindowSize } from "./react/hooks";
import NoteLink from "./react/NoteLink";
import RawHtml from "./react/RawHtml";
@@ -47,8 +48,9 @@ export type FloatingButtonsList = ((context: FloatingButtonContext) => false | V
export const DESKTOP_FLOATING_BUTTONS: FloatingButtonsList = [
RefreshBackendLogButton,
SwitchSplitOrientationButton,
ToggleReadOnlyButton,
SwitchSplitOrientationButton,
DisplayModeSwitcher,
EditButton,
ShowTocWidgetButton,
ShowHighlightsListWidgetButton,
@@ -80,9 +82,13 @@ function RefreshBackendLogButton({ note, parentComponent, noteContext, isDefault
}
function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: FloatingButtonContext) {
const isEnabled = note.type === "mermaid" && note.isContentAvailable() && !isReadOnly && isDefaultViewMode;
const [ displayMode ] = useNoteLabel(note, "displayMode");
const [ splitEditorOrientation, setSplitEditorOrientation ] = useTriliumOption("splitEditorOrientation");
const upcomingOrientation = splitEditorOrientation === "horizontal" ? "vertical" : "horizontal";
const effectiveMode = displayMode === "source" || displayMode === "split" || displayMode === "preview"
? displayMode
: isReadOnly ? "preview" : "split";
const isEnabled = note.type === "mermaid" && note.isContentAvailable() && effectiveMode === "split" && isDefaultViewMode;
return isEnabled && <FloatingButton
text={upcomingOrientation === "vertical" ? t("switch_layout_button.title_vertical") : t("switch_layout_button.title_horizontal")}
@@ -94,7 +100,7 @@ function SwitchSplitOrientationButton({ note, isReadOnly, isDefaultViewMode }: F
function ToggleReadOnlyButton({ note, isDefaultViewMode }: FloatingButtonContext) {
const [ isReadOnly, setReadOnly ] = useNoteLabelBoolean(note, "readOnly");
const isSavedSqlite = note.isTriliumSqlite() && !note.isHiddenCompletely();
const isEnabled = ([ "mermaid", "mindMap", "canvas" ].includes(note.type) || isSavedSqlite)
const isEnabled = ([ "mindMap", "canvas", "spreadsheet" ].includes(note.type) || isSavedSqlite)
&& note.isContentAvailable() && isDefaultViewMode;
return isEnabled && <FloatingButton
@@ -104,6 +110,33 @@ function ToggleReadOnlyButton({ note, isDefaultViewMode }: FloatingButtonContext
/>;
}
function DisplayModeSwitcher({ note, isDefaultViewMode }: FloatingButtonContext) {
const [ displayMode, setDisplayMode ] = useNoteLabel(note, "displayMode");
const isEnabled = (note.isMarkdown() || note.type === "mermaid") && note.isContentAvailable() && isDefaultViewMode;
if (!isEnabled) return false;
const mode = displayMode === "source" || displayMode === "preview" ? displayMode : "split";
const buttons: Array<{ value: "source" | "split" | "preview"; icon: string; text: string }> = [
{ value: "source", icon: "bx bx-code", text: t("display_mode.source") },
{ value: "split", icon: "bx bxs-dock-left", text: t("display_mode.split") },
{ value: "preview", icon: "bx bx-show", text: t("display_mode.preview") }
];
return (
<ButtonGroup size="sm">
{buttons.map(({ value, icon, text }) => (
<FloatingButton
key={value}
icon={icon}
text={text}
active={mode === value}
onClick={() => setDisplayMode(value)}
/>
))}
</ButtonGroup>
);
}
function EditButton({ note, noteContext }: FloatingButtonContext) {
const [animationClass, setAnimationClass] = useState("");
const {isReadOnly, enableEditing} = useIsNoteReadOnly(note, noteContext);

View File

@@ -4,6 +4,7 @@ import clsx from "clsx";
import { isValidElement, VNode } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
import appContext from "../components/app_context";
import NoteContext from "../components/note_context";
import FNote from "../entities/fnote";
import type { PrintReport } from "../print";
@@ -146,13 +147,21 @@ export default function NoteDetail() {
toast.closePersistent("printing");
handlePrintReport(printReport);
};
const onPreviewResult = (_e: any, { buffer, notePath }: { buffer: Uint8Array; notePath: string }) => {
toast.closePersistent("printing");
if (note) {
appContext.triggerCommand("showPrintPreview", { pdfBuffer: buffer, note, notePath });
}
};
ipcRenderer.on("print-progress", onPrintProgress);
ipcRenderer.on("print-done", onPrintDone);
ipcRenderer.on("export-as-pdf-preview-result", onPreviewResult);
return () => {
ipcRenderer.off("print-progress", onPrintProgress);
ipcRenderer.off("print-done", onPrintDone);
ipcRenderer.off("export-as-pdf-preview-result", onPreviewResult);
};
}, []);
}, [note]);
useTriliumEvent("executeInActiveNoteDetailWidget", ({ callback }) => {
if (!noteContext?.isActive()) return;
@@ -173,54 +182,51 @@ export default function NoteDetail() {
useTriliumEvent("printActiveNote", () => {
if (!noteContext?.isActive() || !note) return;
showToast("printing");
if (isElectron()) {
// On Electron, open the print preview dialog. Actual print/PDF actions
// are triggered from the dialog's footer buttons.
showToast("exporting_pdf");
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.send("print-note", {
notePath: noteContext.notePath
ipcRenderer.send("export-as-pdf-preview", {
title: note.title,
notePath: noteContext.notePath,
pageSize: note.getAttributeValue("label", "printPageSize") ?? "Letter",
landscape: note.hasAttribute("label", "printLandscape"),
scale: parseFloat(note.getAttributeValue("label", "printScale") ?? "1") || 1,
margins: note.getAttributeValue("label", "printMargins") ?? "default",
pageRanges: ""
});
} else {
const iframe = document.createElement('iframe');
iframe.src = `?print#${noteContext.notePath}`;
iframe.className = "print-iframe";
document.body.appendChild(iframe);
iframe.onload = () => {
if (!iframe.contentWindow) {
toast.closePersistent("printing");
document.body.removeChild(iframe);
return;
return;
}
// Browser fallback: render the print page in a hidden iframe and use window.print().
showToast("printing");
const iframe = document.createElement('iframe');
iframe.src = `?print#${noteContext.notePath}`;
iframe.className = "print-iframe";
document.body.appendChild(iframe);
iframe.onload = () => {
if (!iframe.contentWindow) {
toast.closePersistent("printing");
document.body.removeChild(iframe);
return;
}
iframe.contentWindow.addEventListener("note-load-progress", (e) => {
showToast("printing", e.detail.progress);
});
iframe.contentWindow.addEventListener("note-ready", (e) => {
toast.closePersistent("printing");
if ("detail" in e) {
handlePrintReport(e.detail as PrintReport);
}
iframe.contentWindow.addEventListener("note-load-progress", (e) => {
showToast("printing", e.detail.progress);
});
iframe.contentWindow.addEventListener("note-ready", (e) => {
toast.closePersistent("printing");
if ("detail" in e) {
handlePrintReport(e.detail as PrintReport);
}
iframe.contentWindow?.print();
document.body.removeChild(iframe);
});
};
}
});
useTriliumEvent("exportAsPdf", () => {
if (!noteContext?.isActive() || !note) return;
showToast("exporting_pdf");
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.send("export-as-pdf", {
title: note.title,
notePath: noteContext.notePath,
pageSize: note.getAttributeValue("label", "printPageSize") ?? "Letter",
landscape: note.hasAttribute("label", "printLandscape")
});
iframe.contentWindow?.print();
document.body.removeChild(iframe);
});
};
});
return (
@@ -346,7 +352,9 @@ export async function getExtendedWidgetType(note: FNote | null | undefined, note
resultingType = "readOnlyText";
} else if (note.isTriliumSqlite()) {
resultingType = "sqlConsole";
} else if ((type === "code" || type === "mermaid") && (await noteContext?.isReadOnly())) {
} else if (note.isMarkdown()) {
resultingType = "markdown";
} else if (type === "code" && (await noteContext?.isReadOnly())) {
resultingType = "readOnlyCode";
} else if (type === "text") {
resultingType = "editableText";

View File

@@ -267,7 +267,9 @@ const ATTR_HELP: Record<string, Record<string, string>> = {
newNotesOnTop: t("attribute_detail.new_notes_on_top"),
hideHighlightWidget: t("attribute_detail.hide_highlight_widget"),
printLandscape: t("attribute_detail.print_landscape"),
printPageSize: t("attribute_detail.print_page_size")
printPageSize: t("attribute_detail.print_page_size"),
printScale: t("attribute_detail.print_scale"),
printMargins: t("attribute_detail.print_margins")
},
relation: {
runOnNoteCreation: t("attribute_detail.run_on_note_creation"),

View File

@@ -0,0 +1,179 @@
.about-dialog {
:where(body.light-theme &) {
--donate-button-color: #e33f3b;
&.nightly {
--modal-background-color: #f2e1ff;
}
}
:where(body.dark-theme &) {
--donate-button-color: #fba6a5;
&.nightly {
--modal-background-color: #23182b;
}
}
--bs-modal-width: 680px;
.icon {
width: 160px;
height: 160px;
&[data-icon="default"] {
background-image: url(../../assets/icon.svg);
}
&[data-icon="nightly"] {
background-image: url(../../assets/icon-nightly.svg);
}
&[data-icon="default"],
&[data-icon="nightly"] {
animation: icon-intro 500ms ease-out;
will-change: opacity, transform;
}
&[data-icon="classic"] {
mask-image: url(../../assets/icon-classic.svg);
background-color: var(--muted-text-color);
animation: icon-classic-intro 300ms ease-in-out;
will-change: opacity, transform;
}
}
h2 {
all: unset;
font-size: 2em;
font-weight: 300;
letter-spacing: 1pt;
.channel-name {
opacity: .75;
}
}
.about-dialog-content {
display: flex;
flex-direction: column;
align-items: center;
}
.about-dialog-property-sheet {
margin-block: 30px;
&.wide {
font-size: .85em;
margin-inline: 20px;
}
}
.build-info {
color: var(--muted-text-color);
font-size: .9em;
}
.contributor-list {
a, span {
white-space: nowrap;
}
.contributor-role {
text-decoration: underline dotted var(--main-text-color);
text-underline-offset: 3px;
text-decoration-color: var(--muted-text-color);
cursor: help;
}
.about-dialog-property-sheet.narrow & {
line-height: 1.75;
}
}
footer {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
a {
--_icon-size: 28px;
display: flex;
flex-direction: column;
align-items: center;
padding: 8px 10px;
border-radius: 6px;
font-size: .9rem;
color: var(--main-text-color);
&:hover {
background: var(--icon-button-hover-background);
}
&::after {
display: none;
}
i {
font-size: var(--_icon-size);
}
svg {
fill: currentColor;
height: var(--_icon-size);
}
&.donate-link {
color: var(--donate-button-color);
&:hover i {
animation: heartbeat 600ms ease-in-out;
animation-iteration-count: 3;
}
}
}
}
}
.about-dialog-brief-history-tooltip {
--main-font-size: .9em;
padding-inline: 30px;
.tooltip-inner {
max-width: 600px;
}
}
@keyframes icon-intro {
from {
opacity: 0;
transform: scale(.5);
} to {
opacity: 1;
transform: scale(1);
}
}
@keyframes icon-classic-intro {
from {
opacity: 0;
transform: rotate(50deg) scale(.5);
} to {
opacity: 1;
transform: rotate(0deg) scale(1.25);
}
}
@keyframes heartbeat {
0% {
transform: scale(1);
} 50% {
transform: scale(1.15);
} 75% {
transform: scale(1);
} 100% {
transform: scale(1);
}
}

View File

@@ -1,84 +1,236 @@
import type { AppInfo } from "@triliumnext/commons";
import type { CSSProperties } from "preact/compat";
import { useState } from "preact/hooks";
import Modal from "../react/Modal.js";
import { t } from "../../services/i18n.js";
import openService from "../../services/open.js";
import { formatDateTime } from "../../utils/formatters.js";
import server from "../../services/server.js";
import utils from "../../services/utils.js";
import { formatDateTime } from "../../utils/formatters.js";
import { useTriliumEvent } from "../react/hooks.jsx";
import Modal from "../react/Modal.js";
import openService from "../../services/open.js";
import { useState, useCallback, useRef } from "preact/hooks";
import type { AppInfo, Contributor, ContributorList } from "@triliumnext/commons";
import { useTooltip, useTriliumEvent } from "../react/hooks.jsx";
import { PropertySheet, PropertySheetItem } from "../react/PropertySheet.js";
import "./about.css";
import { Trans } from "react-i18next";
import type React from "react";
import contributors from "../../../../../contributors.json";
import { Fragment } from "preact/jsx-runtime";
import type { ComponentChildren } from "preact";
import { useMemo, memo } from "preact/compat";
import clsx from "clsx";
export default function AboutDialog() {
const [appInfo, setAppInfo] = useState<AppInfo | null>(null);
const [shown, setShown] = useState(false);
const forceWordBreak: CSSProperties = { wordBreak: "break-all" };
const [isShown, setIsShown] = useState(false);
const [isNightly, setNightly] = useState(false);
const [icon, setIcon] = useState("default");
const [altIcon, setAltIcon] = useState<string | null>(null);
useTriliumEvent("openAboutDialog", () => setShown(true));
const hasLoaded = useRef(false);
const onLoad = useCallback(async () => {
if (!hasLoaded.current) {
const info = await server.get<AppInfo>("app-info");
if (info.appVersion.includes("test")) {
setNightly(true);
setIcon("nightly");
}
setAppInfo(info);
hasLoaded.current = true;
}
setIsShown(true);
}, []);
useTriliumEvent("openAboutDialog", onLoad);
const createContributorHoverHandler = () => {
let timeoutID: ReturnType<typeof setTimeout>;
return (contributor: Contributor, isHovering: boolean, part: "name" | "role") => {
if (part === "role" && contributor.role === "original-dev") {
if (isHovering) {
timeoutID = setTimeout(() => {
setAltIcon("classic");
}, 500);
} else {
clearTimeout(timeoutID);
setAltIcon(null);
}
}
}
};
/* Cache the contributor list to prevent its rerendering.
* When the icon changes, it triggers a rerender of the dialog. If this happens while an
* element with a tooltip is hovered, its tooltip will break. */
const CachedContributors = useMemo(() => memo(function CachedContributors() {
return <Contributors
data={contributors as ContributorList}
onHover={createContributorHoverHandler()}
/>
}), []);
return (
<Modal className="about-dialog"
size="lg"
title={t("about.title")}
show={shown}
onShown={async () => {
const appInfo = await server.get<AppInfo>("app-info");
setAppInfo(appInfo);
}}
onHidden={() => setShown(false)}
<Modal
className={clsx(["about-dialog", {"nightly": isNightly}])}
size="md"
isFullPageOnMobile
show={isShown}
onHidden={() => setIsShown(false)}
>
<table className="table table-borderless">
<tbody>
<tr>
<th>{t("about.homepage")}</th>
<td className="selectable-text"><a className="tn-link external" href="https://github.com/TriliumNext/Trilium" style={forceWordBreak}>https://github.com/TriliumNext/Trilium</a></td>
</tr>
<tr>
<th>{t("about.app_version")}</th>
<td className="app-version selectable-text">{appInfo?.appVersion}</td>
</tr>
<tr>
<th>{t("about.db_version")}</th>
<td className="db-version selectable-text">{appInfo?.dbVersion}</td>
</tr>
<tr>
<th>{t("about.sync_version")}</th>
<td className="sync-version selectable-text">{appInfo?.syncVersion}</td>
</tr>
<tr>
<th>{t("about.build_date")}</th>
<td className="build-date selectable-text">
{appInfo?.buildDate ? formatDateTime(appInfo.buildDate) : ""}
</td>
</tr>
<tr>
<th>{t("about.build_revision")}</th>
<td className="selectable-text">
{appInfo?.buildRevision && <a className="tn-link build-revision external" href={`https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`} target="_blank" style={forceWordBreak} rel="noreferrer">{appInfo.buildRevision}</a>}
</td>
</tr>
{ appInfo?.dataDirectory && <tr>
<th>{t("about.data_directory")}</th>
<td className="data-directory">
{appInfo?.dataDirectory && (<DirectoryLink directory={appInfo.dataDirectory} style={forceWordBreak} />)}
</td>
</tr>}
</tbody>
</table>
<div className="about-dialog-content">
<div className={"icon"} data-icon={altIcon ?? icon} />
<h2>Trilium Notes {isNightly && <span className="channel-name">Nightly</span>}</h2>
<a className="tn-link" href="https://triliumnotes.org/" target="_blank" rel="noopener noreferrer">
triliumnotes.org
</a>
<PropertySheet className="about-dialog-property-sheet">
<PropertySheetItem label={t("about.version_label")}>
{t("about.version", {
appVersion: appInfo?.appVersion,
dbVersion: appInfo?.dbVersion,
syncVersion: appInfo?.syncVersion
})}
<div className="build-info">
<Trans
i18nKey="about.build_info"
values={{
buildDate: appInfo?.buildDate ? formatDateTime(appInfo.buildDate) : ""
}}
components={{
buildRevision: <RevisionLink appInfo={appInfo} /> as React.ReactElement
}}
/>
</div>
</PropertySheetItem>
<PropertySheetItem className="contributor-list use-tn-links" label={t("about.contributors_label")}>
<CachedContributors />
<a href="https://github.com/TriliumNext/Trilium/graphs/contributors" target="_blank" rel="noopener noreferrer">
{t("about.contributor_full_list")}
</a>
</PropertySheetItem>
<PropertySheetItem label={t("about.data_directory")}>
<div style={{wordBreak: "break-all"}}>
{appInfo?.dataDirectory && (<DirectoryLink directory={appInfo.dataDirectory} />)}
</div>
</PropertySheetItem>
</PropertySheet>
</div>
<footer>
<FooterLink
text="GitHub"
url="https://github.com/TriliumNext/Trilium"
tooltip={t("about.github_tooltip")}>
<i className='bx bxl-github'></i>
</FooterLink>
<FooterLink
text="AGPL 3.0"
url="https://docs.triliumnotes.org/user-guide/misc/license"
tooltip={t("about.license_tooltip")}>
{/* https://pictogrammers.com/library/mdi/icon/scale-balance/ */}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,3C10.73,3 9.6,3.8 9.18,5H3V7H4.95L2,14C1.53,16 3,17 5.5,17C8,17 9.56,16 9,14L6.05,7H9.17C9.5,7.85 10.15,8.5 11,8.83V20H2V22H22V20H13V8.82C13.85,8.5 14.5,7.85 14.82,7H17.95L15,14C14.53,16 16,17 18.5,17C21,17 22.56,16 22,14L19.05,7H21V5H14.83C14.4,3.8 13.27,3 12,3M12,5A1,1 0 0,1 13,6A1,1 0 0,1 12,7A1,1 0 0,1 11,6A1,1 0 0,1 12,5M5.5,10.25L7,14H4L5.5,10.25M18.5,10.25L20,14H17L18.5,10.25Z" /></svg>
</FooterLink>
<FooterLink
text={t("about.donate")}
url="https://triliumnotes.org/en/support-us"
tooltip={t("about.donate_tooltip")}
className="donate-link">
<i className='bx bx-heart' ></i>
</FooterLink>
</footer>
</Modal>
);
}
function DirectoryLink({ directory, style }: { directory: string, style?: CSSProperties }) {
function RevisionLink({appInfo}: {appInfo: AppInfo | null}) {
return <>
{appInfo?.buildRevision && <a href={`https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`} target="_blank" rel="noopener noreferrer" className="tn-link">
{appInfo.buildRevision.substring(0, 7)}
</a>}
</>;
}
function FooterLink(props: {children: ComponentChildren, text: string, url: string, tooltip: string, className?: string}) {
const linkRef = useRef<HTMLAnchorElement>(null);
useTooltip(linkRef, {
title: props.tooltip,
delay: 250,
placement: "bottom"
})
return <a ref={linkRef} href={props.url} className={props.className} target="_blank" rel="noopener noreferrer" draggable={false}>
{props.children}
{props.text}
</a>
}
type HoverCallback = (contributor: Contributor, isHovering: boolean, part: "name" | "role") => void;
function Contributors({data, onHover}: {data: ContributorList, onHover?: HoverCallback}) {
return data.contributors.map((c, index, array) => {
return <Fragment key={c.name}>
<ContributorListItem data={c} onHover={onHover} />
{/* Add a comma between items */}
{(index < array.length - 1) ? ", " : ". "}
</Fragment>
});
}
function ContributorListItem({data, onHover}: {data: Contributor, onHover?: HoverCallback}) {
const roleRef = useRef<HTMLSpanElement>(null);
const roleString = (data.role) ? t(`about.contributor_roles.${data.role}`) : "";
useTooltip(roleRef, (data.role) ? {
title: t(`about.role_brief_history.${data.role}`),
customClass: "about-dialog-brief-history-tooltip",
placement: "bottom",
offset: [0, 10],
delay: 500
}: {});
return <>
<a
href={data.url}
target="_blank"
rel="noopener noreferrer"
onMouseEnter={() => onHover?.(data, true, "name")}
onMouseLeave={() => onHover?.(data, false, "name")}>
{data.fullName ?? data.name}
</a>
{roleString && <span
ref={roleRef}
onMouseEnter={() => onHover?.(data, true, "role")}
onMouseLeave={() => onHover?.(data, false, "role")}>
(<span className="contributor-role">{roleString}</span>)
</span>}
</>
}
function DirectoryLink({ directory }: { directory: string}) {
if (utils.isElectron()) {
const onClick = (e: MouseEvent) => {
e.preventDefault();
openService.openDirectory(directory);
};
return <a className="tn-link selectable-text" href="#" onClick={onClick} style={style}>{directory}</a>;
}
return <span className="selectable-text" style={style}>{directory}</span>;
}
return <a className="tn-link selectable-text" href="#" onClick={onClick}>{directory}</a>
} else {
return <span className="selectable-text">{directory}</span>;
}
}

View File

@@ -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<LinkType>();
const [ suggestion, setSuggestion ] = useState<Suggestion | null>(null);
const [ bookmarks, setBookmarks ] = useState<string[]>([]);
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() {
/>
</FormGroup>
{bookmarks.length > 0 && (
<FormGroup label={t("add_link.anchor")} name="anchor">
<select
className="form-select"
value={selectedBookmark}
onChange={(e) => setSelectedBookmark((e.target as HTMLSelectElement).value)}
>
<option value="">{t("add_link.anchor_none")}</option>
{bookmarks.map((bk) => (
<option key={bk} value={bk}>{bk}</option>
))}
</select>
</FormGroup>
)}
{!opts?.hasSelection && (
<div className="add-link-title-settings">
{(linkType !== "external-link") && (

View File

@@ -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<Suggestion | null>();
const [ noteTypes, setNoteTypes ] = useState<MenuItem<TreeCommandNames>[]>([]);
const modalRef = useRef<HTMLDivElement>(null);
const autocompleteRef = useRef<HTMLInputElement>(null);
useTriliumEvent("chooseNoteType", ({ callback }) => {
setCallback(() => callback);
@@ -68,11 +71,17 @@ export default function NoteTypeChooserDialogComponent() {
return (
<Modal
modalRef={modalRef}
title={t("note_type_chooser.modal_title")}
className="note-type-chooser-dialog"
size="md"
zIndex={1100} // note type chooser needs to be higher than other dialogs from which it is triggered, e.g. "add link"
scrollable
onShown={() => {
refToJQuerySelector(autocompleteRef)
.trigger("focus")
.trigger("select");
}}
onHidden={() => {
callback?.({ success: false });
setShown(false);
@@ -82,6 +91,7 @@ export default function NoteTypeChooserDialogComponent() {
>
<FormGroup name="parent-note" label={t("note_type_chooser.change_path_prompt")}>
<NoteAutocomplete
inputRef={autocompleteRef}
onChange={setParentNote}
placeholder={t("note_type_chooser.search_placeholder")}
opts={{

View File

@@ -0,0 +1,480 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
import FNote from "../../entities/fnote";
import { t } from "../../services/i18n";
import toast from "../../services/toast";
import { dynamicRequire, isElectron } from "../../services/utils";
import Button, { ButtonGroup } from "../react/Button";
import Dropdown from "../react/Dropdown";
import { FormListHeader, FormListItem } from "../react/FormList";
import { useNoteLabelBoolean, useNoteLabelWithDefault, useTriliumEvent } from "../react/hooks";
import Modal from "../react/Modal";
import Slider from "../react/Slider";
import PdfViewer from "../type_widgets/file/PdfViewer";
import OptionsRow from "../type_widgets/options/components/OptionsRow";
import OptionsSection from "../type_widgets/options/components/OptionsSection";
const PAGE_SIZES = ["A0", "A1", "A2", "A3", "A4", "A5", "A6", "Legal", "Letter", "Tabloid", "Ledger"] as const;
/** Pseudo-printer name used to route the Print button to the PDF export flow. */
const DESTINATION_PDF = "__pdf__";
interface PrinterInfo {
name: string;
displayName: string;
description: string;
location: string;
isDefault: boolean;
}
/** Builds the description line shown under a printer in the dropdown. */
function buildPrinterDescription(printer: PrinterInfo): string | undefined {
const parts: string[] = [];
if (printer.isDefault) parts.push(t("print_preview.destination_default"));
if (printer.location) parts.push(printer.location);
else if (printer.description) parts.push(printer.description);
return parts.length ? parts.join(" · ") : undefined;
}
const MARGIN_PRESETS = ["default", "none", "minimum"] as const;
type MarginPreset = typeof MARGIN_PRESETS[number];
interface CustomMargins {
top: number;
right: number;
bottom: number;
left: number;
}
function parseMarginValue(value: string): { preset: MarginPreset | "custom"; custom: CustomMargins } {
if (MARGIN_PRESETS.includes(value as MarginPreset)) {
return { preset: value as MarginPreset, custom: { top: 10, right: 10, bottom: 10, left: 10 } };
}
const parts = value.split(",").map(Number);
if (parts.length === 4 && parts.every((n) => !isNaN(n))) {
return { preset: "custom", custom: { top: parts[0], right: parts[1], bottom: parts[2], left: parts[3] } };
}
return { preset: "default", custom: { top: 10, right: 10, bottom: 10, left: 10 } };
}
function serializeMargins(preset: MarginPreset | "custom", custom: CustomMargins): string {
if (preset !== "custom") return preset;
return `${custom.top},${custom.right},${custom.bottom},${custom.left}`;
}
/** Validates a page-range string such as "1-5, 8, 11-13". Empty string is valid (= all pages). */
function isValidPageRanges(value: string): boolean {
const trimmed = value.trim();
if (!trimmed) return true;
return /^\s*\d+(\s*-\s*\d+)?(\s*,\s*\d+(\s*-\s*\d+)?)*\s*$/.test(trimmed);
}
export interface PrintPreviewData {
pdfBuffer: Uint8Array;
note: FNote;
notePath: string;
}
interface PreviewOpts {
landscape: boolean;
pageSize: string;
scale: number;
margins: string;
pageRanges: string;
}
export default function PrintPreviewDialog() {
const [shown, setShown] = useState(false);
const [pdfUrl, setPdfUrl] = useState<string>();
const [note, setNote] = useState<FNote>();
const [loading, setLoading] = useState(false);
const bufferRef = useRef<Uint8Array>();
const notePathRef = useRef("");
const pdfUrlRef = useRef<string>();
const generationRef = useRef(0);
const [landscape, setLandscape] = useNoteLabelBoolean(note, "printLandscape");
const [pageSize, setPageSize] = useNoteLabelWithDefault(note, "printPageSize", "Letter");
const [scaleStr, setScaleStr] = useNoteLabelWithDefault(note, "printScale", "1");
const scale = parseFloat(scaleStr) || 1;
const [marginsStr, setMarginsStr] = useNoteLabelWithDefault(note, "printMargins", "default");
const { preset: marginPreset, custom: customMargins } = useMemo(() => parseMarginValue(marginsStr), [marginsStr]);
// Page ranges are kept local — they're one-off per export, not a persistent preference.
const [pageRanges, setPageRanges] = useState("");
const pageRangesValid = isValidPageRanges(pageRanges);
// Printer list and current destination. DESTINATION_PDF means "Save as PDF";
// any other value is the system printer name to use for silent printing.
const [printers, setPrinters] = useState<PrinterInfo[]>([]);
const [destination, setDestination] = useState<string>(DESTINATION_PDF);
const skipNextRegenRef = useRef(false);
useEffect(() => {
if (!shown || !isElectron()) return;
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.invoke("get-printers").then((list: PrinterInfo[]) => {
setPrinters(list ?? []);
const defaultPrinter = list?.find((p) => p.isDefault);
if (defaultPrinter) setDestination(defaultPrinter.name);
});
}, [shown]);
const updatePreview = useCallback((buffer: Uint8Array) => {
bufferRef.current = buffer;
if (pdfUrlRef.current) {
URL.revokeObjectURL(pdfUrlRef.current);
}
const blob = new Blob([buffer as BlobPart], { type: "application/pdf" });
const url = URL.createObjectURL(blob);
pdfUrlRef.current = url;
setPdfUrl(url);
setLoading(false);
}, []);
useTriliumEvent("showPrintPreview", (data: PrintPreviewData) => {
// When the dialog is already open, it manages its own regeneration via
// a persistent IPC listener. Ignore duplicate events from NoteDetail's
// listener to avoid overwriting the preview with stale data.
if (shown) return;
skipNextRegenRef.current = true;
setNote(data.note);
notePathRef.current = data.notePath;
updatePreview(data.pdfBuffer);
setShown(true);
});
// Handle regeneration results via a persistent listener scoped to the
// dialog's lifecycle. A generation counter discards stale results when
// multiple requests overlap.
useEffect(() => {
if (!shown || !isElectron()) return;
const { ipcRenderer } = dynamicRequire("electron");
const onResult = (_e: any, { buffer, error }: { buffer?: Uint8Array; error?: string }) => {
if (generationRef.current <= 0) return;
toast.closePersistent("printing");
if (error) {
setLoading(false);
if (pdfUrlRef.current) {
URL.revokeObjectURL(pdfUrlRef.current);
pdfUrlRef.current = undefined;
setPdfUrl(undefined);
}
toast.showPersistent({
id: "print-preview-error",
icon: "bx bx-error-circle",
message: `${t("print_preview.render_error")}\n\n${error}`
});
return;
}
toast.closePersistent("print-preview-error");
if (buffer) {
updatePreview(buffer);
}
};
ipcRenderer.on("export-as-pdf-preview-result", onResult);
return () => {
ipcRenderer.off("export-as-pdf-preview-result", onResult);
};
}, [shown, updatePreview]);
const regeneratePreview = useCallback((opts: PreviewOpts) => {
if (!isElectron()) return;
++generationRef.current;
setLoading(true);
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.send("export-as-pdf-preview", {
notePath: notePathRef.current,
pageSize: opts.pageSize,
landscape: opts.landscape,
scale: opts.scale,
margins: opts.margins,
pageRanges: opts.pageRanges
});
}, []);
useEffect(() => {
if (!shown || !pageRangesValid) return;
if (skipNextRegenRef.current) {
skipNextRegenRef.current = false;
return;
}
const handle = setTimeout(() => {
regeneratePreview({ landscape, pageSize, scale, margins: marginsStr, pageRanges: pageRanges.trim() });
}, 400);
return () => clearTimeout(handle);
}, [shown, landscape, pageSize, scale, marginsStr, pageRanges, pageRangesValid, regeneratePreview]);
function handleClose() {
setShown(false);
toast.closePersistent("print-preview-error");
if (pdfUrlRef.current) {
URL.revokeObjectURL(pdfUrlRef.current);
pdfUrlRef.current = undefined;
setPdfUrl(undefined);
}
bufferRef.current = undefined;
setLoading(false);
}
function handleExportPdf() {
if (!bufferRef.current) return;
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.send("save-pdf", {
title: note?.title ?? "",
buffer: bufferRef.current
});
handleClose();
}
function handlePrint(silent: boolean, deviceName?: string) {
if (!isElectron()) return;
const { ipcRenderer } = dynamicRequire("electron");
ipcRenderer.send("print-from-preview", {
notePath: notePathRef.current,
pageSize,
landscape,
scale,
margins: marginsStr,
pageRanges,
silent,
deviceName
});
handleClose();
}
/** Primary action: route to PDF export or silent print based on the selected destination. */
function handlePrimaryAction() {
if (destination === DESTINATION_PDF) {
handleExportPdf();
} else {
handlePrint(true, destination);
}
}
function handleScaleChange(newScale: number) {
const clamped = Math.min(2, Math.max(0.1, Math.round(newScale * 10) / 10));
setScaleStr(String(clamped));
}
function handleCustomMarginChange(side: keyof CustomMargins, value: number) {
const newCustom = { ...customMargins, [side]: Math.max(0, value) };
setMarginsStr(serializeMargins("custom", newCustom));
}
return (
<Modal
className="print-preview-dialog"
title={t("print_preview.title")}
size="xl"
show={shown}
onHidden={handleClose}
bodyStyle={{ height: "78vh", padding: 0, display: "flex" }}
footerAlignment="between"
footer={
<>
<a
href="#"
class={loading ? "disabled" : ""}
onClick={(e) => {
e.preventDefault();
if (loading) return;
// When a specific printer is selected, pre-select it in the system dialog.
const deviceName = destination === DESTINATION_PDF ? undefined : destination;
handlePrint(false, deviceName);
}}
>
{t("print_preview.system_print")}
</a>
<Button
text={destination === DESTINATION_PDF ? t("print_preview.export_pdf") : t("print_preview.print")}
icon={destination === DESTINATION_PDF ? "bx-file" : "bx-printer"}
className="btn-primary"
onClick={handlePrimaryAction}
disabled={loading}
/>
</>
}
>
<div style={{ padding: "16px", minWidth: "250px", overflowY: "auto" }}>
<OptionsSection>
<OptionsRow name="destination" label={t("print_preview.destination")}>
<Dropdown
disabled={loading}
text={<DestinationLabel destination={destination} printers={printers} />}
>
<FormListItem
icon="bx bxs-file-pdf"
selected={destination === DESTINATION_PDF}
onClick={() => setDestination(DESTINATION_PDF)}
>
{t("print_preview.destination_pdf")}
</FormListItem>
{printers.length > 0 && <FormListHeader text={t("print_preview.destination_printers")} />}
{printers.map((printer) => (
<FormListItem
key={printer.name}
icon="bx bx-printer"
selected={destination === printer.name}
onClick={() => setDestination(printer.name)}
description={buildPrinterDescription(printer)}
>
{printer.displayName || printer.name}
</FormListItem>
))}
</Dropdown>
</OptionsRow>
<OptionsRow name="orientation" label={t("print_preview.orientation")}>
<ButtonGroup>
<Button
text={t("print_preview.portrait")}
icon="bx-rectangle bx-rotate-90"
className={!landscape ? "active" : ""}
onClick={() => setLandscape(false)}
disabled={loading}
size="small"
/>
<Button
text={t("print_preview.landscape")}
icon="bx-rectangle"
className={landscape ? "active" : ""}
onClick={() => setLandscape(true)}
disabled={loading}
size="small"
/>
</ButtonGroup>
</OptionsRow>
<OptionsRow name="pageSize" label={t("print_preview.page_size")}>
<select
class="form-select form-select-sm"
value={pageSize}
onChange={(e) => setPageSize((e.target as HTMLSelectElement).value)}
disabled={loading}
>
{PAGE_SIZES.map((size) => (
<option key={size} value={size}>{size}</option>
))}
</select>
</OptionsRow>
<OptionsRow name="scale" label={t("print_preview.scale")} description={`${Math.round(scale * 100)}%`}>
<Slider
value={scale}
min={0.1}
max={2}
step={0.1}
onChange={handleScaleChange}
/>
</OptionsRow>
<OptionsRow name="margins" label={t("print_preview.margins")}>
<select
class="form-select form-select-sm"
value={marginPreset}
onChange={(e) => setMarginsStr(serializeMargins((e.target as HTMLSelectElement).value as MarginPreset | "custom", customMargins))}
disabled={loading}
>
<option value="default">{t("print_preview.margins_default")}</option>
<option value="none">{t("print_preview.margins_none")}</option>
<option value="minimum">{t("print_preview.margins_minimum")}</option>
<option value="custom">{t("print_preview.margins_custom")}</option>
</select>
</OptionsRow>
{marginPreset === "custom" && (
<MarginEditor margins={customMargins} onChange={handleCustomMarginChange} disabled={loading} />
)}
<OptionsRow
name="pageRanges"
label={t("print_preview.page_ranges")}
description={!pageRangesValid ? t("print_preview.page_ranges_invalid") : t("print_preview.page_ranges_hint")}
>
<input
type="text"
class={`form-control form-control-sm ${!pageRangesValid ? "is-invalid" : ""}`}
value={pageRanges}
placeholder={t("print_preview.page_ranges_placeholder")}
onInput={(e) => setPageRanges((e.target as HTMLInputElement).value)}
disabled={loading}
style={{ width: "140px" }}
/>
</OptionsRow>
</OptionsSection>
</div>
<div style={{ flex: 1, position: "relative" }}>
{loading && (
<div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1, backgroundColor: "var(--modal-bg-color, rgba(255,255,255,0.8))" }}>
<span class="bx bx-loader-circle bx-spin" style={{ fontSize: "2rem" }} />
</div>
)}
{pdfUrl && <PdfViewer pdfUrl={pdfUrl} disableSelection />}
</div>
</Modal>
);
}
function DestinationLabel({ destination, printers }: { destination: string; printers: PrinterInfo[] }) {
if (destination === DESTINATION_PDF) {
return <><span class="bx bxs-file-pdf" /> {t("print_preview.destination_pdf")}</>;
}
const printer = printers.find((p) => p.name === destination);
return <><span class="bx bx-printer" /> {printer?.displayName || printer?.name || destination}</>;
}
function MarginEditor({ margins, onChange, disabled }: {
margins: CustomMargins;
onChange: (side: keyof CustomMargins, value: number) => void;
disabled: boolean;
}) {
const spinnerStyle = { width: "130px" };
return (
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: "4px", padding: "8px 0" }}>
<MarginSpinner label={t("print_preview.margin_top")} value={margins.top} onChange={(v) => onChange("top", v)} disabled={disabled} style={spinnerStyle} />
<div style={{ display: "flex", gap: "24px", alignItems: "center" }}>
<MarginSpinner label={t("print_preview.margin_left")} value={margins.left} onChange={(v) => onChange("left", v)} disabled={disabled} style={spinnerStyle} />
<MarginSpinner label={t("print_preview.margin_right")} value={margins.right} onChange={(v) => onChange("right", v)} disabled={disabled} style={spinnerStyle} />
</div>
<MarginSpinner label={t("print_preview.margin_bottom")} value={margins.bottom} onChange={(v) => onChange("bottom", v)} disabled={disabled} style={spinnerStyle} />
</div>
);
}
function MarginSpinner({ label, value, onChange, disabled, style }: {
label: string;
value: number;
onChange: (value: number) => void;
disabled: boolean;
style?: Record<string, string>;
}) {
return (
<div class="input-group input-group-sm" style={style}>
<input
type="number"
class="form-control form-control-sm"
title={label}
aria-label={label}
value={value}
min={0}
max={100}
step={1}
onChange={(e) => onChange(Math.min(100, (e.target as HTMLInputElement).valueAsNumber || 0))}
disabled={disabled}
/>
<span class="input-group-text">mm</span>
</div>
);
}

View File

@@ -3,74 +3,209 @@ body.mobile .revisions-dialog {
height: 95vh;
}
.modal-header {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
font-size: 0.9em;
}
.modal-title {
flex-grow: 1;
width: 100%;
}
.modal-body {
height: fit-content !important;
flex-direction: column;
padding: 0;
}
.modal-footer {
font-size: 0.9em;
}
.revision-list {
height: fit-content !important;
max-height: 20vh;
border-bottom: 1px solid var(--main-border-color) !important;
padding: 0 1em;
flex-shrink: 0;
}
.modal-body > .revision-content-wrapper {
flex-grow: 1;
max-width: unset !important;
height: 100%;
margin: 0;
display: block !important;
}
.modal-body > .revision-content-wrapper > div:first-of-type {
flex-direction: column;
}
.revision-title {
font-size: 1rem;
}
.revision-title-buttons {
text-align: center;
display: flex;
gap: 0.25em;
.revision-toolbar-actions {
flex-wrap: wrap;
}
.revision-content {
padding: 0.5em;
height: fit-content;
}
}
body.desktop .revisions-dialog {
.revision-list {
width: 300px;
}
.modal-content-with-sidebar {
height: 80vh;
}
}
.revisions-dialog {
.revision-title-buttons {
.modal-body {
padding: 0;
display: flex;
flex-direction: column;
}
.modal-sidebar {
background-color: var(--card-background-color);
}
.modal-sidebar .dropdown-menu.static {
background-color: transparent !important;
border-radius: 0 !important;
}
.revision-toolbar {
flex-shrink: 0;
border-bottom: 1px solid var(--main-border-color);
padding: 8px 20px;
}
.revision-title {
font-size: 1.2em;
margin: 8px 0;
}
.revision-toolbar-actions {
display: flex;
align-items: center;
gap: 4px;
}
.revision-menu-header {
font-weight: bold;
font-size: 0.85em;
text-transform: uppercase;
opacity: 0.6;
}
.revision-content-wrapper {
flex-grow: 1;
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
.revision-content {
flex-grow: 1;
min-height: 0;
overflow: auto;
padding: 20px;
}
.no-items {
padding-block: 3em;
}
.revision-list {
flex: 1 1 0;
min-height: 0;
overflow: auto;
.dropdown-item {
min-height: 2.5em;
>div {
padding-left: 0.25em;
min-width: 0;
}
}
}
.revision-item-description {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.85em;
opacity: 0.7;
}
.revision-group-header {
font-size: 0.75em;
font-weight: bold;
text-transform: uppercase;
opacity: 0.5;
padding: 6px 12px 2px;
}
.revision-item-meta {
font-size: 0.85em;
opacity: 0.7;
}
.revision-description-icon {
opacity: 0.5;
flex-shrink: 0;
}
.revision-description-editor {
display: flex;
gap: 5px;
align-items: center;
margin: 3px 0;
input {
flex-grow: 1;
}
}
.revision-description-display {
display: flex;
align-items: center;
margin: 3px 0;
gap: 5px;
min-height: 24px;
}
.revision-description-text {
font-size: 0.9em;
&.empty {
opacity: 0.5;
font-style: italic;
}
}
.revision-diff-code {
font-family: var(--font-family-monospace, monospace);
font-size: 0.9rem;
white-space: pre-wrap;
word-break: break-all;
max-width: 100%;
padding: 0;
}
/* HTML diff styles (htmldiff-js) */
.revision-diff-content {
ins {
text-decoration: none;
&.diffins,
&.diffmod {
background-color: color-mix(in srgb, var(--bs-success) 25%, transparent);
}
}
del {
text-decoration: line-through;
&.diffdel,
&.diffmod {
background-color: color-mix(in srgb, var(--bs-danger) 25%, transparent);
}
}
/* Image diff styles */
ins img,
del img {
border: 3px solid;
border-radius: 4px;
position: relative;
}
del img {
border-color: var(--bs-danger);
opacity: 0.6;
}
ins img {
border-color: var(--bs-success);
}
}
.revision-content.type-file {
display: flex;
min-width: 0;

View File

@@ -1,8 +1,10 @@
import "./revisions.css";
import type { RevisionItem, RevisionPojo } from "@triliumnext/commons";
import { dayjs, type RevisionItem, type RevisionPojo } from "@triliumnext/commons";
import clsx from "clsx";
import { diffWords } from "diff";
import HtmlDiff from "htmldiff-js";
import { Fragment } from "preact";
import type { CSSProperties } from "preact/compat";
import { Dispatch, StateUpdater, useEffect, useRef, useState } from "preact/hooks";
@@ -20,11 +22,13 @@ import toast from "../../services/toast";
import utils from "../../services/utils";
import ActionButton from "../react/ActionButton";
import Button from "../react/Button";
import FormList, { FormListItem } from "../react/FormList";
import Dropdown from "../react/Dropdown";
import FormList, { FormDropdownDivider, FormListItem } from "../react/FormList";
import FormToggle from "../react/FormToggle";
import { useTriliumEvent } from "../react/hooks";
import Modal from "../react/Modal";
import { RawHtmlBlock } from "../react/RawHtml";
import NoItems from "../react/NoItems";
import { RawHtmlBlock, SanitizedHtml } from "../react/RawHtml";
import PdfViewer from "../type_widgets/file/PdfViewer";
export default function RevisionsDialog() {
@@ -33,7 +37,7 @@ export default function RevisionsDialog() {
const [ revisions, setRevisions ] = useState<RevisionItem[]>();
const [ currentRevision, setCurrentRevision ] = useState<RevisionItem>();
const [ shown, setShown ] = useState(false);
const [ showDiff, setShowDiff ] = useState(false);
const [ showDiff, setShowDiff ] = useState(true);
const [ refreshCounter, setRefreshCounter ] = useState(0);
useTriliumEvent("showRevisions", async ({ noteId }) => {
@@ -54,114 +58,390 @@ export default function RevisionsDialog() {
}
}, [ note, refreshCounter ]);
const revisionsLoaded = revisions !== undefined;
const hasRevisions = !!revisions?.length;
if (revisions?.length && !currentRevision) {
setCurrentRevision(revisions[0]);
}
const onHidden = () => {
setShown(false);
setShowDiff(true);
setNote(undefined);
setCurrentRevision(undefined);
setRevisions(undefined);
};
if (revisionsLoaded && !hasRevisions) {
return (
<Modal
className="revisions-dialog"
size="md"
title={t("revisions.note_revisions")}
helpPageId="vZWERwf8U3nx"
header={note && (
<RevisionsMenu
note={note}
onRevisionSaved={() => {
setRefreshCounter(c => c + 1);
setCurrentRevision(undefined);
}}
onAllDeleted={() => {
setRevisions([]);
setCurrentRevision(undefined);
}}
hasRevisions={false}
/>
)}
onHidden={onHidden}
show={shown}
>
<NoItems icon="bx bx-history" text={t("revisions.no_revisions")} />
</Modal>
);
}
return (
<Modal
className="revisions-dialog"
size="xl"
title={t("revisions.note_revisions")}
helpPageId="vZWERwf8U3nx"
bodyStyle={{ display: "flex", height: "80vh" }}
header={
!!revisions?.length && (
<>
{["text", "code", "mermaid"].includes(currentRevision?.type ?? "") && (
<FormToggle
currentValue={showDiff}
onChange={(newValue) => setShowDiff(newValue)}
switchOnName={t("revisions.diff_on")}
switchOffName={t("revisions.diff_off")}
switchOnTooltip={t("revisions.diff_on_hint")}
switchOffTooltip={t("revisions.diff_off_hint")}
/>
)}
&nbsp;
<Button
text={t("revisions.delete_all_revisions")}
size="small"
style={{ padding: "0 10px" }}
onClick={async () => {
const text = t("revisions.confirm_delete_all");
if (note && await dialog.confirm(text)) {
await server.remove(`notes/${note.noteId}/revisions`);
setRevisions([]);
setCurrentRevision(undefined);
toast.showMessage(t("revisions.revisions_deleted"));
}
}}
/>
</>
)
header={note && (
<RevisionsMenu
note={note}
onRevisionSaved={() => {
setRefreshCounter(c => c + 1);
setCurrentRevision(undefined);
}}
onAllDeleted={() => {
setRevisions([]);
setCurrentRevision(undefined);
}}
hasRevisions={true}
/>
)}
sidebar={
<RevisionsList
revisions={revisions ?? []}
onSelect={(revisionId) => {
const correspondingRevision = (revisions ?? []).find((r) => r.revisionId === revisionId);
if (correspondingRevision) {
setCurrentRevision(correspondingRevision);
}
}}
currentRevision={currentRevision}
/>
}
footer={<RevisionFooter note={note} />}
footerStyle={{ paddingTop: 0, paddingBottom: 0 }}
onHidden={() => {
setShown(false);
setShowDiff(false);
setNote(undefined);
setCurrentRevision(undefined);
setRevisions(undefined);
}}
onHidden={onHidden}
show={shown}
>
<RevisionsList
revisions={revisions ?? []}
onSelect={(revisionId) => {
const correspondingRevision = (revisions ?? []).find((r) => r.revisionId === revisionId);
if (correspondingRevision) {
setCurrentRevision(correspondingRevision);
<RevisionToolbar
revisionItem={currentRevision}
showDiff={showDiff}
setShowDiff={setShowDiff}
setShown={setShown}
onRevisionDeleted={() => {
setRefreshCounter(c => c + 1);
setCurrentRevision(undefined);
}}
onDescriptionUpdated={(revisionId, description) => {
setRevisions(prev => prev?.map(r =>
r.revisionId === revisionId ? { ...r, description } : r
));
if (currentRevision?.revisionId === revisionId) {
setCurrentRevision({ ...currentRevision, description });
}
}}
currentRevision={currentRevision}
/>
<div className="revision-content-wrapper" style={{
flexGrow: "1",
marginInlineStart: "20px",
display: "flex",
flexDirection: "column",
maxWidth: "calc(100% - 150px)",
minWidth: 0
}}>
<div className="revision-content-wrapper">
<RevisionPreview
noteContent={noteContent}
revisionItem={currentRevision}
showDiff={showDiff}
setShown={setShown}
onRevisionDeleted={() => {
setRefreshCounter(c => c + 1);
setCurrentRevision(undefined);
}} />
/>
</div>
</Modal>
);
}
function RevisionsMenu({ note, onRevisionSaved, onAllDeleted, hasRevisions }: {
note: FNote,
onRevisionSaved: () => void,
onAllDeleted: () => void,
hasRevisions: boolean
}) {
let revisionsNumberLimit: number | string = parseInt(note.getLabelValue("versioningLimit") ?? "", 10);
if (!Number.isInteger(revisionsNumberLimit)) {
revisionsNumberLimit = options.getInt("revisionSnapshotNumberLimit") ?? 0;
}
if (revisionsNumberLimit === -1) {
revisionsNumberLimit = "∞";
}
return (
<Dropdown
text={<span className="bx bx-dots-horizontal-rounded" />}
hideToggleArrow
buttonClassName="custom-title-bar-button"
noSelectButtonStyle
buttonProps={{ title: t("revisions.menu_tooltip") }}
dropdownContainerClassName="mobile-bottom-menu"
dropdownOptions={{ popperConfig: { strategy: "fixed" } }}
>
<FormListItem
icon="bx bx-save"
onClick={async () => {
await server.post(`notes/${note.noteId}/revision`);
toast.showMessage(t("revisions.revision_saved"));
onRevisionSaved();
}}
>
{t("revisions.save_revision_now")}
</FormListItem>
<FormListItem
icon="bx bx-purchase-tag"
onClick={async () => {
const name = await dialog.prompt({
title: t("entrypoints.save-named-revision-title"),
message: t("entrypoints.save-named-revision-message"),
defaultValue: ""
});
if (name === null) return;
await server.post(`notes/${note.noteId}/revision`, { description: name || undefined });
toast.showMessage(t("revisions.revision_saved"));
onRevisionSaved();
}}
>
{t("revisions.save_named_revision")}
</FormListItem>
<FormDropdownDivider />
<FormListItem disabled className="revision-menu-header">
{t("revisions.snapshot_header")}
</FormListItem>
<FormListItem disabled>
{t("revisions.snapshot_interval_value", { seconds: options.getInt("revisionSnapshotTimeInterval") })}
</FormListItem>
<FormListItem disabled>
{t("revisions.snapshot_limit_value", { number: revisionsNumberLimit })}
</FormListItem>
<FormListItem
icon="bx bx-cog"
onClick={() => appContext.tabManager.openContextWithNote("_optionsOther", { activate: true })}
>
{t("revisions.settings")}
</FormListItem>
{hasRevisions && (
<>
<FormDropdownDivider />
<FormListItem
icon="bx bx-trash"
onClick={async () => {
if (await dialog.confirm(t("revisions.confirm_delete_all"))) {
await server.remove(`notes/${note.noteId}/revisions`);
onAllDeleted();
toast.showMessage(t("revisions.revisions_deleted"));
}
}}
>
{t("revisions.delete_all_revisions")}
</FormListItem>
</>
)}
</Dropdown>
);
}
const REVISION_SOURCE_ICONS: Record<string, string> = {
auto: "bx bx-time-five",
manual: "bx bx-save",
etapi: "bx bx-code-alt",
llm: "bx bx-bot",
restore: "bx bx-history"
};
const DEFAULT_REVISION_ICON = "bx bx-file";
function getRevisionSourceTitle(source?: string): string {
return t(`revisions.source_description_${source ?? "unknown"}`);
}
type DateGroup = "today" | "yesterday" | "this_week" | "this_month" | "older";
function getDateGroup(dateStr: string): DateGroup {
const date = dayjs(dateStr);
const now = dayjs();
if (date.isSame(now, "day")) return "today";
if (date.isSame(now.subtract(1, "day"), "day")) return "yesterday";
if (date.isSame(now, "week")) return "this_week";
if (date.isSame(now, "month")) return "this_month";
return "older";
}
function getDateGroupLabel(group: DateGroup, dateStr: string): string {
if (group === "older") return dayjs(dateStr).format("MMMM YYYY");
return t(`revisions.date_${group}`);
}
function formatRevisionDate(dateStr: string, group: DateGroup): string {
const date = dayjs(dateStr);
switch (group) {
case "today":
case "yesterday":
return date.format("HH:mm");
case "this_week":
return date.format("dddd · HH:mm");
default:
return date.isSame(dayjs(), "year")
? date.format("MMM D · HH:mm")
: date.format("MMM D, YYYY · HH:mm");
}
}
function buildRevisionTooltip(item: RevisionItem): string {
const dateLine = item.dateCreated
? `${dayjs(item.dateCreated).format("YYYY-MM-DD HH:mm")} (${dayjs(item.dateCreated).fromNow()})`
: "";
return [
item.description,
getRevisionSourceTitle(item.source),
dateLine,
item.contentLength && utils.formatSize(item.contentLength)
].filter(Boolean).join("\n");
}
function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) {
let lastGroup: DateGroup | "" = "";
return (
<FormList onSelect={onSelect} fullHeight wrapperClassName="revision-list">
{revisions.map((item) =>
<FormListItem
key={item.revisionId}
value={item.revisionId}
active={currentRevision && item.revisionId === currentRevision.revisionId}
>
{item.dateCreated && item.dateCreated.substr(0, 16)} ({item.contentLength && utils.formatSize(item.contentLength)})
</FormListItem>
)}
{revisions.map((item) => {
const group = item.dateCreated ? getDateGroup(item.dateCreated) : "" as DateGroup;
const showHeader = group !== lastGroup;
lastGroup = group;
return (
<Fragment key={item.revisionId}>
{showHeader && (
<div className="revision-group-header">{item.dateCreated ? getDateGroupLabel(group, item.dateCreated) : ""}</div>
)}
<FormListItem
key={item.revisionId}
value={item.revisionId}
icon={REVISION_SOURCE_ICONS[item.source ?? ""] ?? DEFAULT_REVISION_ICON}
title={buildRevisionTooltip(item)}
active={currentRevision && item.revisionId === currentRevision.revisionId}
>
<div>
<div className="revision-item-date">
{item.dateCreated && formatRevisionDate(item.dateCreated, group)}
</div>
{item.description && (
<div className="revision-item-description">
{item.description}
</div>
)}
</div>
</FormListItem>
</Fragment>
);
})}
</FormList>);
}
function RevisionPreview({noteContent, revisionItem, showDiff, setShown, onRevisionDeleted }: {
function RevisionToolbar({ revisionItem, showDiff, setShowDiff, setShown, onRevisionDeleted, onDescriptionUpdated }: {
revisionItem?: RevisionItem,
showDiff: boolean,
setShowDiff: Dispatch<StateUpdater<boolean>>,
setShown: Dispatch<StateUpdater<boolean>>,
onRevisionDeleted?: () => void,
onDescriptionUpdated?: (revisionId: string, description: string) => void,
}) {
const canShowDiff = ["text", "code", "mermaid"].includes(revisionItem?.type ?? "");
const canInteract = revisionItem && (!revisionItem.isProtected || protected_session_holder.isProtectedSessionAvailable());
const [ editingDescription, setEditingDescription ] = useState(false);
const [ descriptionDraft, setDescriptionDraft ] = useState("");
useEffect(() => {
setEditingDescription(false);
}, [revisionItem]);
return (
<div className="revision-toolbar">
{revisionItem && (
<div className="revision-toolbar-actions">
{canShowDiff && (
<FormToggle
currentValue={showDiff}
onChange={(newValue) => setShowDiff(newValue)}
switchOnName={t("revisions.highlight_changes")}
switchOffName={t("revisions.highlight_changes")}
/>
)}
<div style="flex-grow: 1" />
{canInteract && (
<>
<ActionButton
icon="bx bx-trash"
text={t("revisions.delete_button")}
onClick={async () => {
if (await dialog.confirm(t("revisions.confirm_delete"))) {
await server.remove(`revisions/${revisionItem.revisionId}`);
toast.showMessage(t("revisions.revision_deleted"));
onRevisionDeleted?.();
}
}} frame />
<ActionButton
icon="bx bx-download"
text={t("revisions.download_button")}
onClick={() => {
if (revisionItem.revisionId) {
open.downloadRevision(revisionItem.noteId, revisionItem.revisionId);
}
}}
frame />
<Button
icon="bx bx-history"
text={t("revisions.restore_button")}
onClick={async () => {
if (await dialog.confirm(t("revisions.confirm_restore"))) {
await server.post(`revisions/${revisionItem.revisionId}/restore`);
setShown(false);
toast.showMessage(t("revisions.revision_restored"));
}
}}/>
</>
)}
</div>
)}
{revisionItem && (
<RevisionDescription
revisionItem={revisionItem}
editing={editingDescription}
draft={descriptionDraft}
onEdit={() => {
setDescriptionDraft(revisionItem.description || "");
setEditingDescription(true);
}}
onDraftChange={setDescriptionDraft}
onSave={async () => {
await server.patch(`revisions/${revisionItem.revisionId}`, { description: descriptionDraft });
setEditingDescription(false);
toast.showMessage(t("revisions.description_updated"));
onDescriptionUpdated?.(revisionItem.revisionId!, descriptionDraft);
}}
onCancel={() => setEditingDescription(false)}
/>
)}
</div>
);
}
function RevisionPreview({noteContent, revisionItem, showDiff }: {
noteContent?: string,
revisionItem?: RevisionItem,
showDiff: boolean,
setShown: Dispatch<StateUpdater<boolean>>,
onRevisionDeleted?: () => void
}) {
const [ fullRevision, setFullRevision ] = useState<RevisionPojo>();
@@ -174,54 +454,60 @@ function RevisionPreview({noteContent, revisionItem, showDiff, setShown, onRevis
}, [revisionItem]);
return (
<>
<div style="flex-grow: 0; display: flex; justify-content: space-between;">
<h3 className="revision-title" style="margin: 3px; flex-grow: 100;">{revisionItem?.title ?? t("revisions.no_revisions")}</h3>
{(revisionItem && <div className="revision-title-buttons">
{(!revisionItem.isProtected || protected_session_holder.isProtectedSessionAvailable()) &&
<>
<Button
icon="bx bx-history"
text={t("revisions.restore_button")}
onClick={async () => {
if (await dialog.confirm(t("revisions.confirm_restore"))) {
await server.post(`revisions/${revisionItem.revisionId}/restore`);
setShown(false);
toast.showMessage(t("revisions.revision_restored"));
}
}}/>
&nbsp;
<Button
icon="bx bx-trash"
text={t("revisions.delete_button")}
onClick={async () => {
if (await dialog.confirm(t("revisions.confirm_delete"))) {
await server.remove(`revisions/${revisionItem.revisionId}`);
toast.showMessage(t("revisions.revision_deleted"));
onRevisionDeleted?.();
}
}} />
&nbsp;
<Button
kind="primary"
icon="bx bx-download"
text={t("revisions.download_button")}
onClick={() => {
if (revisionItem.revisionId) {
open.downloadRevision(revisionItem.noteId, revisionItem.revisionId);}
}
}/>
</>
}
</div>)}
<div
className={clsx("revision-content use-tn-links selectable-text", `type-${revisionItem?.type}`)}
style={{ wordBreak: "break-word" }}
>
<h3 className="revision-title">{revisionItem?.title}</h3>
<RevisionContent noteContent={noteContent} revisionItem={revisionItem} fullRevision={fullRevision} showDiff={showDiff}/>
</div>
);
}
function RevisionDescription({ revisionItem, editing, draft, onEdit, onDraftChange, onSave, onCancel }: {
revisionItem: RevisionItem,
editing: boolean,
draft: string,
onEdit: () => void,
onDraftChange: (val: string) => void,
onSave: () => void,
onCancel: () => void
}) {
if (editing) {
return (
<div className="revision-description-editor">
<span className="bx bx-purchase-tag revision-description-icon" />
<input
type="text"
className="form-control form-control-sm"
placeholder={t("revisions.description_placeholder")}
value={draft}
onInput={(e) => onDraftChange((e.target as HTMLInputElement).value)}
onKeyDown={(e) => {
if (e.key === "Enter") onSave();
if (e.key === "Escape") onCancel();
}}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
/>
<ActionButton icon="bx bx-check" text={t("common.save")} onClick={onSave} />
<ActionButton icon="bx bx-x" text={t("common.cancel")} onClick={onCancel} />
</div>
<div
className={clsx("revision-content use-tn-links selectable-text", `type-${revisionItem?.type}`)}
style={{ overflow: "auto", wordBreak: "break-word" }}
>
<RevisionContent noteContent={noteContent} revisionItem={revisionItem} fullRevision={fullRevision} showDiff={showDiff}/>
</div>
</>
);
}
return (
<div className="revision-description-display">
<span className="bx bx-purchase-tag revision-description-icon" />
<span className={clsx("revision-description-text", { empty: !revisionItem.description })}>
{revisionItem.description || t("revisions.description_placeholder")}
</span>
<ActionButton
icon="bx bx-edit-alt"
text={t("revisions.edit_description")}
onClick={onEdit}
/>
</div>
);
}
@@ -250,7 +536,7 @@ function RevisionContent({ noteContent, revisionItem, fullRevision, showDiff }:
case "text":
return <RevisionContentText content={content} />;
case "code":
return <pre style={CODE_STYLE}>{content}</pre>;
return <div className="revision-diff-code">{content}</div>;
case "image":
switch (revisionItem.mime) {
case "image/svg+xml": {
@@ -299,69 +585,33 @@ function RevisionContentDiff({ noteContent, itemContent, itemType }: {
itemContent: string | Uint8Array | undefined,
itemType: string
}) {
const contentRef = useRef<HTMLDivElement>(null);
if (!noteContent || typeof itemContent !== "string") {
return <div className="revision-diff-content">{t("revisions.diff_not_available")}</div>;
}
useEffect(() => {
if (!noteContent || typeof itemContent !== "string") {
if (contentRef.current) {
contentRef.current.textContent = t("revisions.diff_not_available");
}
return;
}
let processedNoteContent = noteContent;
let processedItemContent = itemContent;
if (itemType === "text") {
processedNoteContent = utils.formatHtml(noteContent);
processedItemContent = utils.formatHtml(itemContent);
}
const diff = diffWords(processedNoteContent, processedItemContent);
const diffHtml = diff.map(part => {
let diffHtml: string;
if (itemType === "text") {
// Use proper HTML-aware diff for rich text content
diffHtml = HtmlDiff.execute(noteContent, itemContent);
} else {
// Use word diff for code/mermaid (plain text)
const diff = diffWords(noteContent, itemContent);
diffHtml = diff.map(part => {
if (part.added) {
return `<span class="revision-diff-added">${utils.escapeHtml(part.value)}</span>`;
} else if (part.removed) {
return `<span class="revision-diff-removed">${utils.escapeHtml(part.value)}</span>`;
}
return utils.escapeHtml(part.value);
}).join("");
}
if (contentRef.current) {
contentRef.current.innerHTML = diffHtml;
}
}, [noteContent, itemContent, itemType]);
return <div ref={contentRef} className="ck-content" style={{ whiteSpace: "pre-wrap" }} />;
return <SanitizedHtml
className={clsx("revision-diff-content", itemType === "text" ? "ck-content" : "revision-diff-code")}
html={diffHtml}
/>;
}
function RevisionFooter({ note }: { note?: FNote }) {
if (!note) {
return <></>;
}
let revisionsNumberLimit: number | string = parseInt(note?.getLabelValue("versioningLimit") ?? "", 10);
if (!Number.isInteger(revisionsNumberLimit)) {
revisionsNumberLimit = options.getInt("revisionSnapshotNumberLimit") ?? 0;
}
if (revisionsNumberLimit === -1) {
revisionsNumberLimit = "∞";
}
return <>
<span class="revisions-snapshot-interval flex-grow-1 my-0 py-0">
{t("revisions.snapshot_interval", { seconds: options.getInt("revisionSnapshotTimeInterval") })}
</span>
<span class="maximum-revisions-for-current-note flex-grow-1 my-0 py-0">
{t("revisions.maximum_revisions", { number: revisionsNumberLimit })}
</span>
<ActionButton
icon="bx bx-cog" text={t("revisions.settings")}
onClick={() => appContext.tabManager.openContextWithNote("_optionsOther", { activate: true })}
/>
</>;
}
function FilePreview({ revisionItem, fullRevision }: { revisionItem: RevisionItem, fullRevision: RevisionPojo }) {
return (

View File

@@ -195,7 +195,9 @@ export default class FindWidget extends NoteContextAwareWidget {
return;
}
if (!SUPPORTED_NOTE_TYPES.includes(this.note?.type ?? "")) {
const isSourceView = this.noteContext?.viewScope?.viewMode === "source";
if (!isSourceView && !SUPPORTED_NOTE_TYPES.includes(this.note?.type ?? "")) {
return;
}
@@ -204,7 +206,7 @@ export default class FindWidget extends NoteContextAwareWidget {
const isReadOnly = await this.noteContext?.isReadOnly();
let selectedText = "";
if (this.note?.type === "code" && this.noteContext) {
if ((this.note?.type === "code" || isSourceView) && this.noteContext) {
const codeEditor = await this.noteContext.getCodeEditor();
selectedText = codeEditor.getSelectedText();
} else {
@@ -249,6 +251,11 @@ export default class FindWidget extends NoteContextAwareWidget {
}
async getHandler() {
// In source view, all note types render via a read-only CodeMirror editor.
if (this.noteContext?.viewScope?.viewMode === "source") {
return this.codeHandler;
}
switch (this.note?.type) {
case "render":
return this.htmlHandler;
@@ -362,7 +369,9 @@ export default class FindWidget extends NoteContextAwareWidget {
}
isEnabled() {
return super.isEnabled() && SUPPORTED_NOTE_TYPES.includes(this.note?.type ?? "");
return super.isEnabled()
&& (SUPPORTED_NOTE_TYPES.includes(this.note?.type ?? "")
|| this.noteContext?.viewScope?.viewMode === "source");
}
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {

View File

@@ -63,7 +63,7 @@ export default class FindInText {
const findResultElement = editorEl?.querySelectorAll(".ck-find-result");
const scrollingContainer = editorEl?.closest('.scrolling-container');
const containerTop = scrollingContainer?.getBoundingClientRect().top ?? 0;
const closestIndex = Array.from(findResultElement ?? []).findIndex((el) => el.getBoundingClientRect().top >= containerTop);
const closestIndex = Array.from(findResultElement ?? []).findIndex((el: Element) => el.getBoundingClientRect().top >= containerTop);
currentFound = closestIndex >= 0 ? closestIndex : 0;
}
}

View File

@@ -10,11 +10,11 @@ import { useChildNotes, useNote, useNoteIcon, useNoteLabelBoolean } from "../rea
import NoteLink from "../react/NoteLink";
import ResponsiveContainer from "../react/ResponsiveContainer";
import { CustomNoteLauncher, launchCustomNoteLauncher } from "./GenericButtons";
import { LaunchBarContext, LaunchBarDropdownButton, useLauncherIconAndTitle } from "./launch_bar_widgets";
import { LaunchBarContext, LaunchBarDropdownButton, launcherContextMenuHandler, LauncherNoteProps, useLauncherIconAndTitle } from "./launch_bar_widgets";
const PARENT_NOTE_ID = "_lbBookmarks";
export default function BookmarkButtons() {
export default function BookmarkButtons({ launcherNote }: LauncherNoteProps) {
const { isHorizontalLayout } = useContext(LaunchBarContext);
const style = useMemo<CSSProperties>(() => ({
display: "flex",
@@ -22,20 +22,27 @@ export default function BookmarkButtons() {
contain: "none"
}), [ isHorizontalLayout ]);
const childNotes = useChildNotes(PARENT_NOTE_ID);
const bookmarks = childNotes?.map(childNote => <SingleBookmark key={childNote.noteId} note={childNote} />);
const showContextMenu = launcherContextMenuHandler(launcherNote);
return (
<ResponsiveContainer
desktop={
<div style={style}>
{childNotes?.map(childNote => <SingleBookmark key={childNote.noteId} note={childNote} />)}
<div
style={style}
// Only trigger on empty container area; individual bookmark buttons handle their own context menu.
onContextMenu={(e) => e.target === e.currentTarget && showContextMenu?.(e)}
>
{bookmarks}
</div>
}
mobile={
<LaunchBarDropdownButton
launcherNote={launcherNote}
icon="bx bx-bookmark"
title={t("bookmark_buttons.bookmarks")}
>
{childNotes?.map(childNote => <SingleBookmark key={childNote.noteId} note={childNote} />)}
{bookmarks}
</LaunchBarDropdownButton>
}
/>
@@ -90,6 +97,7 @@ function BookmarkFolder({ note }: { note: FNote }) {
return (
<LaunchBarDropdownButton
launcherNote={note}
icon={icon}
title={title}
>

View File

@@ -58,6 +58,7 @@ export default function CalendarWidget({ launcherNote }: LauncherNoteProps) {
return (
<LaunchBarDropdownButton
launcherNote={launcherNote}
icon={icon} title={title}
onShown={async () => {
const dateNote = appContext.tabManager.getActiveContextNote()?.getOwnedLabelValue("dateNote");

View File

@@ -1,7 +1,8 @@
import { useCallback } from "preact/hooks";
import appContext from "../../components/app_context";
import appContext, { CommandNames } from "../../components/app_context";
import FNote from "../../entities/fnote";
import { showLauncherContextMenu } from "../../menus/launcher_button_context_menu";
import link_context_menu from "../../menus/link_context_menu";
import { isCtrlKey } from "../../services/utils";
import { useGlobalShortcut, useNoteLabel } from "../react/hooks";
@@ -13,7 +14,7 @@ export function CustomNoteLauncher(props: {
getHoistedNoteId?: (launcherNote: FNote) => string | null;
keyboardShortcut?: string;
}) {
const { launcherNote, getTargetNoteId } = props;
const { launcherNote, getTargetNoteId, getHoistedNoteId } = props;
const { icon, title } = useLauncherIconAndTitle(launcherNote);
const launch = useCallback(async (evt: MouseEvent | KeyboardEvent) => {
@@ -31,11 +32,20 @@ export function CustomNoteLauncher(props: {
onClick={launch}
onAuxClick={launch}
onContextMenu={async evt => {
// Must preventDefault synchronously — awaiting getTargetNoteId first would let the
// native browser context menu open before showLauncherContextMenu gets a chance to.
evt.preventDefault();
const targetNoteId = await getTargetNoteId(launcherNote);
if (targetNoteId) {
link_context_menu.openContextMenu(targetNoteId, evt);
}
const hoistedNoteId = getHoistedNoteId?.(launcherNote) ?? null;
const linkItems = targetNoteId ? link_context_menu.getItems(evt) : [];
await showLauncherContextMenu<CommandNames>(launcherNote, evt, {
extraItems: linkItems,
onCommand: (command) => {
if (command && targetNoteId) {
link_context_menu.handleLinkContextMenuItem(command, evt, targetNoteId, {}, hoistedNoteId);
}
}
});
}}
/>
);

View File

@@ -3,6 +3,7 @@ import { useMemo } from "preact/hooks";
import FNote from "../../entities/fnote";
import contextMenu, { MenuCommandItem } from "../../menus/context_menu";
import { showLauncherContextMenu } from "../../menus/launcher_button_context_menu";
import froca from "../../services/froca";
import link from "../../services/link";
import tree from "../../services/tree";
@@ -25,46 +26,63 @@ export default function HistoryNavigationButton({ launcherNote, command }: Histo
icon={icon}
text={title}
triggerCommand={command}
onContextMenu={webContents ? handleHistoryContextMenu(webContents) : undefined}
onContextMenu={async (e) => {
// Prevent the native menu synchronously before awaiting history items.
e.preventDefault();
const items = webContents ? await getHistoryItems(webContents) : [];
showLauncherContextMenu<string>(launcherNote, e, {
extraItems: items,
onCommand: (cmd) => {
if (cmd && webContents) {
webContents.navigationHistory.goToIndex(parseInt(cmd, 10));
}
}
});
}}
/>
);
}
async function getHistoryItems(webContents: WebContents): Promise<MenuCommandItem<string>[]> {
if (webContents.navigationHistory.length() < 2) return [];
let items: MenuCommandItem<string>[] = [];
const history = webContents.navigationHistory.getAllEntries();
const activeIndex = webContents.navigationHistory.getActiveIndex();
for (const idx in history) {
const { noteId, notePath } = link.parseNavigationStateFromUrl(history[idx].url);
if (!noteId || !notePath) continue;
const title = await tree.getNotePathTitle(notePath);
const index = parseInt(idx, 10);
const note = froca.getNoteFromCache(noteId);
items.push({
title,
command: idx,
checked: index === activeIndex,
enabled: index !== activeIndex,
uiIcon: note?.getIcon()
});
}
items.reverse();
if (items.length > HISTORY_LIMIT) {
items = items.slice(0, HISTORY_LIMIT);
}
return items;
}
export function handleHistoryContextMenu(webContents: WebContents) {
return async (e: MouseEvent) => {
e.preventDefault();
if (!webContents || webContents.navigationHistory.length() < 2) {
return;
}
let items: MenuCommandItem<string>[] = [];
const history = webContents.navigationHistory.getAllEntries();
const activeIndex = webContents.navigationHistory.getActiveIndex();
for (const idx in history) {
const { noteId, notePath } = link.parseNavigationStateFromUrl(history[idx].url);
if (!noteId || !notePath) continue;
const title = await tree.getNotePathTitle(notePath);
const index = parseInt(idx, 10);
const note = froca.getNoteFromCache(noteId);
items.push({
title,
command: idx,
checked: index === activeIndex,
enabled: index !== activeIndex,
uiIcon: note?.getIcon()
});
}
items.reverse();
if (items.length > HISTORY_LIMIT) {
items = items.slice(0, HISTORY_LIMIT);
}
const items = await getHistoryItems(webContents);
if (items.length === 0) return;
contextMenu.show({
x: e.pageX,

View File

@@ -83,13 +83,13 @@ function initBuiltinWidget(note: FNote, isHorizontalLayout: boolean) {
const baseSize = parseInt(note.getLabelValue("baseSize") || "40");
const growthFactor = parseInt(note.getLabelValue("growthFactor") || "100");
return <SpacerWidget baseSize={baseSize} growthFactor={growthFactor} />;
return <SpacerWidget launcherNote={note} baseSize={baseSize} growthFactor={growthFactor} />;
case "bookmarks":
return <BookmarkButtons />;
return <BookmarkButtons launcherNote={note} />;
case "protectedSession":
return <ProtectedSessionStatusWidget />;
return <ProtectedSessionStatusWidget launcherNote={note} />;
case "syncStatus":
return <SyncStatus />;
return <SyncStatus launcherNote={note} />;
case "backInHistoryButton":
return <HistoryNavigationButton launcherNote={note} command="backInNoteHistory" />;
case "forwardInHistoryButton":
@@ -97,11 +97,11 @@ function initBuiltinWidget(note: FNote, isHorizontalLayout: boolean) {
case "todayInJournal":
return <TodayLauncher launcherNote={note} />;
case "quickSearch":
return <QuickSearchLauncherWidget />;
return <QuickSearchLauncherWidget launcherNote={note} />;
case "mobileTabSwitcher":
return <TabSwitcher />;
return <TabSwitcher launcherNote={note} />;
case "sidebarChat":
return isExperimentalFeatureEnabled("llm") ? <SidebarChatButton /> : undefined;
return isExperimentalFeatureEnabled("llm") ? <SidebarChatButton launcherNote={note} /> : undefined;
default:
console.warn(`Unrecognized builtin widget ${builtinWidget} for launcher ${note.noteId} "${note.title}"`);
}

Some files were not shown because too many files have changed in this diff Show More