Compare commits

..
89 Commits
Author SHA1 Message Date
LudyandGitHub 9b0b141074 Merge branch 'main' into AppImage_fix 2026-01-09 20:42:05 +01:00
Ludy87 42e484e30a Update tauri.conf.json 2026-01-09 14:39:56 +01:00
LudyandGitHub 9fb22d66f3 Merge branch 'main' into AppImage_fix 2026-01-09 14:36:48 +01:00
Ludy87 22daafcba3 Update workflows and add new frontend dependencies 2026-01-09 14:34:56 +01:00
LudyandGitHub 31410f42f8 Merge branch 'main' into AppImage_fix 2025-12-29 20:41:19 +01:00
Ludy87 4ba84ec35f Remove license field from Cargo.toml
Cleared the license field in the Cargo.toml for the Stirling-PDF desktop application. This may be to update or clarify the project's licensing information.
2025-12-12 20:46:26 +01:00
LudyandGitHub f8f541af8d Merge branch 'main' into AppImage_fix 2025-12-12 20:44:43 +01:00
LudyandGitHub 9ed16687fa Merge branch 'main' into AppImage_fix 2025-12-11 10:23:31 +01:00
Ludy87 dbb5463d89 Enhance multiOS and Tauri build workflows
Adds macOS DMG tooling installation and dependency checks to multiOSReleases workflow. Improves artifact handling for RPM packages and unknown platforms. Updates Tauri build workflow for consistency in formatting and dependency installation steps.
2025-12-06 12:26:11 +01:00
Ludy87 7b05e57a6d Add create-dmg installation step for macOS builds
Adds a step to install the 'create-dmg' tool via Homebrew when building on macOS platforms. This ensures DMG creation tooling is available for packaging macOS builds.
2025-12-06 11:55:57 +01:00
Anthony StirlingandGitHub 9df9c8caf2 Merge branch 'main' into AppImage_fix 2025-12-06 00:18:57 +00:00
LudyandGitHub d9e0970bd9 Merge branch 'main' into AppImage_fix 2025-12-04 20:32:08 +01:00
Ludy87 2a36a3c585 Enable native keyring features for Apple and Windows
Updated the keyring dependency in Cargo.toml to enable 'apple-native' and 'windows-native' features, improving native integration on those platforms. Cargo.lock updated to reflect new and updated dependencies.
2025-12-04 20:30:54 +01:00
Ludy87 9fab426143 Update dependencies and CI build matrix
Updated several Rust and JavaScript dependencies to their latest versions, including @tauri-apps/api, and made corresponding changes in Cargo.lock and package-lock.json. The Tauri build GitHub Actions workflow was also updated to remove duplicate macOS build targets and streamline the build matrix.
2025-12-04 20:26:24 +01:00
Ludy87 ac88ac077f Update JDK version to 21 in tauri-build workflow
The GitHub Actions workflow now sets up JDK 21 instead of JDK 17 to ensure compatibility with newer Java features and dependencies.
2025-12-04 18:18:24 +01:00
Ludy87 579ea8948c Update JDK version to 21 in CI workflow
Changed the Java setup steps in multiOSReleases.yml to use JDK 21 instead of JDK 17 for building and testing. This ensures compatibility with newer Java features and aligns with updated project requirements.
2025-12-04 18:16:13 +01:00
LudyandGitHub b5c0ab3b11 Merge branch 'main' into AppImage_fix 2025-12-04 11:33:39 +01:00
LudyandGitHub a4dba200e0 Merge branch 'V2' into AppImage_fix 2025-12-03 05:19:42 +01:00
Ludy87 5412326b49 Update dependencies in package-lock.json
Added new optional dependencies including @emnapi/core, @emnapi/runtime, @emnapi/wasi-threads, and @napi-rs/canvas with platform-specific builds. Updated and expanded esbuild platform support packages and refreshed several ESLint-related dependencies.
2025-12-02 15:24:16 +01:00
LudyandGitHub b57a6d3354 Merge branch 'V2' into AppImage_fix 2025-12-02 15:15:28 +01:00
Ludy87 b995a7f413 Update release workflows for RPM and signing logic
Added RPM package to multiOS release artifacts. Improved Windows signing logic in tauri-build workflow with detailed conditions for enabling signing.
2025-12-02 15:07:44 +01:00
Ludy87 e20df4ca22 Automate GPG key cleanup in AppImage build
Adds steps to export the GPG fingerprint to the environment and clean up the temporary GPG key after building the AppImage on Ubuntu. Also fixes heredoc usage for key generation parameters.
2025-12-02 14:47:23 +01:00
Ludy87 9b960f2e28 Improve error handling and GPG key cleanup in CI workflows
Adds error handling to wget commands for package downloads in multiOSReleases.yml and tauri-build.yml to ensure the workflow fails on download errors. Updates GPG key generation to export the fingerprint and introduces a cleanup step to remove temporary GPG keys after use in tauri-build.yml.
2025-12-02 14:46:23 +01:00
Ludy87 6a8183b0fd Bump version to 2.0.3 and add GPG key generation for CI
Updated project version to 2.0.3 in build.gradle, tauri.conf.json, and test configs. Added a step in the multiOSReleases GitHub workflow to generate a temporary GPG key for AppImage signing on Ubuntu CI builds.
2025-12-02 12:07:14 +01:00
Ludy87 b4746fe377 Update CI workflows for improved Linux packaging and concurrency
Added concurrency control to multiOSReleases workflow to cancel in-progress jobs on new triggers. Expanded Linux build matrix to include AppImage, DEB, and RPM targets. Updated Ubuntu dependency installation for better compatibility with Tauri v2 and packaging formats. Changed JDK version from 21 to 17. Added step-security/harden-runner to tauri-build workflow for enhanced security.
2025-12-02 10:52:18 +01:00
Ludy87 378696a140 Restrict Ubuntu steps to AppImage build only
Updated workflow conditions so that making libjvm discoverable and generating a temporary GPG key only run for the linux-x86_64-appimage build on Ubuntu 22.04, instead of all Ubuntu builds.
2025-12-01 22:17:02 +01:00
Ludy87 460cc827a6 Update Ubuntu dependency installation in CI workflow
Refines the dependency installation steps in the tauri-build GitHub Actions workflow. Adds conditional logic to separate AppImage-specific installs and updates the list of packages for Tauri v2 compatibility, including detailed comments explaining each dependency.
2025-12-01 22:09:01 +01:00
Ludy87 db2e93d285 Update tauri.conf.json 2025-12-01 22:04:23 +01:00
Ludy87 6ca248d68e Fix Tauri build workflow argument and platform handling
Uncomments the 'args' parameter for the Tauri build step to enable passing build arguments. Refines platform-specific artifact copying logic to handle AppImage files for Ubuntu and adds an explicit message for unknown platforms.
2025-12-01 22:02:36 +01:00
Ludy87 8a22f2e52a Simplify AppImage artifact processing in CI workflow
Removed FUSE installation and custom AppImage extraction, modification, and repackaging steps from the tauri-build GitHub Actions workflow. Now, AppImage files are simply copied to the dist directory, streamlining the build process for linux-x86_64-appimage targets.
2025-12-01 21:54:36 +01:00
Ludy87 31f5b73a05 Update tauri-build.yml 2025-12-01 21:41:56 +01:00
Ludy87 0dab986c3d Update tauri-build.yml 2025-12-01 21:26:45 +01:00
Ludy87 894293d378 Update tauri.conf.json 2025-12-01 21:15:10 +01:00
Ludy87 178474d254 Update tauri-build.yml 2025-12-01 20:46:30 +01:00
Ludy87 a8773cb769 Update tauri-build.yml 2025-12-01 20:43:23 +01:00
Ludy87 2096ae3a1f Update tauri-build.yml 2025-12-01 20:30:51 +01:00
Ludy87 bc40a856d8 Update tauri-build.yml 2025-12-01 20:30:20 +01:00
Ludy87 61093191fb Update tauri-build.yml 2025-12-01 20:13:15 +01:00
Ludy87 521c308e63 Update tauri-build.yml 2025-12-01 20:10:37 +01:00
Ludy87 e7207475ee Update tauri-build.yml 2025-12-01 20:09:28 +01:00
Ludy87 6c37815157 Update tauri-build.yml 2025-12-01 20:08:05 +01:00
Ludy87 3b5f607cbf Update tauri-build.yml 2025-12-01 19:34:11 +01:00
Ludy87 388bb439d7 Improve Linux WebKit fallback configuration
Updated the GitHub Actions workflow to simplify package installation for WebKit dependencies on Ubuntu and removed explicit version pinning. Enhanced the Linux WebKit configuration in Rust to apply and log multiple environment variable fallbacks for better handling of EGL issues.
2025-12-01 18:47:05 +01:00
Ludy87 279a307153 Update tauri-build.yml 2025-12-01 18:35:15 +01:00
Ludy87 a20fb83d31 Update tauri-build.yml 2025-12-01 18:23:12 +01:00
Ludy87 c1f569b2d5 Enable software rendering for WebKit on Linux
Adds a function to set WEBKIT_DISABLE_COMPOSITING_MODE on Linux if not already set, enabling software rendering to avoid EGL issues. Logs a message when the environment variable is configured.
2025-12-01 17:59:01 +01:00
Ludy87 bfda167b89 Update stirling-pdf.desktop 2025-12-01 17:17:36 +01:00
Ludy87 1090779081 Remove WebKit helper binaries copy step from CI
Eliminates the step that copies WebKit helper binaries for AppImage builds on Ubuntu 22.04 from the tauri-build GitHub Actions workflow. This may be due to changes in build requirements or improved packaging.
2025-12-01 16:40:24 +01:00
Ludy87 edee6529ff Update AppImage build to copy WebKit helper binaries
Adds a workflow step to copy WebKit2GTK helper binaries for AppImage builds on Ubuntu 22.04. Removes explicit file mapping from tauri.conf.json, relying on the workflow to provide required binaries.
2025-12-01 16:37:29 +01:00
Ludy87 8b81acf105 Update tauri.conf.json 2025-12-01 16:27:46 +01:00
Ludy87 2969385844 Remove license-checker and update Tauri config
Removed the 'license-checker' dev dependency from package.json and package-lock.json. Updated tauri.conf.json to explicitly include WebKit process binaries in the AppImage build. Also enabled Gradle cache in the GitHub Actions workflow and removed the AppImage functional test step.
2025-12-01 16:03:35 +01:00
Ludy87 b8dfb835da Update tauri-build.yml 2025-12-01 15:46:11 +01:00
Ludy87 86d95d3fad Update tauri-build.yml 2025-12-01 15:42:28 +01:00
LudyandGitHub e0ce76201a Simplify matrix echo commands in tauri-build.yml 2025-12-01 12:08:07 +01:00
LudyandGitHub 7c8ff1820f Refactor matrix generation for build platforms 2025-12-01 12:02:51 +01:00
LudyandGitHub fb06028a5a Generate GPG key for AppImage signing
Add step to generate temporary GPG key for AppImage signing on Ubuntu 22.04.
2025-12-01 06:11:47 +01:00
LudyandGitHub 649b426e4a Remove GPG key generation from build workflow
Removed temporary GPG key generation step for AppImage.
2025-12-01 03:22:44 +01:00
Ludy87 0227274a03 Update tauri-build.yml 2025-11-30 23:03:30 +01:00
Ludy87 49b79b5e66 Update tauri-build.yml 2025-11-30 22:50:01 +01:00
Ludy87 793d25725a Update tauri-build.yml 2025-11-30 22:40:56 +01:00
Ludy87 b0311a6325 Update tauri-build.yml 2025-11-30 22:39:23 +01:00
Ludy87 709280895c Update tauri-build.yml 2025-11-30 22:25:40 +01:00
Ludy87 700ef3eefc Update tauri-build.yml 2025-11-30 22:09:04 +01:00
Ludy87 baea057050 Add --no-sign flag to Linux build in CI
Appends the --no-sign flag to the Linux build arguments in the GitHub Actions workflow to disable signing during CI builds for x86_64-unknown-linux-gnu targets.
2025-11-30 22:02:49 +01:00
Ludy87 0cb6ae1270 Update tauri build workflow and frontend dependencies
Modified tauri-build.yml to conditionally set APPIMAGETOOL_SIGN_PASSPHRASE only on main branch. Removed unused dev dependencies from frontend/package.json and package-lock.json, including madge and related packages.
2025-11-30 21:46:11 +01:00
Ludy87 0e292a4d07 Add step to link libjvm for Ubuntu builds
Introduces a workflow step to create a symlink for libjvm.so on Ubuntu 22.04, ensuring the Java backend build can discover the JVM library. This addresses potential issues with library discovery during CI builds.
2025-11-30 21:25:39 +01:00
Ludy87 c2648e20b7 Update tauri-build.yml 2025-11-30 21:12:18 +01:00
Ludy87 08bccc4607 Update tauri-build.yml 2025-11-30 20:53:40 +01:00
Ludy87 71d1e5e2c4 Update tauri-build.yml 2025-11-30 20:53:10 +01:00
Ludy87 bf7987b483 Update Tauri CLI and dependencies, adjust build workflow
Upgrades @tauri-apps/cli to v2.9.5 and updates related optional dependencies in package-lock.json. Also updates js-yaml and glob packages. The tauri-build GitHub workflow is modified to streamline and correct the list of required Ubuntu packages for builds.
2025-11-30 20:42:11 +01:00
Ludy87 914e6c0129 Update tauri-build.yml 2025-11-30 20:31:21 +01:00
Ludy87 e4e9bba413 Update tauri-build.yml 2025-11-30 20:23:11 +01:00
Ludy87 4f66948ed6 Add libglib2.0-dev to Ubuntu build dependencies
Included libglib2.0-dev in the list of packages installed for Ubuntu builds to ensure all required libraries are available for Tauri application compilation.
2025-11-30 19:45:14 +01:00
Ludy87 7b726496c7 Update tauri-build.yml 2025-11-30 18:56:27 +01:00
Ludy87 93c11d1702 Refactor Linux build steps in Tauri workflow
Linux build matrix no longer passes bundle arguments directly; instead, a dedicated step for building AppImage, deb, and rpm is added for the Ubuntu platform. Other platforms use the general Tauri build step, improving workflow clarity and separation of build logic.
2025-11-30 18:50:26 +01:00
Ludy87 1bfe37f2fe Fix typo in tauri-build workflow args
Replaces '--buildes' with '--bundles' in the matrix configuration for Linux builds in the tauri-build GitHub Actions workflow to ensure correct argument usage.
2025-11-30 18:23:11 +01:00
Ludy87 5099dc049e Update build workflow and bundle targets
Adds explicit build targets (appimage, deb, rpm) for Linux in the GitHub Actions workflow and expands Tauri bundle targets to include deb, rpm, dmg, app, and msi. Removes JRE caching step to always rebuild the custom JRE during CI.
2025-11-30 18:18:33 +01:00
Ludy87 b9d71cdef0 Update tauri-build.yml 2025-11-30 17:54:36 +01:00
Ludy87 f2dfc30f80 Update tauri.conf.json 2025-11-30 17:49:09 +01:00
Ludy87 98fdf1a01b Update tauri-build.yml 2025-11-30 17:48:58 +01:00
Ludy87 d5453a06cd Update tauri-build.yml 2025-11-30 17:18:58 +01:00
Ludy87 6009310c69 Update tauri-build.yml 2025-11-30 17:17:19 +01:00
Ludy87 b0fe3877a9 Update tauri-build.yml 2025-11-30 17:17:03 +01:00
Ludy87 640aa861d4 Refactor JRE build and dependencies in CI workflows 2025-11-30 17:12:17 +01:00
Ludy87 2f33d0318e Update multiOSReleases.yml 2025-11-30 16:51:05 +01:00
Ludy87 4634ccb25d Update multiOSReleases.yml 2025-11-30 16:22:50 +01:00
Ludy87 153faec52a Update app version to 2.0.2 and fix workflow dependencies
Bump app version from 2.0.0 to 2.0.2 in tauri config and simulation configs. Add missing 'linuxdeploy' package and fix typo in GitHub Actions workflow dependencies for Ubuntu builds.
2025-11-30 15:06:10 +01:00
Ludy87 f06f6d30d1 Update Ubuntu dependencies in CI workflow
Added desktop-file-utils and libglib2.0-bin to the list of packages installed for Ubuntu-22.04 in the multiOSReleases workflow to ensure required tools are available for builds.
2025-11-30 14:39:37 +01:00
Ludy87 ce42c3e41a Add AppImage to Tauri bundle targets 2025-11-30 12:30:57 +01:00
147 changed files with 4826 additions and 23758 deletions
+1 -3
View File
@@ -13,8 +13,6 @@
"reecebrowne",
"DarioGii",
"ConnorYoh",
"EthanHealy01",
"jbrunton96",
"balazs-szucs"
"EthanHealy01"
]
}
+1 -1
View File
@@ -6,7 +6,7 @@
version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directories:
directories:
- "/" # Location of package manifests
- "/app/common"
- "/app/core"
+1 -1
View File
@@ -200,4 +200,4 @@
from_name: "tauri"
- name: "license-review-required"
color: "EDEDED"
description: "This PR requires a license review"
description: "This PR requires a license review"
+32 -51
View File
@@ -11,16 +11,13 @@ adjusting the format.
Usage:
python check_language_toml.py --reference-file <path_to_reference_file> --branch <branch_name> [--actor <actor_name>] [--files <list_of_changed_files>]
"""
# Sample for Windows:
# python .github/scripts/check_language_toml.py --reference-file frontend/public/locales/en-GB/translation.toml --branch "" --files frontend/public/locales/de-DE/translation.toml frontend/public/locales/fr-FR/translation.toml
import argparse
import glob
import os
import argparse
import re
from pathlib import Path
import tomllib # Python 3.11+ (stdlib)
import tomli_w # For writing TOML files
@@ -39,8 +36,7 @@ def find_duplicate_keys(file_path, keys=None, prefix=""):
duplicates = []
# Load TOML file
file_path = Path(file_path)
with file_path.open("rb") as file:
with open(file_path, "rb") as file:
data = tomllib.load(file)
def process_dict(obj, current_prefix=""):
@@ -59,8 +55,8 @@ def find_duplicate_keys(file_path, keys=None, prefix=""):
return duplicates
# Maximum size for TOML files (e.g., 570 KB)
MAX_FILE_SIZE = 570 * 1024
# Maximum size for TOML files (e.g., 500 KB)
MAX_FILE_SIZE = 500 * 1024
def parse_toml_file(file_path):
@@ -69,8 +65,7 @@ def parse_toml_file(file_path):
:param file_path: Path to the TOML file.
:return: Dictionary with flattened keys.
"""
file_path = Path(file_path)
with file_path.open("rb") as file:
with open(file_path, "rb") as file:
data = tomllib.load(file)
def flatten_dict(d, parent_key="", sep="."):
@@ -113,8 +108,7 @@ def write_toml_file(file_path, updated_properties):
"""
nested_data = unflatten_dict(updated_properties)
file_path = Path(file_path)
with file_path.open("wb") as file:
with open(file_path, "wb") as file:
tomli_w.dump(nested_data, file)
@@ -125,23 +119,18 @@ def update_missing_keys(reference_file, file_list, branch=""):
:param file_list: List of translation files to update.
:param branch: Branch where the files are located.
"""
reference_file = Path(reference_file)
reference_properties = parse_toml_file(reference_file)
branch_path = Path(branch) if branch else Path()
for file_path in file_list:
file_path = Path(file_path)
language_dir = file_path.parent.name
reference_lang_dir = reference_file.parent.name
basename_current_file = os.path.basename(os.path.join(branch, file_path))
if (
language_dir == reference_lang_dir
or file_path.suffix != ".toml"
or file_path.parents[1].name != "locales"
basename_current_file == os.path.basename(reference_file)
or not file_path.endswith(".toml")
or not os.path.dirname(file_path).endswith("locales")
):
print(f"Skipping file: {file_path}")
continue
current_properties = parse_toml_file(branch_path / file_path)
current_properties = parse_toml_file(os.path.join(branch, file_path))
updated_properties = {}
for ref_key, ref_value in reference_properties.items():
@@ -152,7 +141,7 @@ def update_missing_keys(reference_file, file_list, branch=""):
# Add missing key with reference value
updated_properties[ref_key] = ref_value
write_toml_file(branch_path / file_path, updated_properties)
write_toml_file(os.path.join(branch, file_path), updated_properties)
def check_for_missing_keys(reference_file, file_list, branch):
@@ -160,17 +149,14 @@ def check_for_missing_keys(reference_file, file_list, branch):
def read_toml_keys(file_path):
file_path = Path(file_path)
if file_path.is_file():
if os.path.isfile(file_path) and os.path.exists(file_path):
return parse_toml_file(file_path)
return {}
def check_for_differences(reference_file, file_list, branch, actor):
reference_branch = branch
reference_file = Path(reference_file)
basename_reference_file = reference_file.name
branch_path = Path(branch) if branch else Path()
basename_reference_file = os.path.basename(reference_file)
report = []
report.append(f"#### 🔄 Reference Branch: `{reference_branch}`")
@@ -184,44 +170,39 @@ def check_for_differences(reference_file, file_list, branch, actor):
if len(file_list) == 1:
file_arr = file_list[0].split()
base_dir = Path.cwd() / "frontend" / "public" / "locales"
base_dir = os.path.abspath(
os.path.join(os.getcwd(), "frontend", "public", "locales")
)
for file_path in file_arr:
file_path = Path(file_path)
file_normpath = file_path
absolute_path = file_normpath.resolve()
basename_current_file = (branch_path / file_normpath).name
locale_dir = file_normpath.parent.name
report.append(f"#### 📃 **File Check:** `{locale_dir}/{basename_current_file}`")
file_normpath = os.path.normpath(file_path)
absolute_path = os.path.abspath(file_normpath)
# Verify that file is within the expected directory
if not absolute_path.is_relative_to(base_dir):
has_differences = True
report.append(
f"\n⚠️ Unsafe file found: `{locale_dir}/{basename_current_file}`\n\n---\n"
)
continue
if not absolute_path.startswith(base_dir):
raise ValueError(f"Unsafe file found: {file_normpath}")
# Verify file size before processing
if (branch_path / file_normpath).stat().st_size > MAX_FILE_SIZE:
has_differences = True
report.append(
f"\n⚠️ The file `{locale_dir}/{basename_current_file}` is too large and could pose a security risk.\n\n---\n"
if os.path.getsize(os.path.join(branch, file_normpath)) > MAX_FILE_SIZE:
raise ValueError(
f"The file {file_normpath} is too large and could pose a security risk."
)
continue
basename_current_file = os.path.basename(os.path.join(branch, file_normpath))
locale_dir = os.path.basename(os.path.dirname(file_normpath))
if basename_current_file == basename_reference_file and locale_dir == "en-GB":
continue
if (
file_normpath.suffix != ".toml"
not file_normpath.endswith(".toml")
or basename_current_file != "translation.toml"
):
continue
only_reference_file = False
current_keys = read_toml_keys(branch_path / file_path)
report.append(f"#### 📃 **File Check:** `{locale_dir}/{basename_current_file}`")
current_keys = read_toml_keys(os.path.join(branch, file_path))
reference_key_count = len(reference_keys)
current_key_count = len(current_keys)
@@ -266,13 +247,13 @@ def check_for_differences(reference_file, file_list, branch, actor):
else:
report.append("2. **Test Status:** ✅ **_Passed_**")
if find_duplicate_keys(branch_path / file_normpath):
if find_duplicate_keys(os.path.join(branch, file_normpath)):
has_differences = True
output = "\n".join(
[
f" - `{key}`: first at {first}, duplicate at `{duplicate}`"
for key, first, duplicate in find_duplicate_keys(
branch_path / file_normpath
os.path.join(branch, file_normpath)
)
]
)
+13 -17
View File
@@ -11,10 +11,6 @@ on:
allow_fork:
description: "Allow deploying fork PR?"
required: false
type: choice
options:
- "true"
- "false"
default: "false"
permissions:
@@ -35,7 +31,7 @@ jobs:
pr_ref: ${{ steps.resolve.outputs.ref }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
@@ -46,7 +42,7 @@ jobs:
script: |
const { owner, repo } = context.repo;
let prNumber = context.eventName === 'workflow_dispatch'
? parseInt(context.payload.inputs.pr, 10)
? parseInt(process.env.INPUT_PR, 10)
: context.payload.number;
if (!Number.isInteger(prNumber)) { core.setFailed('Invalid PR number'); return; }
@@ -111,7 +107,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
@@ -180,7 +176,7 @@ jobs:
fetch-depth: 0 # Fetch full history for commit hash detection
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Get version number
id: versionNumber
@@ -189,7 +185,7 @@ jobs:
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_API }}
@@ -275,7 +271,7 @@ jobs:
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Deploy V2 to VPS
@@ -320,16 +316,16 @@ jobs:
ports:
- "${V2_PORT}:80" # Frontend port (same as regular PRs)
environment:
VITE_API_BASE_URL: "http://${{ secrets.NEW_VPS_HOST }}:${BACKEND_PORT}"
VITE_API_BASE_URL: "http://${{ secrets.VPS_HOST }}:${BACKEND_PORT}"
depends_on:
- stirling-pdf-v2-backend
restart: on-failure:5
EOF
# Deploy to VPS
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }}:/tmp/docker-compose-v2.yml
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose-v2.yml
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << ENDSSH
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH
# Create V2 PR-specific directories
mkdir -p /stirling/V2-PR-${{ needs.check-pr.outputs.pr_number }}/{data,config,logs}
@@ -379,7 +375,7 @@ jobs:
}
}
const deploymentUrl = `http://${{ secrets.NEW_VPS_HOST }}:${v2Port}`;
const deploymentUrl = `http://${{ secrets.VPS_HOST }}:${v2Port}`;
const httpsUrl = `https://${v2Port}.ssl.stirlingpdf.cloud`;
const commentBody = `## 🚀 V2 Auto-Deployment Complete!\n\n` +
@@ -406,7 +402,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
@@ -454,12 +450,12 @@ jobs:
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Cleanup V2 deployment
run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << 'ENDSSH'
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
if [ -d "/stirling/V2-PR-${{ github.event.pull_request.number }}" ]; then
echo "Found V2 PR directory, proceeding with cleanup..."
@@ -25,7 +25,8 @@ jobs:
github.event.comment.user.login == 'frooodle' ||
github.event.comment.user.login == 'sf298' ||
github.event.comment.user.login == 'Ludy87' ||
github.event.comment.user.login == 'balazs-szucs' ||
github.event.comment.user.login == 'LaserKaspar' ||
github.event.comment.user.login == 'sbplat' ||
github.event.comment.user.login == 'reecebrowne' ||
github.event.comment.user.login == 'DarioGii' ||
github.event.comment.user.login == 'EthanHealy01' ||
@@ -40,7 +41,7 @@ jobs:
enable_enterprise: ${{ steps.check-pro-flag.outputs.enable_enterprise }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -128,7 +129,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -168,7 +169,7 @@ jobs:
STIRLING_PDF_DESKTOP_UI: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
@@ -189,7 +190,7 @@ jobs:
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Deploy to VPS
@@ -251,9 +252,9 @@ jobs:
EOF
# Then copy the file and execute commands
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }}:/tmp/docker-compose.yml
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose.yml
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << ENDSSH
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH
# Create PR-specific directories
mkdir -p /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/{data,config,logs}
@@ -335,7 +336,7 @@ jobs:
const prNumber = ${{ needs.check-comment.outputs.pr_number }};
const securityStatus = process.env.security_status || "Security Disabled";
const deploymentUrl = `http://${{ secrets.NEW_VPS_HOST }}:${prNumber}`;
const deploymentUrl = `http://${{ secrets.VPS_HOST }}:${prNumber}`;
const commentBody = `## 🚀 PR Test Deployment\n\n` +
`Your PR has been deployed for testing!\n\n` +
`🔗 **Test URL:** [${deploymentUrl}](${deploymentUrl})\n` +
@@ -362,7 +363,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+4 -4
View File
@@ -8,7 +8,7 @@ permissions:
contents: read
env:
SERVER_IP: ${{ secrets.NEW_VPS_IP }} # Add this to your GitHub secrets
SERVER_IP: ${{ secrets.VPS_IP }} # Add this to your GitHub secrets
CLEANUP_PERFORMED: "false" # Add flag to track if cleanup occurred
jobs:
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -100,14 +100,14 @@ jobs:
if: steps.remove-label-comment.outputs.present == 'true'
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Cleanup PR deployment
if: steps.remove-label-comment.outputs.present == 'true'
id: cleanup
run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << 'ENDSSH'
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
if [ -d "/stirling/PR-${{ github.event.pull_request.number }}" ]; then
echo "Found PR directory, proceeding with cleanup..."
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+12 -24
View File
@@ -32,7 +32,7 @@ jobs:
frontend: ${{ steps.changes.outputs.frontend }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout repository
@@ -56,7 +56,7 @@ jobs:
spring-security: [true, false]
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout repository
@@ -97,7 +97,6 @@ jobs:
with:
name: test-reports-jdk-${{ matrix.jdk-version }}-spring-security-${{ matrix.spring-security }}
path: |
app/**/build/reports/jacoco/test
app/**/build/reports/tests/
app/**/build/test-results/
app/**/build/reports/problems/
@@ -105,24 +104,13 @@ jobs:
retention-days: 3
if-no-files-found: warn
- name: Add coverage to PR with spring security ${{ matrix.spring-security }} and JDK ${{ matrix.jdk-version }}
id: jacoco
uses: madrapps/jacoco-report@50d3aff4548aa991e6753342d9ba291084e63848 # v1.7.2
with:
paths: |
${{ github.workspace }}/**/build/reports/jacoco/test/jacocoTestReport.xml
token: ${{ secrets.GITHUB_TOKEN }}
min-coverage-overall: 10
min-coverage-changed-files: 0
comment-type: summary
check-generateOpenApiDocs:
if: needs.files-changed.outputs.openapi == 'true'
needs: [files-changed]
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
@@ -152,7 +140,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout repository
@@ -186,7 +174,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
@@ -231,7 +219,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
@@ -245,7 +233,7 @@ jobs:
distribution: "temurin"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Install Docker Compose
run: |
@@ -286,7 +274,7 @@ jobs:
artifact-suffix: Dockerfile.fat
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
@@ -313,11 +301,11 @@ jobs:
STIRLING_PDF_DESKTOP_UI: false
- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Build ${{ matrix.docker-rev }}
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
@@ -326,8 +314,8 @@ jobs:
context: .
file: ./${{ matrix.docker-rev }}
push: false
cache-from: type=gha,scope=${{ matrix.artifact-suffix }}
cache-to: type=gha,mode=max,scope=${{ matrix.artifact-suffix }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64/v8
provenance: true
sbom: true
+1 -3
View File
@@ -7,8 +7,6 @@ on:
types: [opened, synchronize, reopened]
paths:
- "frontend/public/locales/*/translation.toml"
- ".github/scripts/check_language_toml.py"
- ".github/workflows/check_toml.yml"
# cancel in-progress jobs if a new job is triggered
concurrency:
@@ -27,7 +25,7 @@ jobs:
pull-requests: write # Allow writing to pull requests
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+6 -6
View File
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
@@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Get commit hashes for frontend and backend
id: commit-hashes
@@ -119,7 +119,7 @@ jobs:
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
chmod 600 ../private.key
- name: Deploy to VPS on port 3000
@@ -158,17 +158,17 @@ jobs:
ports:
- "3000:80"
environment:
VITE_API_BASE_URL: "http://${{ secrets.NEW_VPS_HOST }}:13000"
VITE_API_BASE_URL: "http://${{ secrets.VPS_HOST }}:13000"
depends_on:
- backend
restart: on-failure:5
EOF
# Copy to remote with unique name
scp -i ../private.key -o StrictHostKeyChecking=no $UNIQUE_NAME ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }}:/tmp/$UNIQUE_NAME
scp -i ../private.key -o StrictHostKeyChecking=no $UNIQUE_NAME ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/$UNIQUE_NAME
# SSH and rename/move atomically to avoid interference
ssh -i ../private.key -o StrictHostKeyChecking=no ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << ENDSSH
ssh -i ../private.key -o StrictHostKeyChecking=no ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH
mkdir -p /stirling/V2/{data,config,logs}
mv /tmp/$UNIQUE_NAME /stirling/V2/docker-compose.yml
cd /stirling/V2
@@ -25,7 +25,7 @@ jobs:
licenses-backend: ${{ steps.changes.outputs.licenses-backend }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -49,7 +49,7 @@ jobs:
repository-projects: write # Required for enabling automerge
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -312,7 +312,7 @@ jobs:
repository-projects: write # Required for enabling automerge
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
issues: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+121 -17
View File
@@ -26,6 +26,18 @@ on:
release:
types: [created]
# cancel in-progress jobs if a new job is triggered
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
# or a pull request is updated.
# It helps to save resources and time by ensuring that only the latest commit is built and tested
# This is particularly useful for long-running jobs that may take a while to complete.
# The `group` is set to a combination of the workflow name, event name, and branch name.
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
cancel-in-progress: true
permissions:
contents: read
@@ -38,7 +50,7 @@ jobs:
version: ${{ steps.versionNumber.outputs.versionNumber }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -75,15 +87,15 @@ jobs:
echo 'matrix={"include":[{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}]}' >> $GITHUB_OUTPUT
;;
"linux")
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
;;
*)
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
;;
esac
else
# For push/release events, build all platforms
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
fi
build-jars:
@@ -106,7 +118,7 @@ jobs:
file_suffix: "-server"
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -162,7 +174,7 @@ jobs:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
@@ -170,10 +182,60 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04'
if: matrix.platform == 'ubuntu-22.04' && matrix.name != 'linux-x86_64-appimage'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
# Dependencies explanation:
# - libwebkit2gtk-4.1-dev: WebKit engine for Tauri v2 (4.0 was for v1)
# - libappindicator3-dev: System tray support
# - librsvg2-dev: SVG rendering
# - patchelf: Required for AppImage packaging
# - libxdo-dev: Keyboard/mouse automation
# - libasound2-dev: Audio support
# - libopenblas-dev: GPU acceleration support
# - libx11-dev: X11 development files for window system interaction
# - libxtst-dev: X11 testing extensions for input simulation
# - libxrandr-dev: X11 RandR extension for display configuration
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libxdo-dev libasound2-dev libopenblas-dev libx11-dev libxtst-dev libxrandr-dev
- name: Install macOS DMG tooling
if: startsWith(matrix.platform, 'macos')
run: |
brew list create-dmg >/dev/null 2>&1 || brew install create-dmg
- name: Install dependencies (appimage only)
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
curl \
wget \
file \
libgtk-3-dev \
libxdo-dev \
libssl-dev \
libappindicator3-dev \
librsvg2-dev \
openjdk-17-jre-headless \
patchelf
mkdir -p /tmp/ubuntu-packages
cd /tmp/ubuntu-packages
wget https://launchpadlibrarian.net/723972773/libwebkit2gtk-4.1-0_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libwebkit2gtk-4.1-0"; exit 1; }
wget https://launchpadlibrarian.net/723972761/libwebkit2gtk-4.1-dev_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libwebkit2gtk-4.1-dev"; exit 1; }
wget https://launchpadlibrarian.net/723972770/libjavascriptcoregtk-4.1-0_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libjavascriptcoregtk-4.1-0"; exit 1; }
wget https://launchpadlibrarian.net/723972746/libjavascriptcoregtk-4.1-dev_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libjavascriptcoregtk-4.1-dev"; exit 1; }
wget https://launchpadlibrarian.net/723972735/gir1.2-javascriptcoregtk-4.1_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download gir1.2-javascriptcoregtk-4.1"; exit 1; }
wget https://launchpadlibrarian.net/723972739/gir1.2-webkit2-4.1_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download gir1.2-webkit2-4.1"; exit 1; }
wget https://launchpadlibrarian.net/606433947/libicu70_70.1-2ubuntu1_amd64.deb || { echo "Failed to download libicu70"; exit 1; }
wget https://launchpadlibrarian.net/606433941/libicu-dev_70.1-2ubuntu1_amd64.deb || { echo "Failed to download libicu-dev"; exit 1; }
wget https://launchpadlibrarian.net/606433945/icu-devtools_70.1-2ubuntu1_amd64.deb || { echo "Failed to download icu-devtools"; exit 1; }
wget https://launchpadlibrarian.net/595623693/libjpeg8_8c-2ubuntu10_amd64.deb || { echo "Failed to download libjpeg8"; exit 1; }
wget https://launchpadlibrarian.net/587202140/libjpeg-turbo8_2.1.2-0ubuntu1_amd64.deb || { echo "Failed to download libjpeg-turbo8"; exit 1; }
wget https://launchpadlibrarian.net/592959859/xdg-desktop-portal-gtk_1.14.0-1build1_amd64.deb || { echo "Failed to download xdg-desktop-portal-gtk"; exit 1; }
sudo apt-get install -y /tmp/ubuntu-packages/*.deb
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -268,7 +330,7 @@ jobs:
- name: Install frontend dependencies
working-directory: ./frontend
run: npm ci
run: npm install
# DigiCert KeyLocker Setup (Cloud HSM)
- name: Setup DigiCert KeyLocker
@@ -381,6 +443,35 @@ jobs:
echo "APPLE_SIGNING_IDENTITY=$CERT_ID" >> $GITHUB_ENV
echo "Certificate imported successfully."
- name: Check DMG creation dependencies (macOS only)
if: matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel'
run: |
echo "🔍 Checking DMG creation dependencies on ${{ matrix.platform }}..."
echo "hdiutil version: $(hdiutil --version || echo 'NOT FOUND')"
echo "create-dmg availability: $(which create-dmg || echo 'NOT FOUND')"
echo "Available disk space: $(df -h /tmp | tail -1)"
echo "macOS version: $(sw_vers -productVersion)"
echo "Available tools:"
ls -la /usr/bin/hd* || echo "No hd* tools found"
- name: Generate temporary GPG key for AppImage
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
cat >keyparams <<EOF
%no-protection
Key-Type: RSA
Key-Length: 2048
Name-Real: CI AppImage Signer
Name-Email: ci-appimage@example.invalid
Expire-Date: 0
%commit
EOF
gpg --batch --generate-key keyparams
export GPG_FINGERPRINT=$(gpg --batch --with-colons --list-secret-keys | awk -F: '/^fpr:/ {print $10; exit}')
echo "GPG_FINGERPRINT=$GPG_FINGERPRINT" >> $GITHUB_ENV
echo "Generated temporary GPG key:"
gpg --list-secret-keys --keyid-format=long
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
@@ -404,6 +495,15 @@ jobs:
tauriScript: npx tauri
args: ${{ matrix.args }}
- name: Cleanup temporary GPG key
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
if [ -n "${GPG_FINGERPRINT:-}" ]; then
gpg --batch --yes --delete-secret-keys "$GPG_FINGERPRINT" || true
gpg --batch --yes --delete-keys "$GPG_FINGERPRINT" || true
fi
rm -f keyparams
# Sign with DigiCert KeyLocker (post-build)
- name: Sign Windows binaries with DigiCert KeyLocker
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && (github.event_name == 'release' || github.ref == 'refs/heads/V2-master') }}
@@ -509,10 +609,13 @@ jobs:
find . -name "*.msi" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.msi" \;
elif [ "${{ matrix.platform }}" = "macos-15" ] || [ "${{ matrix.platform }}" = "macos-15-intel" ]; then
find . -name "*.dmg" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.dmg" \;
find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \;
else
# find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \;
elif [ "${{ matrix.platform }}" = "ubuntu-22.04" ]; then
find . -name "*.deb" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.deb" \;
find . -name "*.rpm" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.rpm" \;
find . -name "*.AppImage" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.AppImage" \;
else
echo "Unknown platform: ${{ matrix.platform }}"
fi
- name: Upload build artifacts
@@ -530,7 +633,7 @@ jobs:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -567,10 +670,11 @@ jobs:
tag_name: v${{ needs.determine-matrix.outputs.version }}
generate_release_notes: true
files: |
./artifacts/**/*.jar
./artifacts/**/*.msi
./artifacts/**/*.dmg
./artifacts/**/*.deb
./artifacts/**/*.AppImage
./artifacts/**/Stirling-PDF-*.jar
./artifacts/**/Stirling-PDF-*.msi
./artifacts/**/Stirling-PDF-*.dmg
./artifacts/**/Stirling-PDF-*.deb
./artifacts/**/Stirling-PDF-*.rpm
./artifacts/**/Stirling-PDF-*.AppImage
draft: false
prerelease: false
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+2 -2
View File
@@ -33,7 +33,7 @@ jobs:
id-token: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -51,7 +51,7 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Get version number
id: versionNumber
+2 -2
View File
@@ -35,7 +35,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -75,6 +75,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.29.5
uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v3.29.5
with:
sarif_file: results.sarif
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
+133 -15
View File
@@ -23,6 +23,18 @@ on:
push:
branches: [main]
# cancel in-progress jobs if a new job is triggered
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
# or a pull request is updated.
# It helps to save resources and time by ensuring that only the latest commit is built and tested
# This is particularly useful for long-running jobs that may take a while to complete.
# The `group` is set to a combination of the workflow name, event name, and branch name.
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
cancel-in-progress: true
permissions:
contents: read
@@ -33,6 +45,11 @@ jobs:
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Determine build matrix
id: set-matrix
run: |
@@ -45,15 +62,15 @@ jobs:
echo 'matrix={"include":[{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}]}' >> $GITHUB_OUTPUT
;;
"linux")
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
;;
*)
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
;;
esac
else
# For PR/push events, build all platforms
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT
echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b appimage","name":"linux-x86_64-appimage"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b deb","name":"linux-x86_64-deb"},{"platform":"ubuntu-22.04","args":"--target x86_64-unknown-linux-gnu -b rpm","name":"linux-x86_64-rpm"}]}' >> $GITHUB_OUTPUT
fi
build:
@@ -67,18 +84,68 @@ jobs:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04'
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' && matrix.name != 'linux-x86_64-appimage'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev
# Dependencies explanation:
# - libwebkit2gtk-4.1-dev: WebKit engine for Tauri v2 (4.0 was for v1)
# - libappindicator3-dev: System tray support
# - librsvg2-dev: SVG rendering
# - patchelf: Required for AppImage packaging
# - libxdo-dev: Keyboard/mouse automation
# - libasound2-dev: Audio support
# - libopenblas-dev: GPU acceleration support
# - libx11-dev: X11 development files for window system interaction
# - libxtst-dev: X11 testing extensions for input simulation
# - libxrandr-dev: X11 RandR extension for display configuration
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libxdo-dev libasound2-dev libopenblas-dev libx11-dev libxtst-dev libxrandr-dev
- name: Install macOS DMG tooling
if: startsWith(matrix.platform, 'macos')
run: |
brew list create-dmg >/dev/null 2>&1 || brew install create-dmg
- name: Install dependencies (appimage only)
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
curl \
wget \
file \
libgtk-3-dev \
libxdo-dev \
libssl-dev \
libappindicator3-dev \
librsvg2-dev \
openjdk-17-jre-headless \
patchelf
mkdir -p /tmp/ubuntu-packages
cd /tmp/ubuntu-packages
wget https://launchpadlibrarian.net/723972773/libwebkit2gtk-4.1-0_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libwebkit2gtk-4.1-0"; exit 1; }
wget https://launchpadlibrarian.net/723972761/libwebkit2gtk-4.1-dev_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libwebkit2gtk-4.1-dev"; exit 1; }
wget https://launchpadlibrarian.net/723972770/libjavascriptcoregtk-4.1-0_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libjavascriptcoregtk-4.1-0"; exit 1; }
wget https://launchpadlibrarian.net/723972746/libjavascriptcoregtk-4.1-dev_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download libjavascriptcoregtk-4.1-dev"; exit 1; }
wget https://launchpadlibrarian.net/723972735/gir1.2-javascriptcoregtk-4.1_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download gir1.2-javascriptcoregtk-4.1"; exit 1; }
wget https://launchpadlibrarian.net/723972739/gir1.2-webkit2-4.1_2.44.0-0ubuntu0.22.04.1_amd64.deb || { echo "Failed to download gir1.2-webkit2-4.1"; exit 1; }
wget https://launchpadlibrarian.net/606433947/libicu70_70.1-2ubuntu1_amd64.deb || { echo "Failed to download libicu70"; exit 1; }
wget https://launchpadlibrarian.net/606433941/libicu-dev_70.1-2ubuntu1_amd64.deb || { echo "Failed to download libicu-dev"; exit 1; }
wget https://launchpadlibrarian.net/606433945/icu-devtools_70.1-2ubuntu1_amd64.deb || { echo "Failed to download icu-devtools"; exit 1; }
wget https://launchpadlibrarian.net/595623693/libjpeg8_8c-2ubuntu10_amd64.deb || { echo "Failed to download libjpeg8"; exit 1; }
wget https://launchpadlibrarian.net/587202140/libjpeg-turbo8_2.1.2-0ubuntu1_amd64.deb || { echo "Failed to download libjpeg-turbo8"; exit 1; }
wget https://launchpadlibrarian.net/592959859/xdg-desktop-portal-gtk_1.14.0-1build1_amd64.deb || { echo "Failed to download xdg-desktop-portal-gtk"; exit 1; }
sudo apt-get install -y /tmp/ubuntu-packages/*.deb
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -99,6 +166,18 @@ jobs:
java-version: "21"
distribution: "temurin"
- name: Make libjvm discoverable (appimage only)
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
JAVA_LIBJVM="$JAVA_HOME/lib/server/libjvm.so"
if [ -f "$JAVA_LIBJVM" ]; then
sudo ln -sf "$JAVA_LIBJVM" /usr/lib/libjvm.so
echo "Linked libjvm from $JAVA_LIBJVM"
else
echo "libjvm not found at $JAVA_LIBJVM"
exit 1
fi
- name: Build Java backend with JLink
working-directory: ./
shell: bash
@@ -298,6 +377,24 @@ jobs:
echo "Available tools:"
ls -la /usr/bin/hd* || echo "No hd* tools found"
- name: Generate temporary GPG key for AppImage
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
cat >keyparams <<EOF
%no-protection
Key-Type: RSA
Key-Length: 2048
Name-Real: CI AppImage Signer
Name-Email: ci-appimage@example.invalid
Expire-Date: 0
%commit
EOF
gpg --batch --generate-key keyparams
export GPG_FINGERPRINT=$(gpg --batch --with-colons --list-secret-keys | awk -F: '/^fpr:/ {print $10; exit}')
echo "GPG_FINGERPRINT=$GPG_FINGERPRINT" >> $GITHUB_ENV
echo "Generated temporary GPG key:"
gpg --list-secret-keys --keyid-format=long
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
@@ -308,19 +405,33 @@ jobs:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPIMAGETOOL_SIGN_PASSPHRASE: ${{ secrets.APPIMAGETOOL_SIGN_PASSPHRASE }}
# APPIMAGETOOL_SIGN_PASSPHRASE: ${{ secrets.APPIMAGETOOL_SIGN_PASSPHRASE }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY: ${{ secrets.VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY }}
VITE_SAAS_SERVER_URL: ${{ secrets.VITE_SAAS_SERVER_URL }}
# Only enable Windows signing in Tauri when on main
SIGN: ${{ github.ref == 'refs/heads/main' && (env.SM_API_KEY == '' && env.WINDOWS_CERTIFICATE != '') && '1' || '0' }}
# Enable Windows signing only when ALL of the following are true:
# - The build is running on the Windows platform (matrix.platform == 'windows-latest')
# - The build is triggered from the main branch (github.ref == 'refs/heads/main')
# - The DigiCert KeyLocker HSM is NOT being used (env.SM_API_KEY == '')
# - A Windows certificate is available (env.WINDOWS_CERTIFICATE != '')
# If all conditions are met, SIGN=1 (enable signing); otherwise, SIGN=0 (disable signing).
SIGN: ${{ (matrix.platform == 'windows-latest' && github.ref == 'refs/heads/main' && env.SM_API_KEY == '' && env.WINDOWS_CERTIFICATE != '') && '1' || '0' }}
CI: true
with:
projectPath: ./frontend
tauriScript: npx tauri
args: ${{ matrix.args }}
- name: Cleanup temporary GPG key
if: matrix.platform == 'ubuntu-22.04' && matrix.name == 'linux-x86_64-appimage'
run: |
if [ -n "${GPG_FINGERPRINT:-}" ]; then
gpg --batch --yes --delete-secret-keys "$GPG_FINGERPRINT" || true
gpg --batch --yes --delete-keys "$GPG_FINGERPRINT" || true
fi
rm -f keyparams
# Sign with DigiCert KeyLocker (post-build)
- name: Sign Windows binaries with DigiCert KeyLocker
if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }}
@@ -507,9 +618,13 @@ jobs:
find . -name "*.msi" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.msi" \;
elif [ "${{ matrix.platform }}" = "macos-15" ] || [ "${{ matrix.platform }}" = "macos-15-intel" ]; then
find . -name "*.dmg" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.dmg" \;
else
# find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \;
elif [ "${{ matrix.platform }}" = "ubuntu-22.04" ]; then
find . -name "*.deb" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.deb" \;
find . -name "*.rpm" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.rpm" \;
find . -name "*.AppImage" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.AppImage" \;
else
echo "Unknown platform: ${{ matrix.platform }}"
fi
- name: Verify Windows Code Signature
@@ -599,13 +714,16 @@ jobs:
echo "❌ No macOS artifacts found"
exit 1
fi
else
elif [ "${{ matrix.platform }}" = "ubuntu-22.04" ]; then
echo "Checking for Linux artifacts..."
find . -name "*.deb" -o -name "*.AppImage" | head -5
if [ $(find . -name "*.deb" -o -name "*.AppImage" | wc -l) -eq 0 ]; then
find . -name "*.deb" -o -name "*.AppImage" -o -name "*.rpm" | head -5
if [ $(find . -name "*.deb" -o -name "*.AppImage" -o -name "*.rpm" | wc -l) -eq 0 ]; then
echo "❌ No Linux artifacts found"
exit 1
fi
else
echo "Unknown platform: ${{ matrix.platform }}"
exit 1
fi
echo "✅ Build artifacts found for ${{ matrix.name }}"
@@ -615,7 +733,7 @@ jobs:
run: |
cd ./frontend/src-tauri/target
echo "Artifact sizes for ${{ matrix.name }}:"
find . -name "*.exe" -o -name "*.dmg" -o -name "*.deb" -o -name "*.AppImage" -o -name "*.msi" | while read file; do
find . -name "*.exe" -o -name "*.dmg" -o -name "*.deb" -o -name "*.AppImage" -o -name "*.rpm" -o -name "*.msi" | while read file; do
if [ -f "$file" ]; then
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "unknown")
echo "$file: $size bytes"
+10 -10
View File
@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -49,7 +49,7 @@ jobs:
DISABLE_ADDITIONAL_FEATURES: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Get version number
id: versionNumber
@@ -76,7 +76,7 @@ jobs:
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Deploy to VPS
@@ -107,9 +107,9 @@ jobs:
restart: on-failure:5
EOF
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }}:/tmp/docker-compose.yml
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose.yml
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << EOF
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
mkdir -p /stirling/test-${{ github.sha }}/{data,config,logs}
mv /tmp/docker-compose.yml /stirling/test-${{ github.sha }}/docker-compose.yml
cd /stirling/test-${{ github.sha }}
@@ -140,7 +140,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
@@ -161,7 +161,7 @@ jobs:
npm install
npm run build
npm install dashcam-chrome --save
Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--load-extension=$(pwd)/node_modules/dashcam-chrome/build", "http://${{ secrets.NEW_VPS_HOST }}:1337"
Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--load-extension=$(pwd)/node_modules/dashcam-chrome/build", "http://${{ secrets.VPS_HOST }}:1337"
Start-Sleep -Seconds 20
prompt: |
1. /run testing/testdriver/test.yml
@@ -176,20 +176,20 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.NEW_VPS_SSH_KEY }}" > ../private.key
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Cleanup deployment
if: always()
run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.NEW_VPS_USERNAME }}@${{ secrets.NEW_VPS_HOST }} << EOF
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
cd /stirling/test-${{ github.sha }}
docker-compose down
cd /stirling
-3
View File
@@ -44,9 +44,6 @@ dependencies {
api 'jakarta.servlet:jakarta.servlet-api:6.1.0'
api 'org.snakeyaml:snakeyaml-engine:2.10'
api "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.14"
// Simple Java Mail for EML/MSG parsing (replaces direct Angus Mail usage)
api 'org.simplejavamail:simple-java-mail:8.12.6'
api 'org.simplejavamail:outlook-module:8.12.6' // MSG file support
api 'jakarta.mail:jakarta.mail-api:2.1.5'
runtimeOnly 'org.eclipse.angus:angus-mail:2.0.5'
}
@@ -94,19 +94,16 @@ public class RuntimePathConfig {
defaultSOfficePath, operations != null ? operations.getSoffice() : null);
// Initialize Tesseract data path
// Priority: config setting > TESSDATA_PREFIX env var > default path
String defaultTessDataPath =
isDocker ? "/usr/share/tesseract-ocr/5/tessdata" : "/usr/share/tessdata";
String tessPath = system.getTessdataDir();
String tessdataPrefix = java.lang.System.getenv("TESSDATA_PREFIX");
String defaultPath = "/usr/share/tesseract-ocr/5/tessdata";
if (tessPath != null && !tessPath.isEmpty()) {
this.tessDataPath = tessPath;
} else if (tessdataPrefix != null && !tessdataPrefix.isEmpty()) {
this.tessDataPath = tessdataPrefix;
} else {
this.tessDataPath = defaultPath;
}
String tessdataDir = java.lang.System.getenv("TESSDATA_PREFIX");
this.tessDataPath =
resolvePath(
defaultTessDataPath,
(tessPath != null && !tessPath.isEmpty()) ? tessPath : tessdataDir);
log.info("Using Tesseract data path: {}", this.tessDataPath);
}
@@ -61,7 +61,6 @@ public class ApplicationProperties {
private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated();
private Mail mail = new Mail();
private Telegram telegram = new Telegram();
private Premium premium = new Premium();
@@ -419,15 +418,6 @@ public class ApplicationProperties {
// 'https://app.example.com'). If not set, falls back to backendUrl.
private boolean enableMobileScanner = false; // Enable mobile phone QR code upload feature
private MobileScannerSettings mobileScannerSettings = new MobileScannerSettings();
@Data
public static class MobileScannerSettings {
private boolean convertToPdf = true; // Whether to automatically convert images to PDF
private String imageResolution = "full"; // Options: "full", "reduced"
private String pageFormat = "A4"; // Options: "keep", "A4", "letter"
private boolean stretchToFit = false; // Whether to stretch image to fill page
}
public boolean isAnalyticsEnabled() {
return this.getEnableAnalytics() != null && this.getEnableAnalytics();
@@ -552,10 +542,10 @@ public class ApplicationProperties {
@Override
public String toString() {
return """
Driver {
driverName='%s'
}
"""
Driver {
driverName='%s'
}
"""
.formatted(driverName);
}
}
@@ -608,7 +598,6 @@ public class ApplicationProperties {
private boolean ssoAutoLogin;
private CustomMetadata customMetadata = new CustomMetadata();
@Deprecated
@Data
public static class CustomMetadata {
private boolean autoUpdateMetadata;
@@ -616,23 +605,16 @@ public class ApplicationProperties {
private String creator;
private String producer;
@Deprecated
public String getCreator() {
return creator == null || creator.trim().isEmpty() ? "Stirling-PDF" : creator;
}
@Deprecated
public String getProducer() {
return producer == null || producer.trim().isEmpty() ? "Stirling-PDF" : producer;
}
}
}
/**
* Mail server configuration properties.
*
* @since 0.46.1
*/
@Data
public static class Mail {
private boolean enabled;
@@ -655,102 +637,6 @@ public class ApplicationProperties {
private Boolean sslCheckServerIdentity;
}
/**
* Telegram bot configuration properties.
*
* @since 2.2.x
*/
@Data
public static class Telegram {
private Boolean enabled = false;
@ToString.Exclude private String botToken;
private String botUsername;
private String pipelineInboxFolder = "telegram";
private Boolean customFolderSuffix = false;
private Boolean enableAllowUserIDs = false;
private List<Long> allowUserIDs = new ArrayList<>();
private Boolean enableAllowChannelIDs = false;
private List<Long> allowChannelIDs = new ArrayList<>();
private long processingTimeoutSeconds = 180;
private long pollingIntervalMillis = 2000;
private Feedback feedback = new Feedback();
/**
* Configuration for feedback messages sent by the Telegram bot.
*
* @since 2.2.x
*/
@Data
public static class Feedback {
private Channel channel = new Channel();
private User user = new User();
/**
* Channel-specific feedback settings.
*
* @since 2.2.x
*/
@Data
public static class Channel {
/**
* Set to {@code false} to hide/suppress "no valid document" feedback messages to
* the channel (to avoid spam).
*/
private Boolean noValidDocument = true;
/**
* Set to {@code false} to hide/suppress generic error feedback messages to the
* channel (to avoid spam).
*/
private Boolean errorMessage = true;
/**
* Set to {@code false} to hide/suppress processing error feedback messages to the
* channel (to avoid spam).
*/
private Boolean errorProcessing = true;
/**
* Set to {@code false} to hide/suppress "processing" feedback messages to the
* channel (to avoid spam).
*/
private Boolean processing = true;
}
/**
* User-specific feedback settings.
*
* @since 2.2.x
*/
@Data
public static class User {
/**
* Set to {@code false} to hide/suppress "no valid document" feedback messages to
* users (to avoid spam).
*/
private Boolean noValidDocument = true;
/**
* Set to {@code false} to hide/suppress generic error feedback messages to users
* (to avoid spam).
*/
private Boolean errorMessage = true;
/**
* Set to {@code false} to hide/suppress processing error feedback messages to users
* (to avoid spam).
*/
private Boolean errorProcessing = true;
/**
* Set to {@code false} to hide/suppress "processing" feedback messages to users (to
* avoid spam).
*/
private Boolean processing = true;
}
}
}
@Data
public static class Premium {
private boolean enabled;
@@ -1,417 +1,651 @@
package stirling.software.common.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZoneOffset;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.Properties;
import java.util.regex.Pattern;
import org.simplejavamail.api.email.AttachmentResource;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.email.Recipient;
import org.simplejavamail.converter.EmailConverter;
import jakarta.activation.DataSource;
import jakarta.mail.Message.RecipientType;
import org.springframework.http.MediaType;
import lombok.Data;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.api.converters.EmlToPdfRequest;
@Slf4j
@UtilityClass
public class EmlParser {
// Configuration constants
private final int DEFAULT_MAX_ATTACHMENT_MB = 10;
private final long MAX_SIZE_ESTIMATION_BYTES = 500L * 1024 * 1024; // 500MB
private static volatile Boolean jakartaMailAvailable = null;
private static volatile Method mimeUtilityDecodeTextMethod = null;
private static volatile boolean mimeUtilityChecked = false;
// Message constants
private final String NO_CONTENT_MESSAGE = "Email content could not be parsed";
private final String ATTACHMENT_PREFIX = "attachment-";
private static final Pattern MIME_ENCODED_PATTERN =
RegexPatternUtils.getInstance().getMimeEncodedWordPattern();
public EmailContent extractEmailContent(
private static final String DISPOSITION_ATTACHMENT = "attachment";
private static final String TEXT_PLAIN = MediaType.TEXT_PLAIN_VALUE;
private static final String TEXT_HTML = MediaType.TEXT_HTML_VALUE;
private static final String MULTIPART_PREFIX = "multipart/";
private static final String HEADER_CONTENT_TYPE = "content-type:";
private static final String HEADER_CONTENT_DISPOSITION = "content-disposition:";
private static final String HEADER_CONTENT_TRANSFER_ENCODING = "content-transfer-encoding:";
private static final String HEADER_CONTENT_ID = "Content-ID";
private static final String HEADER_SUBJECT = "Subject:";
private static final String HEADER_FROM = "From:";
private static final String HEADER_TO = "To:";
private static final String HEADER_CC = "Cc:";
private static final String HEADER_BCC = "Bcc:";
private static final String HEADER_DATE = "Date:";
private static synchronized boolean isJakartaMailAvailable() {
if (jakartaMailAvailable == null) {
try {
Class.forName("jakarta.mail.internet.MimeMessage");
Class.forName("jakarta.mail.Session");
Class.forName("jakarta.mail.internet.MimeUtility");
Class.forName("jakarta.mail.internet.MimePart");
Class.forName("jakarta.mail.internet.MimeMultipart");
Class.forName("jakarta.mail.Multipart");
Class.forName("jakarta.mail.Part");
jakartaMailAvailable = true;
} catch (ClassNotFoundException e) {
jakartaMailAvailable = false;
}
}
return jakartaMailAvailable;
}
public static EmailContent extractEmailContent(
byte[] emlBytes, EmlToPdfRequest request, CustomHtmlSanitizer customHtmlSanitizer)
throws IOException {
EmlProcessingUtils.validateEmlInput(emlBytes);
Email email = parseEmail(emlBytes);
return buildEmailContent(email, request, customHtmlSanitizer);
}
private Email parseEmail(byte[] emlBytes) throws IOException {
boolean isMsgFile = EmlProcessingUtils.isMsgFile(emlBytes);
try (ByteArrayInputStream input = new ByteArrayInputStream(emlBytes)) {
Email email;
if (isMsgFile) {
try {
email = EmailConverter.outlookMsgToEmail(input);
} catch (Exception e) {
// OLE2 magic bytes match but parsing failed - might be DOC/XLS/other OLE2 file
throw new IOException(
"The file appears to be an OLE2 file (MSG/DOC/XLS) but could not be "
+ "parsed as an Outlook email. Ensure it is a valid .msg file: "
+ e.getMessage(),
e);
}
} else {
email = EmailConverter.emlToEmail(input);
}
return email;
} catch (IOException e) {
throw e; // Re-throw IOException as-is
} catch (Exception e) {
throw new IOException(
String.format(
"Failed to parse EML file with Simple Java Mail: %s", e.getMessage()),
e);
if (isJakartaMailAvailable()) {
return extractEmailContentAdvanced(emlBytes, request, customHtmlSanitizer);
} else {
return extractEmailContentBasic(emlBytes, customHtmlSanitizer);
}
}
private EmailContent buildEmailContent(
Email email, EmlToPdfRequest request, CustomHtmlSanitizer customHtmlSanitizer)
throws IOException {
private static EmailContent extractEmailContentBasic(
byte[] emlBytes, CustomHtmlSanitizer customHtmlSanitizer) {
String emlContent = new String(emlBytes, StandardCharsets.UTF_8);
EmailContent content = new EmailContent();
content.setSubject(defaultString(email.getSubject()));
content.setFrom(formatRecipient(email.getFromRecipient()));
content.setTo(formatRecipients(email.getRecipients(), RecipientType.TO));
content.setCc(formatRecipients(email.getRecipients(), RecipientType.CC));
content.setBcc(formatRecipients(email.getRecipients(), RecipientType.BCC));
Date sentDate = email.getSentDate();
if (sentDate != null) {
// Use UTC for consistent timezone handling across deployments
content.setDate(ZonedDateTime.ofInstant(sentDate.toInstant(), ZoneOffset.UTC));
content.setSubject(extractBasicHeader(emlContent, HEADER_SUBJECT));
content.setFrom(extractBasicHeader(emlContent, HEADER_FROM));
content.setTo(extractBasicHeader(emlContent, HEADER_TO));
content.setCc(extractBasicHeader(emlContent, HEADER_CC));
content.setBcc(extractBasicHeader(emlContent, HEADER_BCC));
String dateStr = extractBasicHeader(emlContent, HEADER_DATE);
if (!dateStr.isEmpty()) {
content.setDateString(dateStr);
}
String htmlBody = email.getHTMLText();
if (customHtmlSanitizer != null && htmlBody != null) {
htmlBody = customHtmlSanitizer.sanitize(htmlBody);
}
content.setHtmlBody(htmlBody);
String textBody = email.getPlainText();
if (customHtmlSanitizer != null && textBody != null) {
textBody = customHtmlSanitizer.sanitize(textBody);
}
content.setTextBody(textBody);
if (isBlank(content.getHtmlBody()) && isBlank(content.getTextBody())) {
content.setTextBody(NO_CONTENT_MESSAGE);
String htmlBody = extractHtmlBody(emlContent);
if (htmlBody != null) {
content.setHtmlBody(htmlBody);
} else {
String textBody = extractTextBody(emlContent);
content.setTextBody(textBody != null ? textBody : "Email content could not be parsed");
}
List<EmailAttachment> attachments = new ArrayList<>();
attachments.addAll(mapResources(email.getEmbeddedImages(), request, true));
attachments.addAll(mapResources(email.getAttachments(), request, false));
content.setAttachments(attachments);
content.setAttachmentCount(attachments.size());
content.getAttachments().addAll(extractAttachmentsBasic(emlContent));
return content;
}
private List<EmailAttachment> mapResources(
List<AttachmentResource> resources, EmlToPdfRequest request, boolean embedded)
throws IOException {
private static EmailContent extractEmailContentAdvanced(
byte[] emlBytes, EmlToPdfRequest request, CustomHtmlSanitizer customHtmlSanitizer) {
try {
Class<?> sessionClass = Class.forName("jakarta.mail.Session");
Class<?> mimeMessageClass = Class.forName("jakarta.mail.internet.MimeMessage");
if (resources == null || resources.isEmpty()) {
return List.of();
Method getDefaultInstance =
sessionClass.getMethod("getDefaultInstance", Properties.class);
Object session = getDefaultInstance.invoke(null, new Properties());
Class<?>[] constructorArgs = new Class<?>[] {sessionClass, InputStream.class};
Constructor<?> mimeMessageConstructor =
mimeMessageClass.getConstructor(constructorArgs);
Object message =
mimeMessageConstructor.newInstance(session, new ByteArrayInputStream(emlBytes));
return extractFromMimeMessage(message, request, customHtmlSanitizer);
} catch (ReflectiveOperationException e) {
return extractEmailContentBasic(emlBytes, customHtmlSanitizer);
}
List<EmailAttachment> mapped = new ArrayList<>(resources.size());
int unnamedCounter = 0; // Start at 0, increment before use
for (AttachmentResource resource : resources) {
if (resource == null) {
continue; // Skip null resources early
}
// Pre-determine if this resource needs a generated filename
boolean needsGeneratedName = !embedded && needsGeneratedFilename(resource);
if (needsGeneratedName) {
unnamedCounter++;
}
EmailAttachment attachment =
toEmailAttachment(resource, request, embedded, unnamedCounter);
if (attachment != null) {
mapped.add(attachment);
}
}
return mapped;
}
/** Checks if a resource needs a generated filename (has no usable name). */
private boolean needsGeneratedFilename(AttachmentResource resource) {
if (resource == null) {
return false;
private static EmailContent extractFromMimeMessage(
Object message, EmlToPdfRequest request, CustomHtmlSanitizer customHtmlSanitizer) {
EmailContent content = new EmailContent();
try {
Class<?> messageClass = message.getClass();
Method getSubject = messageClass.getMethod("getSubject");
String subject = (String) getSubject.invoke(message);
content.setSubject(subject != null ? safeMimeDecode(subject) : "No Subject");
Method getFrom = messageClass.getMethod("getFrom");
Object[] fromAddresses = (Object[]) getFrom.invoke(message);
content.setFrom(buildAddressString(fromAddresses));
extractRecipients(message, messageClass, content);
Method getSentDate = messageClass.getMethod("getSentDate");
Date legacyDate = (Date) getSentDate.invoke(message);
if (legacyDate != null) {
content.setDate(
ZonedDateTime.ofInstant(legacyDate.toInstant(), ZoneId.systemDefault()));
}
Method getContent = messageClass.getMethod("getContent");
Object messageContent = getContent.invoke(message);
processMessageContent(message, messageContent, content, request, customHtmlSanitizer);
} catch (ReflectiveOperationException | RuntimeException e) {
content.setSubject("Email Conversion");
content.setFrom("Unknown");
content.setTo("Unknown");
content.setCc("");
content.setBcc("");
content.setTextBody("Email content could not be parsed with advanced processing");
}
String resourceName = resource.getName();
if (!isBlank(resourceName)) {
return false;
}
DataSource dataSource = resource.getDataSource();
return isBlank(dataSource.getName());
return content;
}
private EmailAttachment toEmailAttachment(
AttachmentResource resource, EmlToPdfRequest request, boolean embedded, int counter)
throws IOException {
private static void extractRecipients(
Object message, Class<?> messageClass, EmailContent content) {
try {
Method getRecipients =
messageClass.getMethod(
"getRecipients", Class.forName("jakarta.mail.Message$RecipientType"));
Class<?> recipientTypeClass = Class.forName("jakarta.mail.Message$RecipientType");
if (resource == null) {
return null;
}
Object toType = recipientTypeClass.getField("TO").get(null);
Object[] toRecipients = (Object[]) getRecipients.invoke(message, toType);
content.setTo(buildAddressString(toRecipients));
EmailAttachment attachment = new EmailAttachment();
attachment.setEmbedded(embedded);
Object ccType = recipientTypeClass.getField("CC").get(null);
Object[] ccRecipients = (Object[]) getRecipients.invoke(message, ccType);
content.setCc(buildAddressString(ccRecipients));
String resourceName = defaultString(resource.getName());
String filename = resourceName;
DataSource dataSource = resource.getDataSource();
String contentType = dataSource.getContentType();
Object bccType = recipientTypeClass.getField("BCC").get(null);
Object[] bccRecipients = (Object[]) getRecipients.invoke(message, bccType);
content.setBcc(buildAddressString(bccRecipients));
if (!isBlank(dataSource.getName())) {
filename = dataSource.getName();
}
filename = safeMimeDecode(filename);
// Generate unique filename for unnamed attachments
if (isBlank(filename)) {
String extension = detectExtensionFromMimeType(contentType);
filename = embedded ? resourceName : (ATTACHMENT_PREFIX + counter + extension);
}
attachment.setFilename(filename);
String contentId = embedded ? stripCid(resourceName) : null;
attachment.setContentId(contentId);
String detectedContentType = EmlProcessingUtils.detectMimeType(filename, contentType);
attachment.setContentType(detectedContentType);
// Read data with size limit to prevent OOM
ReadResult readResult = readData(dataSource, embedded, request);
if (readResult != null) {
attachment.setSizeBytes(readResult.totalSize);
if (shouldIncludeAttachmentData(embedded, request, readResult)) {
attachment.setData(readResult.data);
} catch (ReflectiveOperationException e) {
try {
Method getAllRecipients = messageClass.getMethod("getAllRecipients");
Object[] recipients = (Object[]) getAllRecipients.invoke(message);
content.setTo(buildAddressString(recipients));
content.setCc("");
content.setBcc("");
} catch (ReflectiveOperationException ex) {
content.setTo("");
content.setCc("");
content.setBcc("");
}
}
return attachment;
}
private boolean shouldIncludeAttachmentData(
boolean embedded, EmlToPdfRequest request, ReadResult readResult) {
// Always include embedded images for proper rendering
if (embedded) {
return readResult != null && readResult.data() != null;
}
// Check if attachments are requested and data is available within size limit
if (request == null || !request.isIncludeAttachments()) {
return false;
}
if (readResult == null || readResult.data() == null) {
return false;
}
return readResult.data().length <= getMaxAttachmentSizeBytes(request);
}
private String detectExtensionFromMimeType(String mimeType) {
if (mimeType == null) {
private static String buildAddressString(Object[] addresses) {
if (addresses == null || addresses.length == 0) {
return "";
}
String lower = mimeType.toLowerCase(Locale.ROOT);
// Remove any parameters (e.g., "text/plain; charset=utf-8" -> "text/plain")
int semicolon = lower.indexOf(';');
if (semicolon > 0) {
lower = lower.substring(0, semicolon).trim();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < addresses.length; i++) {
if (i > 0) builder.append(", ");
builder.append(safeMimeDecode(addresses[i].toString()));
}
// Match exact MIME types first, then fall back to contains() for variants
return switch (lower) {
case "application/pdf" -> ".pdf";
case "image/png" -> ".png";
case "image/jpeg", "image/jpg" -> ".jpg";
case "image/gif" -> ".gif";
case "image/webp" -> ".webp";
case "image/bmp" -> ".bmp";
case "text/plain" -> ".txt";
case "text/html" -> ".html";
case "text/xml", "application/xml" -> ".xml";
case "application/json" -> ".json";
case "application/zip" -> ".zip";
case "application/octet-stream" -> ".bin";
default -> {
if (lower.contains("wordprocessingml") || lower.contains("msword")) yield ".docx";
if (lower.contains("spreadsheetml") || lower.contains("excel")) yield ".xlsx";
if (lower.contains("presentationml") || lower.contains("powerpoint")) yield ".pptx";
if (lower.contains("opendocument.text")) yield ".odt";
if (lower.contains("opendocument.spreadsheet")) yield ".ods";
yield "";
}
};
return builder.toString();
}
private ReadResult readData(DataSource dataSource, boolean embedded, EmlToPdfRequest request)
throws IOException {
if (dataSource == null) {
return null;
}
private static void processMessageContent(
Object message,
Object messageContent,
EmailContent content,
EmlToPdfRequest request,
CustomHtmlSanitizer customHtmlSanitizer) {
try {
if (messageContent instanceof String stringContent) {
Method getContentType = message.getClass().getMethod("getContentType");
String contentType = (String) getContentType.invoke(message);
long maxBytes = getMaxAttachmentSizeBytes(request);
try (InputStream input = dataSource.getInputStream()) {
// Embedded images are usually needed for display regardless of size,
// but regular attachments should be guarded against OOM
if (!embedded && request != null) {
byte[] buffer = new byte[8192];
ByteArrayOutputStream output = new ByteArrayOutputStream();
int bytesRead;
long totalBytes = 0;
while ((bytesRead = input.read(buffer)) != -1) {
totalBytes += bytesRead;
if (totalBytes > maxBytes) {
// Attachment too large - skip remaining data but estimate total size
long remainingBytes = countRemainingBytes(input, totalBytes);
log.debug(
"Attachment exceeds size limit: {} bytes (max: {} bytes), skipping",
remainingBytes,
maxBytes);
return new ReadResult(null, remainingBytes);
}
output.write(buffer, 0, bytesRead);
if (contentType != null
&& contentType.toLowerCase(Locale.ROOT).contains(TEXT_HTML)) {
content.setHtmlBody(stringContent);
} else {
content.setTextBody(stringContent);
}
byte[] data = output.toByteArray();
return new ReadResult(data, data.length);
} else {
byte[] data = input.readAllBytes();
return new ReadResult(data, data.length);
Class<?> multipartClass = Class.forName("jakarta.mail.Multipart");
if (multipartClass.isInstance(messageContent)) {
processMultipart(messageContent, content, request, customHtmlSanitizer, 0);
}
}
} catch (IOException e) {
if (embedded) {
log.debug(
"Failed to read embedded image, using empty placeholder: {}",
e.getMessage());
return new ReadResult(new byte[0], 0);
}
throw e;
} catch (ReflectiveOperationException | ClassCastException e) {
content.setTextBody("Email content could not be parsed with advanced processing");
}
}
private long countRemainingBytes(InputStream input, long alreadyRead) throws IOException {
long count = alreadyRead;
private static void processMultipart(
Object multipart,
EmailContent content,
EmlToPdfRequest request,
CustomHtmlSanitizer customHtmlSanitizer,
int depth) {
long skipped;
while (count < MAX_SIZE_ESTIMATION_BYTES
&& (skipped = input.skip(MAX_SIZE_ESTIMATION_BYTES - count)) > 0) {
count += skipped;
final int MAX_MULTIPART_DEPTH = 10;
if (depth > MAX_MULTIPART_DEPTH) {
content.setHtmlBody("<div class=\"error\">Maximum multipart depth exceeded</div>");
return;
}
if (count < MAX_SIZE_ESTIMATION_BYTES && input.available() > 0) {
byte[] buffer = new byte[8192];
int read;
while ((read = input.read(buffer)) != -1 && count < MAX_SIZE_ESTIMATION_BYTES) {
count += read;
try {
Class<?> multipartClass = multipart.getClass();
Method getCount = multipartClass.getMethod("getCount");
int count = (Integer) getCount.invoke(multipart);
Method getBodyPart = multipartClass.getMethod("getBodyPart", int.class);
for (int i = 0; i < count; i++) {
Object part = getBodyPart.invoke(multipart, i);
processPart(part, content, request, customHtmlSanitizer, depth + 1);
}
}
return count;
} catch (ReflectiveOperationException | ClassCastException e) {
content.setHtmlBody("<div class=\"error\">Error processing multipart content</div>");
}
}
private String formatRecipients(List<Recipient> recipients, RecipientType type) {
if (recipients == null || type == null) {
private static void processPart(
Object part,
EmailContent content,
EmlToPdfRequest request,
CustomHtmlSanitizer customHtmlSanitizer,
int depth) {
try {
Class<?> partClass = part.getClass();
Method isMimeType = partClass.getMethod("isMimeType", String.class);
Method getContent = partClass.getMethod("getContent");
Method getDisposition = partClass.getMethod("getDisposition");
Method getFileName = partClass.getMethod("getFileName");
Method getContentType = partClass.getMethod("getContentType");
Method getHeader = partClass.getMethod("getHeader", String.class);
Object disposition = getDisposition.invoke(part);
String filename = (String) getFileName.invoke(part);
String contentType = (String) getContentType.invoke(part);
String normalizedDisposition =
disposition != null ? ((String) disposition).toLowerCase(Locale.ROOT) : null;
if ((Boolean) isMimeType.invoke(part, TEXT_PLAIN) && normalizedDisposition == null) {
Object partContent = getContent.invoke(part);
if (partContent instanceof String stringContent) {
content.setTextBody(stringContent);
}
} else if ((Boolean) isMimeType.invoke(part, TEXT_HTML)
&& normalizedDisposition == null) {
Object partContent = getContent.invoke(part);
if (partContent instanceof String stringContent) {
String htmlBody =
customHtmlSanitizer != null
? customHtmlSanitizer.sanitize(stringContent)
: stringContent;
content.setHtmlBody(htmlBody);
}
} else if ((normalizedDisposition != null
&& normalizedDisposition.contains(DISPOSITION_ATTACHMENT))
|| (filename != null && !filename.trim().isEmpty())) {
processAttachment(
part, content, request, getHeader, getContent, filename, contentType);
} else if ((Boolean) isMimeType.invoke(part, "multipart/*")) {
Object multipartContent = getContent.invoke(part);
if (multipartContent != null) {
Class<?> multipartClass = Class.forName("jakarta.mail.Multipart");
if (multipartClass.isInstance(multipartContent)) {
processMultipart(
multipartContent, content, request, customHtmlSanitizer, depth + 1);
}
}
}
} catch (ReflectiveOperationException | RuntimeException e) {
// Continue processing other parts if one fails
}
}
private static void processAttachment(
Object part,
EmailContent content,
EmlToPdfRequest request,
Method getHeader,
Method getContent,
String filename,
String contentType) {
content.setAttachmentCount(content.getAttachmentCount() + 1);
if (filename != null && !filename.trim().isEmpty()) {
EmailAttachment attachment = new EmailAttachment();
attachment.setFilename(safeMimeDecode(filename));
attachment.setContentType(contentType);
try {
String[] contentIdHeaders = (String[]) getHeader.invoke(part, HEADER_CONTENT_ID);
if (contentIdHeaders != null) {
for (String contentIdHeader : contentIdHeaders) {
if (contentIdHeader != null && !contentIdHeader.trim().isEmpty()) {
attachment.setEmbedded(true);
String contentId =
RegexPatternUtils.getInstance()
.getAngleBracketsPattern()
.matcher(contentIdHeader.trim())
.replaceAll("");
attachment.setContentId(contentId);
break;
}
}
}
} catch (ReflectiveOperationException e) {
}
if ((request != null && request.isIncludeAttachments()) || attachment.isEmbedded()) {
extractAttachmentData(part, attachment, getContent, request);
}
content.getAttachments().add(attachment);
}
}
private static void extractAttachmentData(
Object part, EmailAttachment attachment, Method getContent, EmlToPdfRequest request) {
try {
Object attachmentContent = getContent.invoke(part);
byte[] attachmentData = null;
if (attachmentContent instanceof InputStream inputStream) {
try (InputStream stream = inputStream) {
attachmentData = stream.readAllBytes();
} catch (IOException e) {
if (attachment.isEmbedded()) {
attachmentData = new byte[0];
} else {
throw new RuntimeException(e);
}
}
} else if (attachmentContent instanceof byte[] byteArray) {
attachmentData = byteArray;
} else if (attachmentContent instanceof String stringContent) {
attachmentData = stringContent.getBytes(StandardCharsets.UTF_8);
}
if (attachmentData != null) {
long maxSizeMB = request != null ? request.getMaxAttachmentSizeMB() : 10L;
long maxSizeBytes = maxSizeMB * 1024 * 1024;
if (attachmentData.length <= maxSizeBytes || attachment.isEmbedded()) {
attachment.setData(attachmentData);
attachment.setSizeBytes(attachmentData.length);
} else {
attachment.setSizeBytes(attachmentData.length);
}
}
} catch (ReflectiveOperationException | RuntimeException e) {
// Continue without attachment data
}
}
private static String extractBasicHeader(String emlContent, String headerName) {
try {
String[] lines =
RegexPatternUtils.getInstance().getNewlineSplitPattern().split(emlContent);
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
if (line.toLowerCase(Locale.ROOT).startsWith(headerName.toLowerCase(Locale.ROOT))) {
StringBuilder value =
new StringBuilder(line.substring(headerName.length()).trim());
for (int j = i + 1; j < lines.length; j++) {
if (lines[j].startsWith(" ") || lines[j].startsWith("\t")) {
value.append(" ").append(lines[j].trim());
} else {
break;
}
}
return safeMimeDecode(value.toString());
}
if (line.trim().isEmpty()) break;
}
} catch (RuntimeException e) {
// Ignore errors in header extraction
}
return "";
}
private static String extractHtmlBody(String emlContent) {
try {
String lowerContent = emlContent.toLowerCase(Locale.ROOT);
int htmlStart = lowerContent.indexOf(HEADER_CONTENT_TYPE + " " + TEXT_HTML);
if (htmlStart == -1) return null;
int bodyStart = emlContent.indexOf("\r\n\r\n", htmlStart);
if (bodyStart == -1) bodyStart = emlContent.indexOf("\n\n", htmlStart);
if (bodyStart == -1) return null;
bodyStart += (emlContent.charAt(bodyStart + 1) == '\r') ? 4 : 2;
int bodyEnd = findPartEnd(emlContent, bodyStart);
return emlContent.substring(bodyStart, bodyEnd).trim();
} catch (Exception e) {
return null;
}
}
private static String extractTextBody(String emlContent) {
try {
String lowerContent = emlContent.toLowerCase(Locale.ROOT);
int textStart = lowerContent.indexOf(HEADER_CONTENT_TYPE + " " + TEXT_PLAIN);
if (textStart == -1) {
int bodyStart = emlContent.indexOf("\r\n\r\n");
if (bodyStart == -1) bodyStart = emlContent.indexOf("\n\n");
if (bodyStart != -1) {
bodyStart += (emlContent.charAt(bodyStart + 1) == '\r') ? 4 : 2;
int bodyEnd = findPartEnd(emlContent, bodyStart);
return emlContent.substring(bodyStart, bodyEnd).trim();
}
return null;
}
int bodyStart = emlContent.indexOf("\r\n\r\n", textStart);
if (bodyStart == -1) bodyStart = emlContent.indexOf("\n\n", textStart);
if (bodyStart == -1) return null;
bodyStart += (emlContent.charAt(bodyStart + 1) == '\r') ? 4 : 2;
int bodyEnd = findPartEnd(emlContent, bodyStart);
return emlContent.substring(bodyStart, bodyEnd).trim();
} catch (RuntimeException e) {
return null;
}
}
private static int findPartEnd(String content, int start) {
String[] lines =
RegexPatternUtils.getInstance()
.getNewlineSplitPattern()
.split(content.substring(start));
StringBuilder result = new StringBuilder();
for (String line : lines) {
if (line.startsWith("--") && line.length() > 10) break;
result.append(line).append("\n");
}
return start + result.length();
}
private static List<EmailAttachment> extractAttachmentsBasic(String emlContent) {
List<EmailAttachment> attachments = new ArrayList<>();
try {
String[] lines =
RegexPatternUtils.getInstance().getNewlineSplitPattern().split(emlContent);
boolean inHeaders = true;
String currentContentType = "";
String currentDisposition = "";
String currentFilename = "";
String currentEncoding = "";
for (String line : lines) {
String lowerLine = line.toLowerCase(Locale.ROOT).trim();
if (line.trim().isEmpty()) {
inHeaders = false;
if (isAttachment(currentDisposition, currentFilename, currentContentType)) {
EmailAttachment attachment = new EmailAttachment();
attachment.setFilename(currentFilename);
attachment.setContentType(currentContentType);
attachment.setTransferEncoding(currentEncoding);
attachments.add(attachment);
}
currentContentType = "";
currentDisposition = "";
currentFilename = "";
currentEncoding = "";
inHeaders = true;
continue;
}
if (!inHeaders) continue;
if (lowerLine.startsWith(HEADER_CONTENT_TYPE)) {
currentContentType = line.substring(HEADER_CONTENT_TYPE.length()).trim();
} else if (lowerLine.startsWith(HEADER_CONTENT_DISPOSITION)) {
currentDisposition = line.substring(HEADER_CONTENT_DISPOSITION.length()).trim();
currentFilename = extractFilenameFromDisposition(currentDisposition);
} else if (lowerLine.startsWith(HEADER_CONTENT_TRANSFER_ENCODING)) {
currentEncoding =
line.substring(HEADER_CONTENT_TRANSFER_ENCODING.length()).trim();
}
}
} catch (RuntimeException e) {
// Continue with empty list
}
return attachments;
}
private static boolean isAttachment(String disposition, String filename, String contentType) {
return (disposition.toLowerCase(Locale.ROOT).contains(DISPOSITION_ATTACHMENT)
&& !filename.isEmpty())
|| (!filename.isEmpty()
&& !contentType.toLowerCase(Locale.ROOT).startsWith("text/"))
|| (contentType.toLowerCase(Locale.ROOT).contains("application/")
&& !filename.isEmpty());
}
private static String extractFilenameFromDisposition(String disposition) {
if (disposition == null || !disposition.contains("filename=")) {
return "";
}
return recipients.stream()
.filter(Objects::nonNull)
// Use type.equals() for null-safe comparison (recipient.getType() may be null)
.filter(recipient -> type.equals(recipient.getType()))
.map(EmlParser::formatRecipient)
.filter(string -> !isBlank(string))
.collect(Collectors.joining(", "));
// Handle filename*= (RFC 2231 encoded filename)
if (disposition.toLowerCase(Locale.ROOT).contains("filename*=")) {
int filenameStarStart = disposition.toLowerCase(Locale.ROOT).indexOf("filename*=") + 10;
int filenameStarEnd = disposition.indexOf(";", filenameStarStart);
if (filenameStarEnd == -1) filenameStarEnd = disposition.length();
String extendedFilename =
disposition.substring(filenameStarStart, filenameStarEnd).trim();
extendedFilename =
RegexPatternUtils.getInstance()
.getQuotesRemovalPattern()
.matcher(extendedFilename)
.replaceAll("");
if (extendedFilename.contains("'")) {
String[] parts = extendedFilename.split("'", 3);
if (parts.length == 3) {
return EmlProcessingUtils.decodeUrlEncoded(parts[2]);
}
}
}
// Handle regular filename=
int filenameStart = disposition.toLowerCase(Locale.ROOT).indexOf("filename=") + 9;
int filenameEnd = disposition.indexOf(";", filenameStart);
if (filenameEnd == -1) filenameEnd = disposition.length();
String filename = disposition.substring(filenameStart, filenameEnd).trim();
filename =
RegexPatternUtils.getInstance()
.getQuotesRemovalPattern()
.matcher(filename)
.replaceAll("");
return safeMimeDecode(filename);
}
private String formatRecipient(Recipient recipient) {
if (recipient == null) {
public static String safeMimeDecode(String headerValue) {
if (headerValue == null || headerValue.trim().isEmpty()) {
return "";
}
String name = safeMimeDecode(recipient.getName());
String address = safeMimeDecode(recipient.getAddress());
if (!isBlank(name) && !isBlank(address)) {
return name + " <" + address + ">";
if (!mimeUtilityChecked) {
synchronized (EmlParser.class) {
if (!mimeUtilityChecked) {
initializeMimeUtilityDecoding();
}
}
}
return !isBlank(name) ? name : address;
}
public String safeMimeDecode(String headerValue) {
if (isBlank(headerValue)) {
return "";
if (mimeUtilityDecodeTextMethod != null) {
try {
return (String) mimeUtilityDecodeTextMethod.invoke(null, headerValue.trim());
} catch (ReflectiveOperationException | RuntimeException e) {
// Fall through to custom implementation
}
}
return EmlProcessingUtils.decodeMimeHeader(headerValue.trim());
}
private String stripCid(String contentId) {
if (contentId == null) {
return null;
}
return RegexPatternUtils.getInstance()
.getAngleBracketsPattern()
.matcher(contentId)
.replaceAll("")
.trim();
}
private long getMaxAttachmentSizeBytes(EmlToPdfRequest request) {
long maxMb = request != null ? request.getMaxAttachmentSizeMB() : DEFAULT_MAX_ATTACHMENT_MB;
return maxMb * 1024L * 1024L;
}
private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}
private String defaultString(String value) {
return value != null ? value : "";
}
private record ReadResult(byte[] data, long totalSize) {
public ReadResult {
if (totalSize < 0) {
throw new IllegalArgumentException("Size cannot be negative: " + totalSize);
}
if (data != null && data.length > totalSize) {
throw new IllegalArgumentException(
"Data length (" + data.length + ") exceeds total size (" + totalSize + ")");
}
private static void initializeMimeUtilityDecoding() {
try {
Class<?> mimeUtilityClass = Class.forName("jakarta.mail.internet.MimeUtility");
mimeUtilityDecodeTextMethod = mimeUtilityClass.getMethod("decodeText", String.class);
} catch (ClassNotFoundException | NoSuchMethodException e) {
mimeUtilityDecodeTextMethod = null;
}
mimeUtilityChecked = true;
}
@Data
public class EmailContent {
public static class EmailContent {
private String subject;
private String from;
private String to;
private String cc;
private String bcc;
private ZonedDateTime date;
private String dateString; // Maintained for compatibility
private String dateString; // For basic parsing fallback
private String htmlBody;
private String textBody;
private int attachmentCount;
@@ -439,7 +673,7 @@ public class EmlParser {
}
@Data
public class EmailAttachment {
public static class EmailAttachment {
private String filename;
private String contentType;
private byte[] data;
@@ -1,7 +1,5 @@
package stirling.software.common.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@@ -10,41 +8,32 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import lombok.Synchronized;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.api.converters.EmlToPdfRequest;
import stirling.software.common.model.api.converters.HTMLToPdfRequest;
@Slf4j
@UtilityClass
public class EmlProcessingUtils {
// Style constants
private final int DEFAULT_FONT_SIZE = 12;
private final String DEFAULT_FONT_FAMILY = "Helvetica, sans-serif";
private final float DEFAULT_LINE_HEIGHT = 1.4f;
private final String DEFAULT_ZOOM = "1.0";
private final String DEFAULT_TEXT_COLOR = "#202124";
private final String DEFAULT_BACKGROUND_COLOR = "#ffffff";
private final String DEFAULT_BORDER_COLOR = "#e8eaed";
private final String ATTACHMENT_BACKGROUND_COLOR = "#f9f9f9";
private final String ATTACHMENT_BORDER_COLOR = "#eeeeee";
private static final int DEFAULT_FONT_SIZE = 12;
private static final String DEFAULT_FONT_FAMILY = "Helvetica, sans-serif";
private static final float DEFAULT_LINE_HEIGHT = 1.4f;
private static final String DEFAULT_ZOOM = "1.0";
private static final String DEFAULT_TEXT_COLOR = "#202124";
private static final String DEFAULT_BACKGROUND_COLOR = "#ffffff";
private static final String DEFAULT_BORDER_COLOR = "#e8eaed";
private static final String ATTACHMENT_BACKGROUND_COLOR = "#f9f9f9";
private static final String ATTACHMENT_BORDER_COLOR = "#eeeeee";
private final String CSS_RESOURCE_PATH = "templates/email-pdf-styles.css";
private final int EML_CHECK_LENGTH = 8192;
private final int MIN_HEADER_COUNT_FOR_VALID_EML = 2;
// MSG file magic bytes (Compound File Binary Format / OLE2)
// D0 CF 11 E0 A1 B1 1A E1
private final byte[] MSG_MAGIC_BYTES = {
(byte) 0xD0, (byte) 0xCF, (byte) 0x11, (byte) 0xE0,
(byte) 0xA1, (byte) 0xB1, (byte) 0x1A, (byte) 0xE1
};
private final Map<String, String> EXTENSION_TO_MIME_TYPE =
private static final int EML_CHECK_LENGTH = 8192;
private static final int MIN_HEADER_COUNT_FOR_VALID_EML = 2;
// MIME type detection
private static final Map<String, String> EXTENSION_TO_MIME_TYPE =
Map.of(
".png", MediaType.IMAGE_PNG_VALUE,
".jpg", MediaType.IMAGE_JPEG_VALUE,
@@ -56,36 +45,18 @@ public class EmlProcessingUtils {
".ico", "image/x-icon",
".tiff", "image/tiff",
".tif", "image/tiff");
private volatile String cachedCssContent = null;
public void validateEmlInput(byte[] emlBytes) {
public static void validateEmlInput(byte[] emlBytes) {
if (emlBytes == null || emlBytes.length == 0) {
throw ExceptionUtils.createEmlEmptyException();
}
if (isMsgFile(emlBytes)) {
return; // Valid MSG file, no further EML validation needed
}
if (isInvalidEmlFormat(emlBytes)) {
throw ExceptionUtils.createEmlInvalidFormatException();
}
}
public boolean isMsgFile(byte[] fileBytes) {
if (fileBytes == null || fileBytes.length < MSG_MAGIC_BYTES.length) {
return false;
}
for (int i = 0; i < MSG_MAGIC_BYTES.length; i++) {
if (fileBytes[i] != MSG_MAGIC_BYTES[i]) {
return false;
}
}
return true;
}
private boolean isInvalidEmlFormat(byte[] emlBytes) {
private static boolean isInvalidEmlFormat(byte[] emlBytes) {
try {
int checkLength = Math.min(emlBytes.length, EML_CHECK_LENGTH);
String content;
@@ -130,7 +101,7 @@ public class EmlProcessingUtils {
}
}
public String generateEnhancedEmailHtml(
public static String generateEnhancedEmailHtml(
EmlParser.EmailContent content,
EmlToPdfRequest request,
CustomHtmlSanitizer customHtmlSanitizer) {
@@ -174,7 +145,7 @@ public class EmlProcessingUtils {
html.append(
String.format(
Locale.ROOT,
"<div><strong>CC:</strong> %s</div>%n",
"<div><strong>CC:</strong> %s</div>\n",
sanitizeText(content.getCc(), customHtmlSanitizer)));
}
@@ -182,7 +153,7 @@ public class EmlProcessingUtils {
html.append(
String.format(
Locale.ROOT,
"<div><strong>BCC:</strong> %s</div>%n",
"<div><strong>BCC:</strong> %s</div>\n",
sanitizeText(content.getBcc(), customHtmlSanitizer)));
}
@@ -190,19 +161,19 @@ public class EmlProcessingUtils {
html.append(
String.format(
Locale.ROOT,
"<div><strong>Date:</strong> %s</div>%n",
"<div><strong>Date:</strong> %s</div>\n",
PdfAttachmentHandler.formatEmailDate(content.getDate())));
} else if (content.getDateString() != null && !content.getDateString().trim().isEmpty()) {
html.append(
String.format(
Locale.ROOT,
"<div><strong>Date:</strong> %s</div>%n",
"<div><strong>Date:</strong> %s</div>\n",
sanitizeText(content.getDateString(), customHtmlSanitizer)));
}
html.append(String.format(Locale.ROOT, "</div></div>%n"));
html.append("</div></div>\n");
html.append(String.format(Locale.ROOT, "<div class=\"email-body\">%n"));
html.append("<div class=\"email-body\">\n");
if (content.getHtmlBody() != null && !content.getHtmlBody().trim().isEmpty()) {
String processedHtml =
processEmailHtmlBody(content.getHtmlBody(), content, customHtmlSanitizer);
@@ -216,17 +187,17 @@ public class EmlProcessingUtils {
} else {
html.append("<div class=\"no-content\"><p><em>No content available</em></p></div>");
}
html.append(String.format(Locale.ROOT, "</div>%n"));
html.append("</div>\n");
if (content.getAttachmentCount() > 0 || !content.getAttachments().isEmpty()) {
appendAttachmentsSection(html, content, request);
appendAttachmentsSection(html, content, request, customHtmlSanitizer);
}
html.append(String.format(Locale.ROOT, "</div>%n</body></html>"));
html.append("</div>\n</body></html>");
return html.toString();
}
public String processEmailHtmlBody(
public static String processEmailHtmlBody(
String htmlBody,
EmlParser.EmailContent emailContent,
CustomHtmlSanitizer customHtmlSanitizer) {
@@ -253,7 +224,8 @@ public class EmlProcessingUtils {
return processed;
}
public String convertTextToHtml(String textBody, CustomHtmlSanitizer customHtmlSanitizer) {
public static String convertTextToHtml(
String textBody, CustomHtmlSanitizer customHtmlSanitizer) {
if (textBody == null) return "";
String html =
@@ -283,25 +255,129 @@ public class EmlProcessingUtils {
return html;
}
private void appendEnhancedStyles(StringBuilder html) {
html.append(
private static void appendEnhancedStyles(StringBuilder html) {
String css =
String.format(
Locale.ROOT,
"""
:root {
--font-family: %s;
--font-size: %dpx;
--line-height: %s;
--text-color: %s;
--bg-color: %s;
--border-color: %s;
--header-font-size: %dpx;
--meta-font-size: %dpx;
--attachment-bg: %s;
--attachment-border: %s;
--attachment-header-size: %dpx;
--attachment-detail-size: %dpx;
--note-font-size: %dpx;
body {
font-family: %s;
font-size: %dpx;
line-height: %s;
color: %s;
margin: 0;
padding: 16px;
background-color: %s;
}
.email-container {
width: 100%%;
max-width: 100%%;
margin: 0 auto;
}
.email-header {
padding-bottom: 10px;
border-bottom: 1px solid %s;
margin-bottom: 10px;
}
.email-header h1 {
margin: 0 0 10px 0;
font-size: %dpx;
font-weight: bold;
}
.email-meta div {
margin-bottom: 2px;
font-size: %dpx;
}
.email-body {
word-wrap: break-word;
}
.attachment-section {
margin-top: 15px;
padding: 10px;
background-color: %s;
border: 1px solid %s;
border-radius: 3px;
}
.attachment-section h3 {
margin: 0 0 8px 0;
font-size: %dpx;
}
.attachment-item {
padding: 5px 0;
}
.attachment-icon {
margin-right: 5px;
}
.attachment-details, .attachment-type {
font-size: %dpx;
color: #555555;
}
.attachment-inclusion-note, .attachment-info-note {
margin-top: 8px;
padding: 6px;
font-size: %dpx;
border-radius: 3px;
}
.attachment-inclusion-note {
background-color: #e6ffed;
border: 1px solid #d4f7dc;
color: #006420;
}
.attachment-info-note {
background-color: #fff9e6;
border: 1px solid #fff0c2;
color: #664d00;
}
.attachment-link-container {
display: flex;
align-items: center;
padding: 8px;
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 4px;
margin: 4px 0;
}
.attachment-link-container:hover {
background-color: #e9ecef;
}
.attachment-note {
font-size: %dpx;
color: #6c757d;
font-style: italic;
margin-left: 8px;
}
.no-content {
padding: 20px;
text-align: center;
color: #666;
font-style: italic;
}
.text-body {
white-space: pre-wrap;
}
img {
max-width: 100%%;
height: auto;
display: block;
}
""",
DEFAULT_FONT_FAMILY,
@@ -310,70 +386,29 @@ public class EmlProcessingUtils {
DEFAULT_TEXT_COLOR,
DEFAULT_BACKGROUND_COLOR,
DEFAULT_BORDER_COLOR,
DEFAULT_FONT_SIZE + 6,
DEFAULT_FONT_SIZE,
DEFAULT_FONT_SIZE + 4,
DEFAULT_FONT_SIZE - 1,
ATTACHMENT_BACKGROUND_COLOR,
ATTACHMENT_BORDER_COLOR,
DEFAULT_FONT_SIZE + 2,
DEFAULT_FONT_SIZE - 1,
DEFAULT_FONT_SIZE - 1));
DEFAULT_FONT_SIZE + 1,
DEFAULT_FONT_SIZE - 2,
DEFAULT_FONT_SIZE - 2,
DEFAULT_FONT_SIZE - 3);
html.append(loadEmailStyles());
html.append(css);
}
@Synchronized
private String loadEmailStyles() {
if (cachedCssContent != null) {
return cachedCssContent;
}
try {
ClassPathResource resource = new ClassPathResource(CSS_RESOURCE_PATH);
try (InputStream inputStream = resource.getInputStream()) {
cachedCssContent = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
return cachedCssContent;
}
} catch (IOException e) {
log.warn("Failed to load email CSS from resource, using fallback: {}", e.getMessage());
cachedCssContent = getFallbackStyles(); // Cache fallback to avoid repeated attempts
return cachedCssContent;
}
}
private String getFallbackStyles() {
return """
/* Minimal fallback - main CSS resource failed to load */
body {
font-family: var(--font-family, Helvetica, sans-serif);
font-size: var(--font-size, 12px);
line-height: var(--line-height, 1.4);
color: var(--text-color, #202124);
margin: 0;
padding: 20px;
word-wrap: break-word;
}
.email-container { max-width: 100%; }
.email-header { border-bottom: 1px solid #ccc; margin-bottom: 16px; padding-bottom: 12px; }
.email-header h1 { margin: 0 0 8px 0; font-size: 18px; }
.email-meta { font-size: 12px; color: #666; }
.email-body { line-height: 1.6; }
.attachment-section { margin-top: 20px; padding: 12px; background: #f5f5f5; border-radius: 4px; }
.attachment-item { padding: 6px 0; border-bottom: 1px solid #ddd; }
.no-content { padding: 20px; text-align: center; color: #888; font-style: italic; }
img { max-width: 100%; height: auto; }
""";
}
private void appendAttachmentsSection(
StringBuilder html, EmlParser.EmailContent content, EmlToPdfRequest request) {
html.append(String.format(Locale.ROOT, "<div class=\"attachment-section\">%n"));
private static void appendAttachmentsSection(
StringBuilder html,
EmlParser.EmailContent content,
EmlToPdfRequest request,
CustomHtmlSanitizer customHtmlSanitizer) {
html.append("<div class=\"attachment-section\">\n");
int displayedAttachmentCount =
content.getAttachmentCount() > 0
? content.getAttachmentCount()
: content.getAttachments().size();
html.append(
String.format(
Locale.ROOT, "<h3>Attachments (%d)</h3>%n", displayedAttachmentCount));
html.append("<h3>Attachments (").append(displayedAttachmentCount).append(")</h3>\n");
if (!content.getAttachments().isEmpty()) {
for (int i = 0; i < content.getAttachments().size(); i++) {
@@ -426,10 +461,10 @@ public class EmlProcessingUtils {
</div>
""");
}
html.append(String.format(Locale.ROOT, "</div>%n"));
html.append("</div>\n");
}
public HTMLToPdfRequest createHtmlRequest(EmlToPdfRequest request) {
public static HTMLToPdfRequest createHtmlRequest(EmlToPdfRequest request) {
HTMLToPdfRequest htmlRequest = new HTMLToPdfRequest();
if (request != null) {
@@ -440,7 +475,7 @@ public class EmlProcessingUtils {
return htmlRequest;
}
public String detectMimeType(String filename, String existingMimeType) {
public static String detectMimeType(String filename, String existingMimeType) {
if (existingMimeType != null && !existingMimeType.isEmpty()) {
return existingMimeType;
}
@@ -457,7 +492,7 @@ public class EmlProcessingUtils {
return MediaType.IMAGE_PNG_VALUE; // Default MIME type
}
public String decodeUrlEncoded(String encoded) {
public static String decodeUrlEncoded(String encoded) {
try {
return java.net.URLDecoder.decode(encoded, StandardCharsets.UTF_8);
} catch (Exception e) {
@@ -465,7 +500,7 @@ public class EmlProcessingUtils {
}
}
public String decodeMimeHeader(String encodedText) {
public static String decodeMimeHeader(String encodedText) {
if (encodedText == null || encodedText.trim().isEmpty()) {
return encodedText;
}
@@ -531,7 +566,7 @@ public class EmlProcessingUtils {
}
}
private String decodeQuotedPrintable(String encodedText, String charset) {
private static String decodeQuotedPrintable(String encodedText, String charset) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < encodedText.length(); i++) {
char c = encodedText.charAt(i);
@@ -574,7 +609,7 @@ public class EmlProcessingUtils {
}
}
public String escapeHtml(String text) {
public static String escapeHtml(String text) {
if (text == null) return "";
return text.replace("&", "&amp;")
.replace("<", "&lt;")
@@ -583,7 +618,7 @@ public class EmlProcessingUtils {
.replace("'", "&#39;");
}
public String sanitizeText(String text, CustomHtmlSanitizer customHtmlSanitizer) {
public static String sanitizeText(String text, CustomHtmlSanitizer customHtmlSanitizer) {
if (customHtmlSanitizer != null) {
return customHtmlSanitizer.sanitize(text);
} else {
@@ -591,7 +626,7 @@ public class EmlProcessingUtils {
}
}
public String simplifyHtmlContent(String htmlContent) {
public static String simplifyHtmlContent(String htmlContent) {
String simplified =
RegexPatternUtils.getInstance()
.getScriptTagPattern()
@@ -89,11 +89,6 @@ public class PDFToFile {
TempDirectory tempOutputDir = new TempDirectory(tempFileManager)) {
inputFile.transferTo(tempInputFile.getFile());
// Create unique subdirectory for pdftohtml output (collision-proof even if called
// multiple times)
Path pdftohtmlDir = Files.createTempDirectory(tempOutputDir.getPath(), "pdftohtml_");
String outputBasename = pdftohtmlDir.resolve("output").toString();
List<String> command =
new ArrayList<>(
Arrays.asList(
@@ -102,13 +97,15 @@ public class PDFToFile {
"-noframes",
"-c",
tempInputFile.getAbsolutePath(),
outputBasename));
pdfBaseName));
ProcessExecutorResult returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.PDFTOHTML)
.runCommandWithOutputHandling(command, pdftohtmlDir.toFile());
.runCommandWithOutputHandling(
command, tempOutputDir.getPath().toFile());
// Process HTML files to Markdown
File[] outputFiles = Objects.requireNonNull(pdftohtmlDir.toFile().listFiles());
File[] outputFiles =
Objects.requireNonNull(tempOutputDir.getPath().toFile().listFiles());
List<File> markdownFiles = new ArrayList<>();
// Convert HTML files to Markdown
@@ -118,7 +115,7 @@ public class PDFToFile {
String markdown = htmlToMarkdownConverter.convert(html);
String mdFileName = outputFile.getName().replace(".html", ".md");
File mdFile = new File(pdftohtmlDir.toFile(), mdFileName);
File mdFile = new File(tempOutputDir.getPath().toFile(), mdFileName);
Files.writeString(mdFile.toPath(), markdown);
markdownFiles.add(mdFile);
}
@@ -185,22 +182,18 @@ public class PDFToFile {
// Save the uploaded file to a temporary location
inputFile.transferTo(tempInputFile);
// Create unique subdirectory for pdftohtml output (collision-proof even if called
// multiple times)
Path pdftohtmlDir = Files.createTempDirectory(tempOutputDir, "pdftohtml_");
String outputBasename = pdftohtmlDir.resolve("output").toString();
// Run the pdftohtml command with complex output
List<String> command =
new ArrayList<>(
Arrays.asList(
"pdftohtml", "-c", tempInputFile.toString(), outputBasename));
"pdftohtml", "-c", tempInputFile.toString(), pdfBaseName));
ProcessExecutorResult returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.PDFTOHTML)
.runCommandWithOutputHandling(command, pdftohtmlDir.toFile());
.runCommandWithOutputHandling(command, tempOutputDir.toFile());
// Get output files
File[] outputFiles = Objects.requireNonNull(pdftohtmlDir.toFile().listFiles());
File[] outputFiles = Objects.requireNonNull(tempOutputDir.toFile().listFiles());
// Return output files in a ZIP archive
fileName = pdfBaseName + "ToHtml.zip";
@@ -261,6 +254,9 @@ public class PDFToFile {
Path tempInputFile = inputFileTemp.getPath();
Path tempOutputDir = outputDirTemp.getPath();
Path unoOutputFile =
tempOutputDir.resolve(
pdfBaseName + "." + resolvePrimaryExtension(outputFormat));
// Save the uploaded file to a temporary location
inputFile.transferTo(tempInputFile);
@@ -269,15 +265,8 @@ public class PDFToFile {
ProcessExecutorResult returnCode = null;
IOException unoconvertException = null;
Path unoOutputFile = null;
if (isUnoConvertEnabled()) {
try {
// Create output file only for unoconvert (it needs specific path)
unoOutputFile =
Files.createTempFile(
tempOutputDir,
"output_",
"." + resolvePrimaryExtension(outputFormat));
List<String> unoCommand =
buildUnoConvertCommand(
tempInputFile, unoOutputFile, outputFormat, libreOfficeFilter);
@@ -286,14 +275,6 @@ public class PDFToFile {
.runCommandWithOutputHandling(unoCommand);
} catch (IOException e) {
unoconvertException = e;
// Clean up temp file if unoconvert failed, so soffice doesn't see it
if (unoOutputFile != null && Files.exists(unoOutputFile)) {
try {
Files.delete(unoOutputFile);
} catch (IOException deleteException) {
log.debug("Failed to clean up temp file after unoconvert failure");
}
}
log.warn(
"Unoconvert command failed ({}). Falling back to soffice command.",
e.getMessage());
@@ -1,233 +0,0 @@
*, *::before, *::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
body {
font-family: var(--font-family, 'Helvetica, sans-serif');
font-size: var(--font-size, 12px);
line-height: var(--line-height, 1.4);
color: var(--text-color, #202124);
margin: 0;
padding: 20px 24px;
background-color: var(--bg-color, #ffffff);
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
}
.email-container {
width: 100%;
max-width: 100%;
margin: 0 auto;
}
.email-header {
padding-bottom: 16px;
border-bottom: 2px solid var(--border-color, #e8eaed);
margin-bottom: 20px;
}
.email-header h1 {
margin: 0 0 12px 0;
font-size: var(--header-font-size, 18px);
font-weight: 600;
color: #1a1a1a;
line-height: 1.3;
word-break: break-word;
}
.email-meta {
font-size: var(--meta-font-size, 12px);
color: #5f6368;
}
.email-meta div {
margin-bottom: 4px;
line-height: 1.5;
}
.email-meta strong {
color: #3c4043;
font-weight: 600;
min-width: 50px;
display: inline-block;
}
.email-body {
word-wrap: break-word;
overflow-wrap: break-word;
line-height: 1.6;
}
.email-body p {
margin: 0 0 1em 0;
}
.email-body a {
color: #1a73e8;
text-decoration: underline;
}
.email-body table {
border-collapse: collapse;
width: auto;
max-width: 100%;
margin: 8px 0;
}
.email-body td,
.email-body th {
padding: 8px 12px;
vertical-align: top;
border: 1px solid #e0e0e0;
}
.email-body ul,
.email-body ol {
margin: 0.5em 0;
padding-left: 2em;
}
.email-body li {
margin-bottom: 0.25em;
}
.email-body blockquote {
margin: 1em 0;
padding: 0 0 0 16px;
border-left: 3px solid #dadce0;
color: #5f6368;
}
.email-body pre,
.email-body code {
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 0.9em;
background-color: #f8f9fa;
border-radius: 3px;
}
.email-body pre {
padding: 12px;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
.email-body code {
padding: 2px 6px;
}
.email-body hr {
border: none;
border-top: 1px solid #e0e0e0;
margin: 1.5em 0;
}
.attachment-section {
margin-top: 24px;
padding: 16px;
background-color: var(--attachment-bg, #f9f9f9);
border: 1px solid var(--attachment-border, #eeeeee);
border-radius: 6px;
page-break-inside: avoid;
}
.attachment-section h3 {
margin: 0 0 12px 0;
font-size: var(--attachment-header-size, 14px);
font-weight: 600;
color: #3c4043;
}
.attachment-item {
padding: 8px 0;
border-bottom: 1px solid #eeeeee;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.attachment-item:last-child {
border-bottom: none;
}
.attachment-icon {
margin-right: 8px;
font-weight: bold;
color: #5f6368;
}
.attachment-name {
font-weight: 500;
color: #1a1a1a;
word-break: break-all;
}
.attachment-details,
.attachment-type {
font-size: var(--attachment-detail-size, 11px);
color: #5f6368;
margin-left: 8px;
}
.attachment-info-note {
margin-top: 12px;
padding: 10px 12px;
font-size: var(--note-font-size, 11px);
border-radius: 4px;
background-color: #e8f0fe;
border: 1px solid #d2e3fc;
color: #1967d2;
}
.attachment-info-note p {
margin: 0;
}
.no-content {
padding: 32px 20px;
text-align: center;
color: #80868b;
font-style: italic;
background-color: #f8f9fa;
border-radius: 6px;
}
.text-body {
white-space: pre-wrap;
word-wrap: break-word;
font-family: inherit;
line-height: 1.6;
}
img {
max-width: 100%;
height: auto;
display: block;
margin: 8px 0;
}
@media print {
body {
padding: 0;
font-size: 11pt;
}
.email-header {
page-break-after: avoid;
}
.attachment-section {
page-break-inside: avoid;
}
a {
text-decoration: none;
color: inherit;
}
}
.email-body div[class*="signature"],
.email-body table[class*="signature"] {
margin-top: 1.5em;
padding-top: 1em;
border-top: 1px solid #e0e0e0;
font-size: 0.95em;
color: #5f6368;
}
@@ -439,7 +439,9 @@ class EmlToPdfTest {
"binary data");
testEmailConversion(
emlContent, new String[] {"Attachment Only Test", "data.bin"}, true);
emlContent,
new String[] {"Attachment Only Test", "data.bin", "No content available"},
true);
}
@Test
@@ -467,13 +469,10 @@ class EmlToPdfTest {
}
@Test
@DisplayName("Should accept ISO-8859-1 charset declaration without errors")
@DisplayName("Should handle non-standard but valid character sets like ISO-8859-1")
void handleIso88591Charset() throws IOException {
// Note: Uses ASCII content to test charset header parsing without
// platform-dependent encoding issues. Actual charset decoding is
// handled by Simple Java Mail library which is thoroughly tested upstream.
String subject = "Subject with ISO-8859-1 charset";
String body = "Body content encoded in ISO-8859-1";
String subject = "Subject with special characters: ñ é ü";
String body = "Body with special characters: ñ é ü";
String emlContent =
createSimpleTextEmailWithCharset(
@@ -489,13 +488,8 @@ class EmlToPdfTest {
String htmlResult = EmlToPdf.convertEmlToHtml(emlBytes, request);
assertNotNull(htmlResult);
// Verify the core subject text is present (charset should be decoded properly)
assertTrue(
htmlResult.contains("Subject with ISO-8859-1 charset"),
"HTML should contain subject text");
assertTrue(
htmlResult.contains("Body content encoded in ISO-8859-1"),
"HTML should contain body text");
assertTrue(htmlResult.contains(subject));
assertTrue(htmlResult.contains(body));
}
@Test
+1 -10
View File
@@ -59,11 +59,10 @@ dependencies {
implementation project(':common')
implementation 'org.springframework.boot:spring-boot-starter-jetty'
implementation 'com.posthog.java:posthog:1.2.0'
implementation 'org.telegram:telegrambots:6.9.7.1'
implementation 'commons-io:commons-io:2.21.0'
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
implementation 'io.micrometer:micrometer-core:1.16.1'
implementation 'io.micrometer:micrometer-core:1.16.0'
implementation 'com.google.zxing:core:3.5.4'
implementation "org.commonmark:commonmark:$commonmarkVersion" // https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark-ext-gfm-tables:$commonmarkVersion"
@@ -208,14 +207,6 @@ tasks.register('npmInstall', Exec) {
println "node_modules not found, will install..."
return true
}
// if required devDependency is missing, reinstall
def iconifyPkg = new File(frontendDir, 'node_modules/@iconify-json/material-symbols/package.json')
if (!iconifyPkg.exists()) {
println "@iconify-json/material-symbols missing, will reinstall..."
return true
}
def packageJson = new File(frontendDir, 'package.json')
def packageLock = new File(frontendDir, 'package-lock.json')
def isOutdated = nodeModules.lastModified() < packageJson.lastModified() ||
@@ -1,18 +0,0 @@
package stirling.software.SPDF.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
@Configuration
@ConditionalOnProperty(prefix = "telegram", name = "enabled", havingValue = "true")
public class TelegramBotConfig {
@Bean
public TelegramBotsApi telegramBotsApi() throws TelegramApiException {
return new TelegramBotsApi(DefaultBotSession.class);
}
}
@@ -32,19 +32,16 @@ public class SettingsController {
@AutoJobPostMapping("/update-enable-analytics")
@Hidden
public ResponseEntity<Map<String, Object>> updateApiKey(@RequestParam Boolean enabled)
throws IOException {
public ResponseEntity<String> updateApiKey(@RequestParam Boolean enabled) throws IOException {
if (applicationProperties.getSystem().getEnableAnalytics() != null) {
return ResponseEntity.status(HttpStatus.ALREADY_REPORTED)
.body(
Map.of(
"message",
"Setting has already been set, To adjust please edit "
+ InstallationPathConfig.getSettingsPath()));
"Setting has already been set, To adjust please edit "
+ InstallationPathConfig.getSettingsPath());
}
GeneralUtils.saveKeyToSettings("system.enableAnalytics", enabled);
applicationProperties.getSystem().setEnableAnalytics(enabled);
return ResponseEntity.ok(Map.of("message", "Updated"));
return ResponseEntity.ok("Updated");
}
@GetMapping("/get-endpoints-status")
@@ -191,7 +191,7 @@ public class UIDataController {
}
private List<String> getAvailableTesseractLanguages() {
String tessdataDir = runtimePathConfig.getTessDataPath();
String tessdataDir = applicationProperties.getSystem().getTessdataDir();
java.io.File[] files = new java.io.File(tessdataDir).listFiles();
if (files == null) {
return Collections.emptyList();
@@ -10,7 +10,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.HtmlUtils;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
@@ -42,12 +41,12 @@ public class ConvertEmlToPDF {
@AutoJobPostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/eml/pdf")
@StandardPdfResponse
@Operation(
summary = "Convert EML/MSG to PDF",
summary = "Convert EML to PDF",
description =
"This endpoint converts EML (email) and MSG (Outlook) files to PDF format"
+ " with extensive customization options. Features include font settings,"
+ " image constraints, display modes, attachment handling, and HTML debug"
+ " output. Input: EML or MSG file, Output: PDF or HTML file. Type: SISO")
"This endpoint converts EML (email) files to PDF format with extensive"
+ " customization options. Features include font settings, image"
+ " constraints, display modes, attachment handling, and HTML debug output."
+ " Input: EML file, Output: PDF or HTML file. Type: SISO")
public ResponseEntity<byte[]> convertEmlToPdf(@ModelAttribute EmlToPdfRequest request) {
MultipartFile inputFile = request.getFileInput();
@@ -55,7 +54,7 @@ public class ConvertEmlToPDF {
// Validate input
if (inputFile.isEmpty()) {
log.error("No file provided for EML/MSG to PDF conversion.");
log.error("No file provided for EML to PDF conversion.");
return ResponseEntity.badRequest()
.body("No file provided".getBytes(StandardCharsets.UTF_8));
}
@@ -66,12 +65,12 @@ public class ConvertEmlToPDF {
.body("Please provide a valid filename".getBytes(StandardCharsets.UTF_8));
}
// Validate file type - support EML and MSG (Outlook) files
// Validate file type - support EML
String lowerFilename = originalFilename.toLowerCase(Locale.ROOT);
if (!lowerFilename.endsWith(".eml") && !lowerFilename.endsWith(".msg")) {
log.error("Invalid file type for EML/MSG to PDF: {}", originalFilename);
if (!lowerFilename.endsWith(".eml")) {
log.error("Invalid file type for EML to PDF: {}", originalFilename);
return ResponseEntity.badRequest()
.body("Please upload a valid EML or MSG file".getBytes(StandardCharsets.UTF_8));
.body("Please upload a valid EML file".getBytes(StandardCharsets.UTF_8));
}
String baseFilename = Filenames.toSimpleFileName(originalFilename); // Use Filenames utility
@@ -82,7 +81,7 @@ public class ConvertEmlToPDF {
if (request.isDownloadHtml()) {
try {
String htmlContent = EmlToPdf.convertEmlToHtml(fileBytes, request);
log.info("Successfully converted email to HTML: {}", originalFilename);
log.info("Successfully converted EML to HTML: {}", originalFilename);
return WebResponseUtils.bytesToWebResponse(
htmlContent.getBytes(StandardCharsets.UTF_8),
baseFilename + ".html",
@@ -96,11 +95,12 @@ public class ConvertEmlToPDF {
}
}
// Convert EML/MSG to PDF with enhanced options
// Convert EML to PDF with enhanced options
try {
byte[] pdfBytes =
EmlToPdf.convertEmlToPdf(
runtimePathConfig.getWeasyPrintPath(),
runtimePathConfig
.getWeasyPrintPath(), // Use configured WeasyPrint path
request,
fileBytes,
originalFilename,
@@ -115,19 +115,19 @@ public class ConvertEmlToPDF {
"PDF conversion failed - empty output"
.getBytes(StandardCharsets.UTF_8));
}
log.info("Successfully converted email to PDF: {}", originalFilename);
log.info("Successfully converted EML to PDF: {}", originalFilename);
return WebResponseUtils.bytesToWebResponse(
pdfBytes, baseFilename + ".pdf", MediaType.APPLICATION_PDF);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Email to PDF conversion was interrupted for {}", originalFilename, e);
log.error("EML to PDF conversion was interrupted for {}", originalFilename, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Conversion was interrupted".getBytes(StandardCharsets.UTF_8));
} catch (IllegalArgumentException e) {
String errorMessage = buildErrorMessage(e, originalFilename);
log.error(
"Email to PDF conversion failed for {}: {}",
"EML to PDF conversion failed for {}: {}",
originalFilename,
errorMessage,
e);
@@ -136,7 +136,7 @@ public class ConvertEmlToPDF {
} catch (RuntimeException e) {
String errorMessage = buildErrorMessage(e, originalFilename);
log.error(
"Email to PDF conversion failed for {}: {}",
"EML to PDF conversion failed for {}: {}",
originalFilename,
errorMessage,
e);
@@ -145,31 +145,27 @@ public class ConvertEmlToPDF {
}
} catch (IOException e) {
log.error("File processing error for email to PDF: {}", originalFilename, e);
log.error("File processing error for EML to PDF: {}", originalFilename, e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("File processing error".getBytes(StandardCharsets.UTF_8));
}
}
private static @NotNull String buildErrorMessage(Exception e, String originalFilename) {
String safeFilename = HtmlUtils.htmlEscape(originalFilename);
String exceptionMessage = e.getMessage();
String safeExceptionMessage =
exceptionMessage == null ? "Unknown error" : HtmlUtils.htmlEscape(exceptionMessage);
String errorMessage;
if (exceptionMessage != null && exceptionMessage.contains("Invalid EML")) {
if (e.getMessage() != null && e.getMessage().contains("Invalid EML")) {
errorMessage =
"Invalid EML file format. Please ensure you've uploaded a valid email"
+ " file ("
+ safeFilename
+ originalFilename
+ ").";
} else if (exceptionMessage != null && exceptionMessage.contains("WeasyPrint")) {
} else if (e.getMessage() != null && e.getMessage().contains("WeasyPrint")) {
errorMessage =
"PDF generation failed for "
+ safeFilename
+ originalFilename
+ ". This may be due to complex email formatting.";
} else {
errorMessage = "Conversion failed for " + safeFilename + ": " + safeExceptionMessage;
errorMessage = "Conversion failed for " + originalFilename + ": " + e.getMessage();
}
return errorMessage;
}
@@ -36,8 +36,6 @@ import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.RegexPatternUtils;
import stirling.software.common.util.TempDirectory;
import stirling.software.common.util.TempFileManager;
import stirling.software.common.util.WebResponseUtils;
@ConvertApi
@@ -49,7 +47,6 @@ public class ConvertOfficeController {
private final RuntimePathConfig runtimePathConfig;
private final CustomHtmlSanitizer customHtmlSanitizer;
private final EndpointConfiguration endpointConfiguration;
private final TempFileManager tempFileManager;
private boolean isUnoconvertAvailable() {
return endpointConfiguration.isGroupEnabled("Unoconvert")
@@ -71,24 +68,29 @@ public class ConvertOfficeController {
}
String extensionLower = extension.toLowerCase(Locale.ROOT);
// Create work directory - caller (processFileToPDF) is responsible for cleanup
String baseName = FilenameUtils.getBaseName(originalFilename);
if (baseName == null || baseName.isBlank()) {
baseName = "input";
}
// create temporary working directory
Path workDir = Files.createTempDirectory("office2pdf_");
Path inputPath = Files.createTempFile(workDir, "input_", "." + extensionLower);
Path outputPath = Files.createTempFile(workDir, "output_", ".pdf");
Path inputPath = workDir.resolve(baseName + "." + extensionLower);
Path outputPath = workDir.resolve(baseName + ".pdf");
// Check if the file is HTML and apply sanitization if needed
if ("html".equals(extensionLower) || "htm".equals(extensionLower)) {
// Read and sanitize HTML content
String htmlContent = new String(inputFile.getBytes(), StandardCharsets.UTF_8);
String sanitizedHtml = customHtmlSanitizer.sanitize(htmlContent);
Files.writeString(inputPath, sanitizedHtml, StandardCharsets.UTF_8);
} else {
// copy file content
Files.copy(inputFile.getInputStream(), inputPath, StandardCopyOption.REPLACE_EXISTING);
}
Path libreOfficeProfile = null;
try {
// Check if the file is HTML and apply sanitization if needed
if ("html".equals(extensionLower) || "htm".equals(extensionLower)) {
// Read and sanitize HTML content
String htmlContent = new String(inputFile.getBytes(), StandardCharsets.UTF_8);
String sanitizedHtml = customHtmlSanitizer.sanitize(htmlContent);
Files.writeString(inputPath, sanitizedHtml, StandardCharsets.UTF_8);
} else {
// copy file content
Files.copy(
inputFile.getInputStream(), inputPath, StandardCopyOption.REPLACE_EXISTING);
}
ProcessExecutorResult result;
// Run Unoconvert command
if (isUnoconvertAvailable()) {
@@ -107,23 +109,21 @@ public class ConvertOfficeController {
.runCommandWithOutputHandling(command);
} // Run soffice command
else {
try (TempDirectory libreOfficeProfileManager = new TempDirectory(tempFileManager)) {
Path libreOfficeProfile = libreOfficeProfileManager.getPath();
List<String> command = new ArrayList<>();
command.add(runtimePathConfig.getSOfficePath());
command.add("-env:UserInstallation=" + libreOfficeProfile.toUri().toString());
command.add("--headless");
command.add("--nologo");
command.add("--convert-to");
command.add("pdf:writer_pdf_Export");
command.add("--outdir");
command.add(workDir.toString());
command.add(inputPath.toString());
libreOfficeProfile = Files.createTempDirectory("libreoffice_profile_");
List<String> command = new ArrayList<>();
command.add(runtimePathConfig.getSOfficePath());
command.add("-env:UserInstallation=" + libreOfficeProfile.toUri().toString());
command.add("--headless");
command.add("--nologo");
command.add("--convert-to");
command.add("pdf:writer_pdf_Export");
command.add("--outdir");
command.add(workDir.toString());
command.add(inputPath.toString());
result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
.runCommandWithOutputHandling(command);
}
result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.LIBRE_OFFICE)
.runCommandWithOutputHandling(command);
}
// Check the result
@@ -162,12 +162,15 @@ public class ConvertOfficeController {
return outputPath.toFile();
} finally {
// Clean up the temporary input file (output and workDir cleaned by caller)
// Clean up the temporary files
try {
Files.deleteIfExists(inputPath);
} catch (IOException e) {
log.warn("Failed to delete temp input file: {}", inputPath, e);
}
if (libreOfficeProfile != null) {
FileUtils.deleteQuietly(libreOfficeProfile.toFile());
}
}
}
@@ -75,25 +75,10 @@ public class ConfigController {
String frontendUrl = applicationProperties.getSystem().getFrontendUrl();
configData.put("frontendUrl", frontendUrl != null ? frontendUrl : "");
// Add mobile scanner settings
// Add mobile scanner setting
configData.put(
"enableMobileScanner",
applicationProperties.getSystem().isEnableMobileScanner());
configData.put(
"mobileScannerConvertToPdf",
applicationProperties.getSystem().getMobileScannerSettings().isConvertToPdf());
configData.put(
"mobileScannerImageResolution",
applicationProperties
.getSystem()
.getMobileScannerSettings()
.getImageResolution());
configData.put(
"mobileScannerPageFormat",
applicationProperties.getSystem().getMobileScannerSettings().getPageFormat());
configData.put(
"mobileScannerStretchToFit",
applicationProperties.getSystem().getMobileScannerSettings().isStretchToFit());
// Extract values from ApplicationProperties
configData.put("appNameNavbar", applicationProperties.getUi().getAppNameNavbar());
@@ -31,7 +31,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.service.MobileScannerService;
import stirling.software.common.service.MobileScannerService.FileMetadata;
@@ -52,31 +51,9 @@ import stirling.software.common.service.MobileScannerService.FileMetadata;
public class MobileScannerController {
private final MobileScannerService mobileScannerService;
private final ApplicationProperties applicationProperties;
public MobileScannerController(
MobileScannerService mobileScannerService,
ApplicationProperties applicationProperties) {
public MobileScannerController(MobileScannerService mobileScannerService) {
this.mobileScannerService = mobileScannerService;
this.applicationProperties = applicationProperties;
}
/**
* Check if mobile scanner feature is enabled
*
* @return Error response if disabled, null if enabled
*/
private ResponseEntity<Map<String, Object>> checkFeatureEnabled() {
if (!applicationProperties.getSystem().isEnableMobileScanner()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(
Map.of(
"error",
"Mobile scanner feature is not enabled",
"enabled",
false));
}
return null;
}
/**
@@ -94,16 +71,10 @@ public class MobileScannerController {
description = "Session created successfully",
content = @Content(schema = @Schema(implementation = SessionInfoResponse.class)))
@ApiResponse(responseCode = "400", description = "Invalid session ID")
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
public ResponseEntity<Map<String, Object>> createSession(
@Parameter(description = "Session ID for QR code", required = true) @PathVariable
String sessionId) {
ResponseEntity<Map<String, Object>> featureCheck = checkFeatureEnabled();
if (featureCheck != null) {
return featureCheck;
}
try {
MobileScannerService.SessionInfo sessionInfo =
mobileScannerService.createSession(sessionId);
@@ -138,16 +109,10 @@ public class MobileScannerController {
description = "Session is valid",
content = @Content(schema = @Schema(implementation = SessionInfoResponse.class)))
@ApiResponse(responseCode = "404", description = "Session not found or expired")
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
public ResponseEntity<Map<String, Object>> validateSession(
@Parameter(description = "Session ID to validate", required = true) @PathVariable
String sessionId) {
ResponseEntity<Map<String, Object>> featureCheck = checkFeatureEnabled();
if (featureCheck != null) {
return featureCheck;
}
MobileScannerService.SessionInfo sessionInfo =
mobileScannerService.validateSession(sessionId);
@@ -182,7 +147,6 @@ public class MobileScannerController {
description = "Files uploaded successfully",
content = @Content(schema = @Schema(implementation = UploadResponse.class)))
@ApiResponse(responseCode = "400", description = "Invalid session ID or files")
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
@ApiResponse(responseCode = "500", description = "Upload failed")
public ResponseEntity<Map<String, Object>> uploadFiles(
@Parameter(description = "Session ID from QR code", required = true) @PathVariable
@@ -190,11 +154,6 @@ public class MobileScannerController {
@Parameter(description = "Files to upload", required = true) @RequestParam("files")
List<MultipartFile> files) {
ResponseEntity<Map<String, Object>> featureCheck = checkFeatureEnabled();
if (featureCheck != null) {
return featureCheck;
}
try {
if (files == null || files.isEmpty()) {
return ResponseEntity.badRequest().body(Map.of("error", "No files provided"));
@@ -235,16 +194,10 @@ public class MobileScannerController {
responseCode = "200",
description = "File list retrieved",
content = @Content(schema = @Schema(implementation = FileListResponse.class)))
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
public ResponseEntity<Map<String, Object>> getSessionFiles(
@Parameter(description = "Session ID", required = true) @PathVariable
String sessionId) {
ResponseEntity<Map<String, Object>> featureCheck = checkFeatureEnabled();
if (featureCheck != null) {
return featureCheck;
}
List<FileMetadata> files = mobileScannerService.getSessionFiles(sessionId);
Map<String, Object> response = new HashMap<>();
@@ -268,17 +221,12 @@ public class MobileScannerController {
description =
"Download a file that was uploaded to a session. File is automatically deleted after download.")
@ApiResponse(responseCode = "200", description = "File downloaded successfully")
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
@ApiResponse(responseCode = "404", description = "File or session not found")
public ResponseEntity<Resource> downloadFile(
@Parameter(description = "Session ID", required = true) @PathVariable String sessionId,
@Parameter(description = "Filename to download", required = true) @PathVariable
String filename) {
if (!applicationProperties.getSystem().isEnableMobileScanner()) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
try {
Path filePath = mobileScannerService.getFile(sessionId, filename);
@@ -320,16 +268,10 @@ public class MobileScannerController {
summary = "Delete a session",
description = "Manually delete a session and all its uploaded files")
@ApiResponse(responseCode = "200", description = "Session deleted successfully")
@ApiResponse(responseCode = "403", description = "Mobile scanner feature not enabled")
public ResponseEntity<Map<String, Object>> deleteSession(
@Parameter(description = "Session ID to delete", required = true) @PathVariable
String sessionId) {
ResponseEntity<Map<String, Object>> featureCheck = checkFeatureEnabled();
if (featureCheck != null) {
return featureCheck;
}
mobileScannerService.deleteSession(sessionId);
return ResponseEntity.ok(
@@ -204,65 +204,11 @@ public class VeraPDFService {
detectedFlavours = detectionParser.getFlavours();
}
// For PDF/A flavours, we need to validate first to check if PDF/A identification exists in
// XMP
// If declaredFlavour is PDF/A, do a quick validation to check for PDF/A identification
// schema
boolean hasValidPdfaMetadata = false;
if (isPdfaFlavour(declaredFlavour)) {
try (PDFAParser quickParser =
Foundries.defaultInstance()
.createParser(new ByteArrayInputStream(pdfBytes), declaredFlavour)) {
PDFAValidator quickValidator =
Foundries.defaultInstance().createValidator(declaredFlavour, false);
ValidationResult quickResult = quickValidator.validate(quickParser);
// Check if the document has the PDF/A Identification extension schema (clause
// 6.7.11, test 1)
// OR if it lacks XMP metadata entirely (clause 6.7.2, test 1)
// If either of these errors is present, the document is NOT a declared PDF/A
hasValidPdfaMetadata = true;
for (TestAssertion assertion : quickResult.getTestAssertions()) {
if (assertion.getStatus() == TestAssertion.Status.FAILED
&& assertion.getRuleId() != null) {
String clause = assertion.getRuleId().getClause();
int testNumber = assertion.getRuleId().getTestNumber();
// Missing XMP metadata entirely (clause 6.7.2, test 1)
if ("6.7.2".equals(clause) && testNumber == 1) {
hasValidPdfaMetadata = false;
log.debug(
"Document lacks XMP metadata (6.7.2): {}",
assertion.getMessage());
break;
}
// Missing PDF/A identification schema in XMP (clause 6.7.11, test 1)
if ("6.7.11".equals(clause) && testNumber == 1) {
hasValidPdfaMetadata = false;
log.debug(
"Document lacks PDF/A identification in XMP (6.7.11): {}",
assertion.getMessage());
break;
}
}
}
} catch (Exception e) {
log.debug("Error checking for PDF/A identification: {}", e.getMessage());
hasValidPdfaMetadata = false;
}
}
List<PDFAFlavour> flavoursToValidate = new ArrayList<>();
boolean hasPdfaDeclaration = isPdfaFlavour(declaredFlavour) && hasValidPdfaMetadata;
boolean hasPdfaDeclaration = isPdfaFlavour(declaredFlavour);
if (declaredFlavour != null) {
boolean isDeclaredPdfa = isPdfaFlavour(declaredFlavour);
if (isDeclaredPdfa && hasPdfaDeclaration) {
flavoursToValidate.add(declaredFlavour);
} else if (!isDeclaredPdfa) {
flavoursToValidate.add(declaredFlavour);
}
flavoursToValidate.add(declaredFlavour);
}
for (PDFAFlavour flavour : detectedFlavours) {
@@ -1,20 +0,0 @@
package stirling.software.SPDF.service.telegram;
/**
* Enumeration representing different feedback types for Telegram service.
*
* @since 2.2.x
*/
public enum FeedbackEnum {
/** Indicates that the provided document is not valid. */
NO_VALID_DOCUMENT,
/** Represents a generic error message. */
ERROR_MESSAGE,
/** Indicates that an error occurred during processing. */
ERROR_PROCESSING,
/** Indicates that processing is ongoing. */
PROCESSING
}
@@ -1,524 +0,0 @@
package stirling.software.SPDF.service.telegram;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.api.methods.GetFile;
import org.telegram.telegrambots.meta.api.methods.send.SendDocument;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Chat;
import org.telegram.telegrambots.meta.api.objects.Document;
import org.telegram.telegrambots.meta.api.objects.File;
import org.telegram.telegrambots.meta.api.objects.InputFile;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.configuration.RuntimePathConfig;
import stirling.software.common.model.ApplicationProperties;
/**
* Telegram bot that processes incoming files through a defined pipeline.
*
* @since 2.2.x
*/
@Slf4j
@Component
@ConditionalOnProperty(prefix = "telegram", name = "enabled", havingValue = "true")
public class TelegramPipelineBot extends TelegramLongPollingBot {
private static final String CHAT_PRIVATE = "private";
private static final String CHAT_GROUP = "group";
private static final String CHAT_SUPERGROUP = "supergroup";
private static final String CHAT_CHANNEL = "channel";
private static final Set<String> SUPPORTED_CHAT_TYPES =
Set.of(CHAT_PRIVATE, CHAT_GROUP, CHAT_SUPERGROUP, CHAT_CHANNEL);
private static final Set<String> ALLOWED_MIME_TYPES = Set.of("application/pdf");
private final Object pipelinePollMonitor = new Object();
private final ApplicationProperties.Telegram telegramProperties;
private final RuntimePathConfig runtimePathConfig;
private final TelegramBotsApi telegramBotsApi;
public TelegramPipelineBot(
ApplicationProperties applicationProperties,
RuntimePathConfig runtimePathConfig,
TelegramBotsApi telegramBotsApi) {
super(applicationProperties.getTelegram().getBotToken());
this.telegramProperties = applicationProperties.getTelegram();
this.runtimePathConfig = runtimePathConfig;
this.telegramBotsApi = telegramBotsApi;
}
@PostConstruct
public void register() {
if (StringUtils.isAnyBlank(getBotUsername(), getBotToken())) {
log.warn("Telegram bot disabled because botToken or botUsername is not configured");
return;
}
try {
telegramBotsApi.registerBot(this);
log.info("Telegram pipeline bot registered as {}", getBotUsername());
} catch (TelegramApiException e) {
log.error("Failed to register Telegram bot", e);
}
}
@Override
public void onUpdateReceived(Update update) {
Message message = extractMessage(update);
if (message == null) {
return;
}
Chat chat = message.getChat();
if (chat == null || !isSupportedChatType(chat.getType())) {
log.info(
"Ignoring message {}, unsupported chat type {}",
message.getMessageId(),
chat != null ? chat.getType() : "null");
return;
}
if (!isAuthorized(message, chat)) {
return;
}
if (update.hasMessage() && update.getMessage().hasText()) {
String messageText = update.getMessage().getText();
long chatId = update.getMessage().getChatId();
if ("/start".equals(messageText)) {
sendMessage(
chatId,
"""
Welcome to the SPDF Telegram Bot!
To get started, please send me a PDF document that you would like to process.
Make sure the document is in PDF format.
Once I receive your document, I'll begin processing it through the pipeline.
""");
return;
}
}
if (message.hasDocument()) {
handleIncomingFile(message);
return;
}
if (feedback(FeedbackEnum.NO_VALID_DOCUMENT, chat.getType())) {
sendMessage(
chat.getId(),
"No valid file found in the message. Please send a document to process.");
}
}
private boolean feedback(FeedbackEnum feedbackEnum, String chatType) {
return switch (feedbackEnum) {
case NO_VALID_DOCUMENT ->
switch (chatType) {
case CHAT_CHANNEL ->
telegramProperties.getFeedback().getChannel().getNoValidDocument();
case CHAT_PRIVATE ->
telegramProperties.getFeedback().getUser().getNoValidDocument();
default -> true;
};
case ERROR_MESSAGE ->
switch (chatType) {
case CHAT_CHANNEL ->
telegramProperties.getFeedback().getChannel().getErrorMessage();
case CHAT_PRIVATE ->
telegramProperties.getFeedback().getUser().getErrorMessage();
default -> true;
};
case ERROR_PROCESSING ->
switch (chatType) {
case CHAT_CHANNEL ->
telegramProperties.getFeedback().getChannel().getErrorProcessing();
case CHAT_PRIVATE ->
telegramProperties.getFeedback().getUser().getErrorProcessing();
default -> true;
};
case PROCESSING ->
switch (chatType) {
case CHAT_CHANNEL ->
telegramProperties.getFeedback().getChannel().getProcessing();
case CHAT_PRIVATE ->
telegramProperties.getFeedback().getUser().getProcessing();
default -> true;
};
default -> true;
};
}
// ---------------------------
// Message Extraction / Chat Type
// ---------------------------
private Message extractMessage(Update update) {
if (update.hasMessage()) return update.getMessage();
if (update.hasChannelPost()) return update.getChannelPost();
return null;
}
private boolean isSupportedChatType(String type) {
return type != null && SUPPORTED_CHAT_TYPES.contains(type);
}
// ---------------------------
// Authorization
// ---------------------------
private boolean isAuthorized(Message message, Chat chat) {
if (!(telegramProperties.getEnableAllowUserIDs()
|| telegramProperties.getEnableAllowChannelIDs())) {
return true;
}
return switch (chat.getType()) {
case CHAT_CHANNEL -> checkChannelAccess(message, chat);
case CHAT_PRIVATE -> checkUserAccess(message, chat);
case CHAT_GROUP, CHAT_SUPERGROUP -> true; // groups allowed by default
default -> false;
};
}
private boolean checkUserAccess(Message message, Chat chat) {
if (!telegramProperties.getEnableAllowUserIDs()) return true;
User from = message.getFrom();
List<Long> allow = telegramProperties.getAllowUserIDs();
if (allow.isEmpty()) {
log.warn("No allowed user IDs configured - allowing all users.");
return true;
}
if (from == null || !allow.contains(from.getId())) {
log.info(
"Rejecting user {} in private chat {}",
from != null ? from.getId() : "unknown",
chat.getId());
if (feedback(FeedbackEnum.ERROR_MESSAGE, chat.getType())) {
sendMessage(chat.getId(), "You are not authorized to use this bot.");
}
return false;
}
return true;
}
private boolean checkChannelAccess(Message message, Chat chat) {
if (!telegramProperties.getEnableAllowChannelIDs()) return true;
Chat senderChat = message.getSenderChat();
List<Long> allow = telegramProperties.getAllowChannelIDs();
if (allow.isEmpty()) {
log.warn("No allowed channel IDs configured - allowing all channels.");
return true;
}
if (senderChat == null || !allow.contains(senderChat.getId())) {
log.info(
"Rejecting channel {} in chat {}",
senderChat != null ? senderChat.getId() : "unknown",
chat.getId());
if (feedback(FeedbackEnum.ERROR_MESSAGE, chat.getType())) {
sendMessage(chat.getId(), "This channel is not authorized to use this bot.");
}
return false;
}
return true;
}
// ---------------------------
// File Handling
// ---------------------------
private void handleIncomingFile(Message message) {
Long chatId = message.getChatId();
Document doc = message.getDocument();
String chatType = message.getChat().getType();
if (doc == null) {
if (feedback(FeedbackEnum.NO_VALID_DOCUMENT, chatType)) {
sendMessage(chatId, "No document found.");
}
return;
}
if (doc.getMimeType() != null
&& !ALLOWED_MIME_TYPES.contains(doc.getMimeType().toLowerCase())) {
if (feedback(FeedbackEnum.NO_VALID_DOCUMENT, chatType)) {
sendMessage(
chatId,
"Unsupported MIME type: "
+ doc.getMimeType()
+ "\nAllowed: "
+ String.join(", ", ALLOWED_MIME_TYPES));
}
return;
}
if (!hasJsonConfig(chatId)) {
if (feedback(FeedbackEnum.ERROR_PROCESSING, chatType)) {
sendMessage(
chatId,
"No JSON configuration file found in the pipeline inbox folder. Please"
+ " contact the administrator.");
}
return;
}
try {
if (!CHAT_CHANNEL.equalsIgnoreCase(chatType)
&& feedback(FeedbackEnum.PROCESSING, chatType)) {
sendMessage(chatId, "File received. Starting processing...");
}
PipelineFileInfo info = downloadMessageFile(message);
List<Path> outputs = waitForPipelineOutputs(info);
if (outputs.isEmpty()) {
if (feedback(FeedbackEnum.ERROR_PROCESSING, chatType)) {
sendMessage(
chatId,
"No results were found in the pipeline output folder. Check"
+ " configuration.");
}
return;
}
for (Path file : outputs) {
SendDocument out = new SendDocument();
out.setChatId(chatId);
out.setDocument(new InputFile(file.toFile(), file.getFileName().toString()));
execute(out);
}
} catch (TelegramApiException e) {
log.error("Telegram API error", e);
if (feedback(FeedbackEnum.ERROR_MESSAGE, chatType)) {
sendMessage(chatId, "Telegram API error occurred.");
}
} catch (IOException e) {
log.error("IO error", e);
if (feedback(FeedbackEnum.ERROR_MESSAGE, chatType)) {
sendMessage(chatId, "An IO error occurred.");
}
} catch (Exception e) {
log.error("Unexpected error", e);
if (feedback(FeedbackEnum.ERROR_MESSAGE, chatType)) {
sendMessage(chatId, "Unexpected error occurred.");
}
}
}
private PipelineFileInfo downloadMessageFile(Message message)
throws TelegramApiException, IOException {
Document document = message.getDocument();
String filename = document.getFileName();
String name =
StringUtils.isNotBlank(filename) ? filename : document.getFileUniqueId() + ".bin";
return downloadFile(document.getFileId(), name, message);
}
private PipelineFileInfo downloadFile(String fileId, String originalName, Message message)
throws TelegramApiException, IOException {
Long chatId = message.getChatId();
Path inboxFolder = getInboxFolder(chatId);
GetFile getFile = new GetFile(fileId);
File tgFile = execute(getFile);
if (tgFile == null || StringUtils.isBlank(tgFile.getFilePath())) {
throw new IOException("Telegram did not return a file path.");
}
URL url = buildDownloadUrl(tgFile.getFilePath());
String base = FilenameUtils.getBaseName(originalName) + "-" + UUID.randomUUID();
String ext = FilenameUtils.getExtension(originalName);
String outFile = ext.isBlank() ? base : base + "." + ext;
Path targetFile = inboxFolder.resolve(outFile);
try (InputStream in = url.openStream()) {
Files.copy(in, targetFile);
}
log.info("Saved Telegram file {} to {}", originalName, targetFile);
return new PipelineFileInfo(targetFile, base, Instant.now());
}
private URL buildDownloadUrl(String filePath) throws MalformedURLException {
try {
URI uri =
new URI(
"https",
"api.telegram.org",
"/file/bot" + getBotToken() + "/" + filePath,
null);
return uri.toURL();
} catch (URISyntaxException e) {
throw new MalformedURLException("Failed to build Telegram download URL");
} catch (MalformedURLException e) {
MalformedURLException sanitized =
new MalformedURLException("Failed to build Telegram download URL");
sanitized.initCause(e);
throw sanitized;
}
}
// ---------------------------
// Inbox-Ordner & JSON-Check
// ---------------------------
private Path getInboxFolder(Long chatId) throws IOException {
Path baseInbox =
Paths.get(
runtimePathConfig.getPipelineWatchedFoldersPath(),
telegramProperties.getPipelineInboxFolder());
Files.createDirectories(baseInbox);
Path inboxFolder =
telegramProperties.getCustomFolderSuffix()
? baseInbox.resolve(chatId.toString())
: baseInbox;
Files.createDirectories(inboxFolder);
return inboxFolder;
}
private boolean hasJsonConfig(Long chatId) {
try {
Path inboxFolder = getInboxFolder(chatId);
try (Stream<Path> s = Files.list(inboxFolder)) {
return s.anyMatch(p -> p.toString().endsWith(".json"));
}
} catch (IOException e) {
log.error("Failed to check JSON config for chat {}", chatId, e);
return false;
}
}
// ---------------------------
// Pipeline polling
// ---------------------------
private List<Path> waitForPipelineOutputs(PipelineFileInfo info) throws IOException {
Path finishedDir = Paths.get(runtimePathConfig.getPipelineFinishedFoldersPath());
Files.createDirectories(finishedDir);
Instant start = info.savedAt();
Duration timeout = Duration.ofSeconds(telegramProperties.getProcessingTimeoutSeconds());
Duration poll = Duration.ofMillis(telegramProperties.getPollingIntervalMillis());
List<Path> results = new ArrayList<>();
while (Duration.between(start, Instant.now()).compareTo(timeout) <= 0) {
try (Stream<Path> s = Files.list(finishedDir)) {
results =
s.filter(Files::isRegularFile)
.filter(path -> matchesBaseName(info.uniqueBaseName(), path))
.filter(path -> isNewerThan(path, start))
.sorted(Comparator.comparing(Path::toString))
.toList();
}
if (!results.isEmpty()) {
break;
}
synchronized (pipelinePollMonitor) {
try {
pipelinePollMonitor.wait(poll.toMillis());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
return results;
}
private boolean matchesBaseName(String base, Path file) {
return file.getFileName().toString().contains(base);
}
private boolean isNewerThan(Path path, Instant since) {
try {
return Files.getLastModifiedTime(path).toInstant().isAfter(since);
} catch (IOException e) {
log.info("Could not read modification time for {}", path);
return false;
}
}
// ---------------------------
// Messaging
// ---------------------------
private void sendMessage(Long chatId, String text) {
if (chatId == null) return;
SendMessage msg = new SendMessage();
msg.setChatId(chatId);
msg.setText(text);
try {
execute(msg);
} catch (TelegramApiException e) {
log.warn("Failed to send message to {}", chatId, e);
}
}
private record PipelineFileInfo(Path originalFile, String uniqueBaseName, Instant savedAt) {}
@Override
public String getBotUsername() {
return telegramProperties.getBotUsername();
}
@Override
public String getBotToken() {
return telegramProperties.getBotToken();
}
}
@@ -16,30 +16,30 @@ security:
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
loginMethod: all # Accepts values like 'all' and 'normal'(only Login with Username/Password), 'oauth2'(only Login with OAuth2) or 'saml2'(only Login with SAML2)
initialLogin:
username: "" # initial username for the first login
password: "" # initial password for the first login
username: '' # initial username for the first login
password: '' # initial password for the first login
oauth2:
enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
client:
keycloak:
issuer: "" # URL of the Keycloak realm's OpenID Connect Discovery endpoint
clientId: "" # client ID for Keycloak OAuth2
clientSecret: "" # client secret for Keycloak OAuth2
issuer: '' # URL of the Keycloak realm's OpenID Connect Discovery endpoint
clientId: '' # client ID for Keycloak OAuth2
clientSecret: '' # client secret for Keycloak OAuth2
scopes: openid, profile, email # scopes for Keycloak OAuth2
useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2. Available options are: [email | name | given_name | family_name | preferred_name]
google:
clientId: "" # client ID for Google OAuth2
clientSecret: "" # client secret for Google OAuth2
clientId: '' # client ID for Google OAuth2
clientSecret: '' # client secret for Google OAuth2
scopes: email, profile # scopes for Google OAuth2
useAsUsername: email # field to use as the username for Google OAuth2. Available options are: [email | name | given_name | family_name]
github:
clientId: "" # client ID for GitHub OAuth2
clientSecret: "" # client secret for GitHub OAuth2
clientId: '' # client ID for GitHub OAuth2
clientSecret: '' # client secret for GitHub OAuth2
scopes: read:user # scope for GitHub OAuth2
useAsUsername: login # field to use as the username for GitHub OAuth2. Available options are: [email | login | name]
issuer: "" # set to any Provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint
clientId: "" # client ID from your Provider
clientSecret: "" # client secret from your Provider
issuer: '' # set to any Provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint
clientId: '' # client ID from your Provider
clientSecret: '' # client secret from your Provider
autoCreateUser: true # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
useAsUsername: email # default is 'email'; custom fields can be used as the username
@@ -47,14 +47,14 @@ security:
provider: google # set this to your OAuth Provider's name, e.g., 'google' or 'keycloak'
saml2:
enabled: false # Only enabled for paid enterprise clients (enterpriseEdition.enabled must be true)
provider: "" # The name of your Provider
provider: '' # The name of your Provider
autoCreateUser: true # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
registrationId: stirling # The name of your Service Provider (SP) app name. Should match the name in the path for your SSO & SLO URLs
idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata # The uri for your Provider's metadata
idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml # The URL for initiating SSO. Provided by your Provider
idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml # The URL for initiating SLO. Provided by your Provider
idpIssuer: "" # The ID of your Provider
idpIssuer: '' # The ID of your Provider
idpCert: classpath:okta.cert # The certificate your Provider will use to authenticate your app's SAML authentication requests. Provided by your Provider
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
@@ -110,45 +110,21 @@ mail:
enableInvites: false # set to 'true' to enable email invites for user management (requires mail.enabled and security.enableLogin)
host: smtp.example.com # SMTP server hostname
port: 587 # SMTP server port
username: "" # SMTP server username
password: "" # SMTP server password
from: "" # sender email address
username: '' # SMTP server username
password: '' # SMTP server password
from: '' # sender email address
startTlsEnable: true # enable STARTTLS (explicit TLS upgrade after connecting) when supported by the SMTP server
startTlsRequired: false # require STARTTLS; connection fails if the upgrade command is not supported
sslEnable: false # enable SSL/TLS wrapper for implicit TLS (typically used with port 465)
sslTrust: "" # optional trusted host override, e.g. "smtp.example.com" or "*"; defaults to "*" (trust all) when empty
sslTrust: '' # optional trusted host override, e.g. "smtp.example.com" or "*"; defaults to "*" (trust all) when empty
sslCheckServerIdentity: false # enable hostname verification when using SSL/TLS
telegram:
enabled: false # set to 'true' to enable Telegram bot integration
botToken: "" # Telegram bot token obtained from BotFather
botUsername: "" # Telegram bot username (without @)
pipelineInboxFolder: telegram # Name of the pipeline inbox folder for Telegram uploads
customFolderSuffix: true # set to 'true' to allow users to specify custom target folders via UserID
enableAllowUserIDs: true # set to 'true' to restrict access to specific Telegram user IDs
allowUserIDs: [] # List of allowed Telegram user IDs (e.g. [123456789, 987654321]). Leave empty to allow all users.
enableAllowChannelIDs: true # set to 'true' to restrict access to specific Telegram channel IDs
allowChannelIDs: [] # List of allowed Telegram channel IDs (e.g. [-1001234567890, -1009876543210]). Leave empty to allow all channels.
processingTimeoutSeconds: 180 # Maximum time in seconds to wait for processing a Telegram request
pollingIntervalMillis: 2000 # Interval in milliseconds between polling for new messages
feedback:
channel:
noValidDocument: true # set to 'false' to hide/suppress feedback messages in channels (to avoid spam)
errorProcessing: true # set to 'false' to hide/suppress feedback messages in channels (to avoid spam)
errorMessage: true # set to 'false' to hide/suppress error messages in channels (to avoid spam)
processing: true # set to 'false' to hide/suppress processing messages in channels (to avoid spam)
user:
noValidDocument: true # set to 'false' to hide/suppress feedback messages to users (to avoid spam)
errorProcessing: true # set to 'false' to hide/suppress feedback messages to users (to avoid spam)
errorMessage: true # set to 'false' to hide/suppress error messages to users (to avoid spam)
processing: true # set to 'false' to hide/suppress processing messages to users (to avoid spam)
legal:
termsAndConditions: https://www.stirling.com/legal/terms-of-service # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
privacyPolicy: https://www.stirling.com/legal/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
accessibilityStatement: "" # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
cookiePolicy: "" # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
impressum: "" # URL to the impressum of your application (e.g. https://example.com/impressum). Empty string to disable or filename to load from local file in static folder
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
impressum: '' # URL to the impressum of your application (e.g. https://example.com/impressum). Empty string to disable or filename to load from local file in static folder
system:
defaultLocale: en-US # set the default language (e.g. 'de-DE', 'fr-FR', etc)
@@ -167,14 +143,9 @@ system:
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
maxDPI: 500 # Maximum allowed DPI for PDF to image conversion
corsAllowedOrigins: [] # List of allowed origins for CORS (e.g. ['http://localhost:5173', 'https://app.example.com']). Leave empty to disable CORS. For local development with frontend on port 5173, add 'http://localhost:5173'
backendUrl: "" # Backend base URL for SAML/OAuth/API callbacks (e.g. 'http://localhost:8080' for dev, 'https://api.example.com' for production). REQUIRED for SSO authentication to work correctly. This is where your IdP will send SAML responses and OAuth callbacks. Leave empty to default to 'http://localhost:8080' in development.
frontendUrl: "" # Frontend URL for invite email links (e.g. 'https://app.example.com'). Optional - if not set, will use backendUrl. This is the URL users click in invite emails.
backendUrl: '' # Backend base URL for SAML/OAuth/API callbacks (e.g. 'http://localhost:8080' for dev, 'https://api.example.com' for production). REQUIRED for SSO authentication to work correctly. This is where your IdP will send SAML responses and OAuth callbacks. Leave empty to default to 'http://localhost:8080' in development.
frontendUrl: '' # Frontend URL for invite email links (e.g. 'https://app.example.com'). Optional - if not set, will use backendUrl. This is the URL users click in invite emails.
enableMobileScanner: false # Enable mobile phone QR code upload feature. Requires frontendUrl to be configured.
mobileScannerSettings:
convertToPdf: true # Automatically convert uploaded images to PDF format. If false, images are kept as-is.
imageResolution: full # Image resolution for mobile uploads: 'full' (original size) or 'reduced' (max 1200px on longest side). Only applies when convertToPdf is true.
pageFormat: A4 # Page format for converted PDFs: 'keep' (original image dimensions), 'A4' (A4 page size), or 'letter' (US Letter page size). Only applies when convertToPdf is true.
stretchToFit: false # Whether to stretch images to fill the entire page (may distort aspect ratio). If false, images are centered with preserved aspect ratio. Only applies when convertToPdf is true.
serverCertificate:
enabled: true # Enable server-side certificate for "Sign with Stirling-PDF" option
organizationName: Stirling-PDF # Organization name for generated certificates
@@ -186,14 +157,14 @@ system:
level: MEDIUM # Security level: MAX (whitelist only), MEDIUM (block internal networks), OFF (no restrictions)
allowedDomains: [] # Whitelist of allowed domains (e.g. ['cdn.example.com', 'images.google.com'])
blockedDomains: [] # Additional domains to block (e.g. ['evil.com', 'malicious.org'])
internalTlds: [".local", ".internal", ".corp", ".home"] # Block domains with these TLD patterns
internalTlds: ['.local', '.internal', '.corp', '.home'] # Block domains with these TLD patterns
blockPrivateNetworks: true # Block RFC 1918 private networks (10.x.x.x, 192.168.x.x, 172.16-31.x.x)
blockLocalhost: true # Block localhost and loopback addresses (127.x.x.x, ::1)
blockLinkLocal: true # Block link-local addresses (169.254.x.x, fe80::/10)
blockCloudMetadata: true # Block cloud provider metadata endpoints (169.254.169.254)
datasource:
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
customDatabaseUrl: "" # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
customDatabaseUrl: '' # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
username: postgres # set the database username
password: postgres # set the database password
type: postgresql # the type of the database to set (e.g. 'h2', 'postgresql')
@@ -202,29 +173,29 @@ system:
name: postgres # set the name of your database. Should match the name of the database you create
customPaths:
pipeline:
watchedFoldersDir: "" # Defaults to /pipeline/watchedFolders
finishedFoldersDir: "" # Defaults to /pipeline/finishedFolders
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
operations:
weasyprint: "" # Defaults to /opt/venv/bin/weasyprint
unoconvert: "" # Defaults to /opt/venv/bin/unoconvert
calibre: "" # Defaults to /usr/bin/ebook-convert
ocrmypdf: "" # Defaults to /usr/bin/ocrmypdf
soffice: "" # Defaults to /usr/bin/soffice
fileUploadLimit: "" # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
calibre: '' # Defaults to /usr/bin/ebook-convert
ocrmypdf: '' # Defaults to /usr/bin/ocrmypdf
soffice: '' # Defaults to /usr/bin/soffice
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
tempFileManagement:
baseTmpDir: "" # Defaults to java.io.tmpdir/stirling-pdf
libreofficeDir: "" # Defaults to tempFileManagement.baseTmpDir/libreoffice
systemTempDir: "" # Only used if cleanupSystemTemp is true
baseTmpDir: '' # Defaults to java.io.tmpdir/stirling-pdf
libreofficeDir: '' # Defaults to tempFileManagement.baseTmpDir/libreoffice
systemTempDir: '' # Only used if cleanupSystemTemp is true
prefix: stirling-pdf- # Prefix for temp file names
maxAgeHours: 24 # Maximum age in hours before temp files are cleaned up
cleanupIntervalMinutes: 30 # How often to run cleanup (in minutes)
startupCleanup: true # Clean up old temp files on startup
cleanupSystemTemp: false # Whether to clean broader system temp directory
databaseBackup:
cron: "0 0 0 * * ?" # Cron expression for automatic database backups "0 0 0 * * ?" daily at midnight
cron: '0 0 0 * * ?' # Cron expression for automatic database backups "0 0 0 * * ?" daily at midnight
ui:
appNameNavbar: "" # name displayed on the navigation bar
appNameNavbar: '' # name displayed on the navigation bar
logoStyle: classic # Options: 'classic' (default - classic S icon) or 'modern' (minimalist logo)
languages: [] # If empty, all languages are enabled. To display only German and Polish ["de_DE", "pl_PL"]. British English is always enabled.
@@ -7,13 +7,6 @@
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-classic",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.23",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
@@ -21,13 +14,6 @@
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.23",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "com.adobe.xmp:xmpcore",
"moduleUrl": "https://www.adobe.com/devnet/xmp/library/eula-xmp-library-java.html",
@@ -112,20 +98,6 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base",
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base",
"moduleVersion": "2.19.2",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider",
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider",
"moduleVersion": "2.19.2",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.fasterxml.jackson.module:jackson-module-jakarta-xmlbind-annotations",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
@@ -133,13 +105,6 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.fasterxml.jackson.module:jackson-module-jaxb-annotations",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
"moduleVersion": "2.19.2",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
@@ -167,20 +132,6 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.github.bbottema:jetbrains-runtime-annotations",
"moduleUrl": "https://github.com/bbottema/jetbrains-runtime-nullability-annotations",
"moduleVersion": "1.0.2",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.github.bbottema:rtf-to-html",
"moduleUrl": "http:///github.com/bbottema/rtf-to-html",
"moduleVersion": "1.1.1",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.github.ben-manes.caffeine:caffeine",
"moduleUrl": "https://github.com/ben-manes/caffeine",
@@ -221,6 +172,13 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.code.gson:gson",
"moduleUrl": "https://github.com/google/gson",
"moduleVersion": "2.13.2",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.errorprone:error_prone_annotations",
"moduleUrl": "https://errorprone.info/error_prone_annotations",
@@ -228,6 +186,13 @@
"moduleLicense": "Apache 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.errorprone:error_prone_annotations",
"moduleUrl": "https://errorprone.info/error_prone_annotations",
"moduleVersion": "2.41.0",
"moduleLicense": "Apache 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.guava:failureaccess",
"moduleUrl": "https://github.com/google/guava/",
@@ -258,7 +223,7 @@
{
"moduleName": "com.google.zxing:core",
"moduleUrl": "https://github.com/zxing/zxing/core",
"moduleVersion": "3.5.4",
"moduleVersion": "3.5.3",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -330,13 +295,6 @@
"moduleLicense": "Apache 2",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.pivovarit:throwing-function",
"moduleUrl": "https://github.com/pivovarit/throwing-function",
"moduleVersion": "1.6.1",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.posthog.java:posthog",
"moduleUrl": "http://github.com/PostHog/posthog-java",
@@ -344,20 +302,6 @@
"moduleLicense": "MIT License",
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
},
{
"moduleName": "com.sanctionco.jmail:jmail",
"moduleUrl": "https://github.com/RohanNagar/jmail",
"moduleVersion": "1.6.3",
"moduleLicense": "MIT License",
"moduleLicenseUrl": "https://opensource.org/licenses/mit-license.php"
},
{
"moduleName": "com.sun.activation:jakarta.activation",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "1.2.2",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "com.sun.istack:istack-commons-runtime",
"moduleUrl": "https://www.eclipse.org",
@@ -365,97 +309,69 @@
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "com.sun.xml.bind:jaxb-core",
"moduleUrl": "http://www.oracle.com/",
"moduleVersion": "2.3.0.1",
"moduleLicense": "CDDL+GPL License",
"moduleLicenseUrl": "http://glassfish.java.net/public/CDDL+GPL_1_1.html"
},
{
"moduleName": "com.sun.xml.bind:jaxb-core",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "4.0.6",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "com.sun.xml.bind:jaxb-impl",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "2.3.9",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "com.sun.xml.bind:jaxb-impl",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "4.0.6",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "com.twelvemonkeys.common:common-image",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.common:common-io",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.common:common-lang",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-batik",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-bmp",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-core",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-jpeg",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-metadata",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-psd",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-tiff",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
{
"moduleName": "com.twelvemonkeys.imageio:imageio-webp",
"moduleVersion": "3.13.0",
"moduleVersion": "3.12.0",
"moduleLicense": "The BSD License",
"moduleLicenseUrl": "https://github.com/haraldk/TwelveMonkeys#license"
},
@@ -606,13 +522,6 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.zaxxer:SparseBitSet",
"moduleUrl": "https://github.com/brettwooldridge/SparseBitSet",
"moduleVersion": "1.3",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "commons-beanutils:commons-beanutils",
"moduleUrl": "https://commons.apache.org/proper/commons-beanutils",
@@ -651,7 +560,7 @@
{
"moduleName": "commons-io:commons-io",
"moduleUrl": "https://commons.apache.org/proper/commons-io/",
"moduleVersion": "2.21.0",
"moduleVersion": "2.20.0",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -703,13 +612,6 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-core",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.16.1",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-jakarta9",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
@@ -776,42 +678,42 @@
{
"moduleName": "io.swagger.core.v3:swagger-annotations-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-annotations",
"moduleVersion": "2.2.38",
"moduleVersion": "2.2.36",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-annotations-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-annotations",
"moduleVersion": "2.2.41",
"moduleVersion": "2.2.40",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-core-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-core",
"moduleVersion": "2.2.38",
"moduleVersion": "2.2.36",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-core-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-core",
"moduleVersion": "2.2.41",
"moduleVersion": "2.2.40",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-models-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-models",
"moduleVersion": "2.2.38",
"moduleVersion": "2.2.36",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-models-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-models",
"moduleVersion": "2.2.41",
"moduleVersion": "2.2.40",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
@@ -913,13 +815,6 @@
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "jakarta.ws.rs:jakarta.ws.rs-api",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.0",
"moduleLicense": "GPL-2.0-with-classpath-exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "jakarta.xml.bind:jakarta.xml.bind-api",
"moduleUrl": "https://www.eclipse.org",
@@ -928,25 +823,32 @@
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "javax.activation:javax.activation-api",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "1.2.0",
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0",
"moduleLicenseUrl": "https://opensource.org/licenses/CDDL-1.0"
"moduleName": "me.friwi:gluegen-rt",
"moduleUrl": "http://jogamp.org/gluegen/www/",
"moduleVersion": "v2.4.0-rc-20210111",
"moduleLicense": "BSD-4 License",
"moduleLicenseUrl": "http://www.spdx.org/licenses/BSD-4-Clause"
},
{
"moduleName": "javax.xml.bind:jaxb-api",
"moduleUrl": "http://www.oracle.com/",
"moduleVersion": "2.3.1",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://oss.oracle.com/licenses/CDDL+GPL-1.1"
"moduleName": "me.friwi:jcef-api",
"moduleUrl": "https://bitbucket.org/chromiumembedded/java-cef/",
"moduleVersion": "jcef-1770317+cef-132.3.1+g144febe+chromium-132.0.6834.83",
"moduleLicense": "BSD License",
"moduleLicenseUrl": "https://bitbucket.org/chromiumembedded/java-cef/src/master/LICENSE.txt"
},
{
"moduleName": "javax.xml.bind:jaxb-api",
"moduleUrl": "http://www.oracle.com/",
"moduleVersion": "2.4.0-b180830.0359",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://oss.oracle.com/licenses/CDDL+GPL-1.1"
"moduleName": "me.friwi:jcefmaven",
"moduleUrl": "https://github.com/jcefmaven/jcefmaven/",
"moduleVersion": "132.3.1",
"moduleLicense": "Apache-2.0 License",
"moduleLicenseUrl": "https://github.com/jcefmaven/jcefmaven/blob/master/LICENSE"
},
{
"moduleName": "me.friwi:jogl-all",
"moduleUrl": "http://jogamp.org/jogl/www/",
"moduleVersion": "v2.4.0-rc-20210111",
"moduleLicense": "Ubuntu Font Licence 1.0",
"moduleLicenseUrl": "http://font.ubuntu.com/ufl/ubuntu-font-licence-1.0.txt"
},
{
"moduleName": "net.bytebuddy:byte-buddy",
@@ -954,13 +856,6 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "net.java.dev.stax-utils:stax-utils",
"moduleUrl": "http://java.net/projects/stax-utils/",
"moduleVersion": "20070216",
"moduleLicense": "BSD",
"moduleLicenseUrl": "http://www.opensource.org/licenses/bsd-license.html"
},
{
"moduleName": "net.minidev:accessors-smart",
"moduleUrl": "https://urielch.github.io/",
@@ -991,14 +886,14 @@
{
"moduleName": "org.apache.commons:commons-collections4",
"moduleUrl": "https://commons.apache.org/proper/commons-collections/",
"moduleVersion": "4.4",
"moduleLicense": "Apache License, Version 2.0",
"moduleVersion": "4.5.0",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.commons:commons-collections4",
"moduleUrl": "https://commons.apache.org/proper/commons-collections/",
"moduleVersion": "4.5.0",
"moduleName": "org.apache.commons:commons-compress",
"moduleUrl": "https://commons.apache.org/proper/commons-compress/",
"moduleVersion": "1.27.1",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -1019,17 +914,10 @@
{
"moduleName": "org.apache.commons:commons-lang3",
"moduleUrl": "https://commons.apache.org/proper/commons-lang/",
"moduleVersion": "3.20.0",
"moduleVersion": "3.19.0",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.commons:commons-math3",
"moduleUrl": "http://commons.apache.org/proper/commons-math/",
"moduleVersion": "3.6.1",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.commons:commons-text",
"moduleUrl": "https://commons.apache.org/proper/commons-text",
@@ -1058,13 +946,6 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.httpcomponents:httpmime",
"moduleUrl": "http://hc.apache.org/httpcomponents-client-ga",
"moduleVersion": "4.5.14",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.logging.log4j:log4j-api",
"moduleVersion": "2.24.3",
@@ -1118,20 +999,6 @@
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.poi:poi",
"moduleUrl": "https://poi.apache.org/",
"moduleVersion": "5.2.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.poi:poi-scratchpad",
"moduleUrl": "https://poi.apache.org/",
"moduleVersion": "5.2.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.apache.santuario:xmlsec",
"moduleUrl": "https://www.apache.org/",
@@ -1190,14 +1057,14 @@
{
"moduleName": "org.bouncycastle:bcpkix-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.83",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
{
"moduleName": "org.bouncycastle:bcprov-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.83",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
@@ -1211,7 +1078,7 @@
{
"moduleName": "org.bouncycastle:bcutil-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.83",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
@@ -1444,62 +1311,6 @@
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.glassfish.grizzly:grizzly-framework",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "4.0.2",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.grizzly:grizzly-http",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "4.0.2",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.grizzly:grizzly-http-server",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "4.0.2",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.hk2.external:aopalliance-repackaged",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "3.0.6",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.hk2:hk2-api",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "3.0.6",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.hk2:hk2-locator",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "3.0.6",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.hk2:hk2-utils",
"moduleUrl": "http://www.oracle.com",
"moduleVersion": "3.0.6",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.hk2:osgi-resource-locator",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "1.0.3",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.jaxb:jaxb-core",
"moduleUrl": "https://www.eclipse.org",
@@ -1521,55 +1332,6 @@
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.glassfish.jersey.containers:jersey-container-grizzly2-http",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.core:jersey-client",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.core:jersey-common",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.core:jersey-server",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.ext:jersey-entity-filtering",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.inject:jersey-hk2",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.glassfish.jersey.media:jersey-media-json-jackson",
"moduleUrl": "https://www.eclipse.org/org/foundation/",
"moduleVersion": "3.1.11",
"moduleLicense": "jQuery license",
"moduleLicenseUrl": "jquery.org/license"
},
{
"moduleName": "org.hdrhistogram:HdrHistogram",
"moduleUrl": "http://hdrhistogram.github.io/HdrHistogram/",
@@ -1598,13 +1360,6 @@
"moduleLicense": "Apache License 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.javassist:javassist",
"moduleUrl": "https://www.javassist.org/",
"moduleVersion": "3.30.2-GA",
"moduleLicense": "MPL 1.1",
"moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/1.1/"
},
{
"moduleName": "org.jboss.logging:jboss-logging",
"moduleUrl": "http://www.jboss.org",
@@ -1646,13 +1401,6 @@
"moduleLicense": "Eclipse Public License, Version 2.0",
"moduleLicenseUrl": "https://github.com/locationtech/jts/blob/master/LICENSE_EPLv2.txt"
},
{
"moduleName": "org.mozilla:rhino",
"moduleUrl": "https://developer.mozilla.org/en/Rhino",
"moduleVersion": "1.7.13",
"moduleLicense": "Mozilla Public License, Version 2.0",
"moduleLicenseUrl": "http://www.mozilla.org/MPL/2.0/index.txt"
},
{
"moduleName": "org.openjfx:javafx-base",
"moduleVersion": "21",
@@ -1777,31 +1525,6 @@
"moduleLicense": "BSD-2-Clause",
"moduleLicenseUrl": "https://jdbc.postgresql.org/about/license.html"
},
{
"moduleName": "org.simplejavamail:core-module",
"moduleVersion": "8.12.6",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.simplejavamail:outlook-message-parser",
"moduleUrl": "https://github.com/bbottema/outlook-message-parser",
"moduleVersion": "1.14.1",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.simplejavamail:outlook-module",
"moduleVersion": "8.12.6",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.simplejavamail:simple-java-mail",
"moduleVersion": "8.12.6",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.slf4j:jul-to-slf4j",
"moduleUrl": "http://www.slf4j.org",
@@ -1825,19 +1548,19 @@
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-common",
"moduleVersion": "2.8.14",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-webmvc-api",
"moduleVersion": "2.8.14",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-webmvc-ui",
"moduleVersion": "2.8.14",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -1960,6 +1683,13 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.7",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-validation",
"moduleUrl": "https://spring.io/projects/spring-boot",
@@ -2142,20 +1872,6 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.telegram:telegrambots",
"moduleUrl": "https://github.com/rubenlagus/TelegramBots",
"moduleVersion": "6.9.7.1",
"moduleLicense": "MIT License",
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
},
{
"moduleName": "org.telegram:telegrambots-meta",
"moduleUrl": "https://github.com/rubenlagus/TelegramBots",
"moduleVersion": "6.9.7.1",
"moduleLicense": "MIT License",
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
},
{
"moduleName": "org.thymeleaf.extras:thymeleaf-extras-springsecurity5",
"moduleVersion": "3.1.3.RELEASE",
@@ -2174,6 +1890,12 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.thymeleaf:thymeleaf-spring6",
"moduleVersion": "3.1.3.RELEASE",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.unbescape:unbescape",
"moduleUrl": "http://www.unbescape.org",
@@ -2181,53 +1903,10 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.verapdf:core",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:feature-reporting",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:metadata-fixer",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:parser",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:pdf-model",
"moduleUrl": "https://github.com/veraPDF/veraPDF-model/",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:validation-model",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.verapdf:verapdf-xmp-core",
"moduleVersion": "1.28.2",
"moduleLicense": "Mozilla Public License 2.0 (MPL-2.0)",
"moduleLicenseUrl": "https://opensource.org/licenses/MPL-2.0"
},
{
"moduleName": "org.webjars:swagger-ui",
"moduleUrl": "https://www.webjars.org",
"moduleVersion": "5.30.1",
"moduleVersion": "5.28.1",
"moduleLicense": "Apache-2.0"
},
{
@@ -169,10 +169,7 @@ public class ProprietaryUIDataController {
OAUTH2 oauth = securityProps.getOauth2();
// Only add OAuth2 providers if loginMethod allows it
if (oauth != null
&& oauth.getEnabled()
&& securityProps.isOauth2Active()) { // This checks loginMethod
if (oauth != null && oauth.getEnabled()) {
if (oauth.isSettingsValid()) {
String firstChar = String.valueOf(oauth.getProvider().charAt(0));
String clientName =
@@ -204,7 +201,6 @@ public class ProprietaryUIDataController {
}
SAML2 saml2 = securityProps.getSaml2();
// Only add SAML2 providers if loginMethod allows it
if (securityProps.isSaml2Active() && applicationProperties.getPremium().isEnabled()) {
String samlIdp = saml2.getProvider();
String saml2AuthenticationPath = "/saml2/authenticate/" + saml2.getRegistrationId();
@@ -163,13 +163,12 @@ public class AdminSettingsController {
responseCode = "500",
description = "Failed to save settings to configuration file")
})
public ResponseEntity<Map<String, Object>> updateSettings(
public ResponseEntity<String> updateSettings(
@Valid @RequestBody UpdateSettingsRequest request) {
try {
Map<String, Object> settings = request.getSettings();
if (settings == null || settings.isEmpty()) {
return ResponseEntity.badRequest()
.body(Map.of("error", "No settings provided to update"));
return ResponseEntity.badRequest().body("No settings provided to update");
}
int updatedCount = 0;
@@ -179,11 +178,7 @@ public class AdminSettingsController {
if (!isValidSettingKey(key)) {
return ResponseEntity.badRequest()
.body(
Map.of(
"error",
"Invalid setting key format: "
+ HtmlUtils.htmlEscape(key)));
.body("Invalid setting key format: " + HtmlUtils.htmlEscape(key));
}
log.info("Admin updating setting: {} = {}", key, value);
@@ -196,26 +191,22 @@ public class AdminSettingsController {
}
return ResponseEntity.ok(
Map.of(
"message",
String.format(
"Successfully updated %d setting(s). Changes will take effect on"
+ " application restart.",
updatedCount)));
String.format(
"Successfully updated %d setting(s). Changes will take effect on"
+ " application restart.",
updatedCount));
} catch (IOException e) {
log.error("Failed to save settings to file: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", GENERIC_FILE_ERROR));
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(GENERIC_FILE_ERROR);
} catch (IllegalArgumentException e) {
log.error("Invalid setting key or value: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", GENERIC_INVALID_SETTING));
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(GENERIC_INVALID_SETTING);
} catch (Exception e) {
log.error("Unexpected error while updating settings: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", GENERIC_SERVER_ERROR));
.body(GENERIC_SERVER_ERROR);
}
}
@@ -292,23 +283,20 @@ public class AdminSettingsController {
description = "Access denied - Admin role required"),
@ApiResponse(responseCode = "500", description = "Failed to save settings")
})
public ResponseEntity<Map<String, Object>> updateSettingsSection(
public ResponseEntity<String> updateSettingsSection(
@PathVariable String sectionName, @Valid @RequestBody Map<String, Object> sectionData) {
try {
if (sectionData == null || sectionData.isEmpty()) {
return ResponseEntity.badRequest()
.body(Map.of("error", "No section data provided to update"));
return ResponseEntity.badRequest().body("No section data provided to update");
}
if (!isValidSectionName(sectionName)) {
return ResponseEntity.badRequest()
.body(
Map.of(
"error",
"Invalid section name: "
+ HtmlUtils.htmlEscape(sectionName)
+ ". Valid sections: "
+ String.join(", ", VALID_SECTION_NAMES)));
"Invalid section name: "
+ HtmlUtils.htmlEscape(sectionName)
+ ". Valid sections: "
+ String.join(", ", VALID_SECTION_NAMES));
}
// Auto-enable premium features if license key is provided
@@ -329,11 +317,7 @@ public class AdminSettingsController {
if (!isValidSettingKey(fullKey)) {
return ResponseEntity.badRequest()
.body(
Map.of(
"error",
"Invalid setting key format: "
+ HtmlUtils.htmlEscape(fullKey)));
.body("Invalid setting key format: " + HtmlUtils.htmlEscape(fullKey));
}
log.info("Admin updating section setting: {} = {}", fullKey, value);
@@ -347,25 +331,21 @@ public class AdminSettingsController {
String escapedSectionName = HtmlUtils.htmlEscape(sectionName);
return ResponseEntity.ok(
Map.of(
"message",
String.format(
"Successfully updated %d setting(s) in section '%s'. Changes will take"
+ " effect on application restart.",
updatedCount, escapedSectionName)));
String.format(
"Successfully updated %d setting(s) in section '%s'. Changes will take"
+ " effect on application restart.",
updatedCount, escapedSectionName));
} catch (IOException e) {
log.error("Failed to save section settings to file: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", GENERIC_FILE_ERROR));
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(GENERIC_FILE_ERROR);
} catch (IllegalArgumentException e) {
log.error("Invalid section data: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("error", GENERIC_INVALID_SECTION));
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(GENERIC_INVALID_SECTION);
} catch (Exception e) {
log.error("Unexpected error while updating section settings: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("error", GENERIC_SERVER_ERROR));
.body(GENERIC_SERVER_ERROR);
}
}
@@ -473,7 +453,7 @@ public class AdminSettingsController {
description = "Access denied - Admin role required"),
@ApiResponse(responseCode = "500", description = "Failed to initiate restart")
})
public ResponseEntity<Map<String, Object>> restartApplication() {
public ResponseEntity<String> restartApplication() {
try {
log.warn("Admin initiated application restart");
@@ -485,18 +465,13 @@ public class AdminSettingsController {
log.error("Cannot restart: not running from JAR (likely development mode)");
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(
Map.of(
"error",
"Restart not available in development mode. Please restart the application manually."));
"Restart not available in development mode. Please restart the application manually.");
}
if (helperJar == null || !Files.isRegularFile(helperJar)) {
log.error("Cannot restart: restart-helper.jar not found at expected location");
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(
Map.of(
"error",
"Restart helper not found. Cannot perform application restart."));
.body("Restart helper not found. Please restart the application manually.");
}
// Get current application arguments
@@ -551,17 +526,12 @@ public class AdminSettingsController {
.start();
return ResponseEntity.ok(
Map.of(
"message",
"Application restart initiated. The server will be back online shortly."));
"Application restart initiated. The server will be back online shortly.");
} catch (Exception e) {
log.error("Failed to initiate restart: {}", e.getMessage(), e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(
Map.of(
"error",
"Failed to initiate application restart: " + e.getMessage()));
.body("Failed to initiate application restart: " + e.getMessage());
}
}
@@ -581,7 +551,6 @@ public class AdminSettingsController {
case "processexecutor", "processExecutor" -> applicationProperties.getProcessExecutor();
case "autopipeline", "autoPipeline" -> applicationProperties.getAutoPipeline();
case "legal" -> applicationProperties.getLegal();
case "telegram" -> applicationProperties.getTelegram();
default -> null;
};
}
@@ -603,8 +572,7 @@ public class AdminSettingsController {
"processexecutor",
"autoPipeline",
"autopipeline",
"legal",
"telegram");
"legal");
// Pattern to validate safe property paths - only alphanumeric, dots, and underscores
private static final Pattern SAFE_KEY_PATTERN =
@@ -21,7 +21,6 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.proprietary.audit.AuditEventType;
import stirling.software.proprietary.audit.AuditLevel;
import stirling.software.proprietary.audit.Audited;
@@ -45,7 +44,6 @@ public class AuthController {
private final JwtServiceInterface jwtService;
private final CustomUserDetailsService userDetailsService;
private final LoginAttemptService loginAttemptService;
private final ApplicationProperties.Security securityProperties;
/**
* Login endpoint - replaces Supabase signInWithPassword
@@ -62,17 +60,6 @@ public class AuthController {
HttpServletRequest httpRequest,
HttpServletResponse response) {
try {
// Check if username/password authentication is allowed
if (!securityProperties.isUserPass()) {
log.warn(
"Username/password login attempted but not allowed by current login method configuration");
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(
Map.of(
"error",
"Username/password authentication is not enabled. Please use the configured authentication method."));
}
// Validate input parameters
if (request.getUsername() == null || request.getUsername().trim().isEmpty()) {
log.warn("Login attempt with null or empty username");
@@ -741,35 +741,31 @@ public class UserController {
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/get-api-key")
public ResponseEntity<Map<String, String>> getApiKey(Principal principal) {
public ResponseEntity<String> getApiKey(Principal principal) {
if (principal == null) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(Map.of("error", "User not authenticated."));
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User not authenticated.");
}
String username = principal.getName();
String apiKey = userService.getApiKeyForUser(username);
if (apiKey == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("error", "API key not found for user."));
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("API key not found for user.");
}
return ResponseEntity.ok(Map.of("apiKey", apiKey));
return ResponseEntity.ok(apiKey);
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/update-api-key")
public ResponseEntity<Map<String, String>> updateApiKey(Principal principal) {
public ResponseEntity<String> updateApiKey(Principal principal) {
if (principal == null) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(Map.of("error", "User not authenticated."));
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("User not authenticated.");
}
String username = principal.getName();
User user = userService.refreshApiKeyForUser(username);
String apiKey = user.getApiKey();
if (apiKey == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("error", "API key not found for user."));
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("API key not found for user.");
}
return ResponseEntity.ok(Map.of("apiKey", apiKey));
return ResponseEntity.ok(apiKey);
}
/**
+9 -123
View File
@@ -14,8 +14,6 @@ plugins {
import com.github.jk1.license.render.*
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.xml.XmlSlurper
import org.gradle.api.tasks.testing.Test
ext {
springBootVersion = "3.5.7"
@@ -62,7 +60,7 @@ repositories {
allprojects {
group = 'stirling.software'
version = '2.3.0'
version = '2.2.0'
configurations.configureEach {
exclude group: 'commons-logging', module: 'commons-logging'
@@ -185,142 +183,30 @@ subprojects {
}
}
tasks.named("compileJava", JavaCompile).configure {
options.compilerArgs.add("-parameters")
compileJava {
options.compilerArgs << "-parameters"
}
def jacocoReport = tasks.named("jacocoTestReport")
tasks.withType(Test).configureEach {
test {
useJUnitPlatform()
finalizedBy(jacocoReport)
finalizedBy jacocoTestReport
}
jacocoReport.configure {
dependsOn(tasks.named("test"))
jacocoTestReport {
dependsOn test
reports {
xml.required.set(true)
csv.required.set(false)
html.required.set(true)
}
doLast {
def xmlReport = reports.xml.outputLocation.get().asFile
if (!xmlReport.exists()) {
logger.lifecycle("Jacoco coverage report not found at ${xmlReport}")
return
}
def xmlContent = xmlReport.getText("UTF-8")
xmlContent = xmlContent.replaceFirst('(?s)<!DOCTYPE.*?>', '')
def report = new XmlSlurper(false, false).parseText(xmlContent)
def counters = report.counter.collectEntries { counter ->
def type = counter.@type.text()
def covered = counter.@covered.text() as BigDecimal
def missed = counter.@missed.text() as BigDecimal
[(type): [covered: covered, missed: missed]]
}
def thresholds = [
LINE : 0.16,
INSTRUCTION: 0.14,
BRANCH : 0.09
]
def types = ["LINE", "INSTRUCTION", "BRANCH"]
def headers = ["Metric", "Coverage", "Covered/Total", "Status", "Target"]
def rows = types.collect { String type ->
def data = counters[type]
if (!data) {
return [type, "—", "—", "No data", ""]
}
def total = data.covered + data.missed
if (total == 0) {
return [type, "—", "0/${total.toBigInteger()}", "No executions", ""]
}
def ratio = data.covered / total * 100
def coverageText = String.format(Locale.ROOT, "%.2f%%", ratio)
def coveredText = String.format(Locale.ROOT, "%d/%d",
data.covered.toBigInteger(),
total.toBigInteger())
def threshold = thresholds[type]
def thresholdPercent = threshold != null ? threshold * 100 : null
def targetText = thresholdPercent != null ?
String.format(Locale.ROOT, ">= %.2f%%", thresholdPercent) : ""
def passed = thresholdPercent != null ? ratio >= thresholdPercent : null
def statusText = passed == null ? "" : (passed ? "PASS" : "FAIL")
return [type, coverageText, coveredText, statusText, targetText]
}
def columnIndexes = (0..<headers.size())
def columnWidths = columnIndexes.collect { idx ->
Math.max(headers[idx].length(), rows.collect { row ->
row[idx] != null ? row[idx].toString().length() : 0
}.max() ?: 0)
}
def formatRow = { List<String> values ->
columnIndexes.collect { idx ->
def value = values[idx] ?: ""
value.padRight(columnWidths[idx])
}.join(" | ")
}
def separator = columnIndexes.collect { idx ->
''.padRight(columnWidths[idx], '-')
}.join("-+-")
logger.lifecycle("")
logger.lifecycle("==== JaCoCo Coverage Summary ====")
logger.lifecycle(formatRow(headers))
logger.lifecycle(separator)
rows.each { row ->
logger.lifecycle(formatRow(row))
}
logger.lifecycle(separator)
def htmlReport = reports.html.outputLocation.get().asFile
logger.lifecycle("Detailed HTML report available at: ${htmlReport}")
if (rows.any { it[3] == "FAIL" }) {
logger.lifecycle("Some coverage targets were missed. Please review the detailed report above.")
} else if (rows.any { it[3] == "PASS" }) {
logger.lifecycle("Great job! All tracked coverage metrics meet their targets.")
}
logger.lifecycle("=================================\n")
}
}
tasks.named("build") {
dependsOn jacocoReport
}
jacocoTestCoverageVerification {
dependsOn jacocoReport
dependsOn jacocoTestReport
violationRules {
rule {
enabled = true
element = 'BUNDLE'
// Bytecode-Anweisungen abgedeckt
limit {
counter = 'INSTRUCTION'
value = 'COVEREDRATIO'
minimum = 0.14
}
// wie viele Quellcode-Zeilen abgedeckt
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.16
}
// Verzweigungen (if/else, switch) abgedeckt; misst Logik-Abdeckung
limit {
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.09
minimum = 0.0
}
}
}
+3 -3
View File
@@ -2,7 +2,7 @@
# Supports MODE parameter: BOTH (default), FRONTEND, BACKEND
# Stage 1: Build Frontend
FROM node:20-alpine@sha256:658d0f63e501824d6c23e06d4bb95c71e7d704537c9d9272f488ac03a370d448 AS frontend-build
FROM node:20-alpine AS frontend-build
WORKDIR /app
@@ -15,7 +15,7 @@ COPY frontend .
RUN DISABLE_ADDITIONAL_FEATURES=false VITE_API_BASE_URL=/ npm run build
# Stage 2: Build Backend (server-only JAR - no UI)
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS backend-build
FROM gradle:8.14-jdk21 AS backend-build
COPY build.gradle .
COPY settings.gradle .
@@ -35,7 +35,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=false \
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
# Stage 3: Final unified image
FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
FROM alpine:3.22.1
ARG VERSION_TAG
+3 -3
View File
@@ -2,7 +2,7 @@
# Supports MODE parameter: BOTH (default), FRONTEND, BACKEND
# Stage 1: Build Frontend
FROM node:20-alpine@sha256:658d0f63e501824d6c23e06d4bb95c71e7d704537c9d9272f488ac03a370d448 AS frontend-build
FROM node:20-alpine AS frontend-build
WORKDIR /app
@@ -15,7 +15,7 @@ COPY frontend .
RUN DISABLE_ADDITIONAL_FEATURES=true VITE_API_BASE_URL=/ npm run build
# Stage 2: Build Backend
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS backend-build
FROM gradle:8.14-jdk21 AS backend-build
COPY build.gradle .
COPY settings.gradle .
@@ -34,7 +34,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=true \
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
# Stage 3: Final unified ultra-lite image
FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
FROM alpine:3.22.1
ARG VERSION_TAG
+1 -1
View File
@@ -6,7 +6,7 @@
# ========================================
# STAGE 1: Build stage - Alpine with Gradle
# ========================================
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
COPY build.gradle .
COPY settings.gradle .
+1 -1
View File
@@ -6,7 +6,7 @@
# ========================================
# STAGE 1: Build stage - Gradle
# ========================================
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
COPY build.gradle .
COPY settings.gradle .
+2 -2
View File
@@ -2,7 +2,7 @@
# ========================================
# STAGE 1: Build stage - Gradle
# ========================================
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
COPY build.gradle .
COPY settings.gradle .
@@ -27,7 +27,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=true \
# ========================================
# STAGE 2: Runtime stage - Alpine minimal
# ========================================
FROM alpine:3.23.2@sha256:865b95f46d98cf867a156fe4a135ad3fe50d2056aa3f25ed31662dff6da4eb62
FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
ARG VERSION_TAG
+2 -13
View File
@@ -2,7 +2,7 @@
# Single JAR contains both frontend and backend
# Stage 1: Build application with embedded frontend
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
# Install Node.js and npm for frontend build
RUN apt-get update && apt-get install -y \
@@ -37,7 +37,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=false \
# Stage 2: Runtime image based on Debian stable-slim
# Contains Java runtime + LibreOffice + Calibre + all PDF tools
FROM debian:stable-slim@sha256:f6681102cd18b4c0c4720a77b602498f4bdcf701c8fc02776dfb0d4c350c381f
FROM debian:stable-slim@sha256:1c25564b03942d874bf6a2b71f2062b71af8bc1475aa873c523e6f7c8fa29e60
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ENV DEBIAN_FRONTEND=noninteractive
@@ -66,8 +66,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xvfb x11-utils coreutils \
# Temporary packages only needed for Calibre installer
xz-utils gpgv curl xdg-utils \
# UTF-8 locale support for handling international filenames
locales \
\
# Install Calibre from official installer script
&& curl -fsSL https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin \
@@ -81,15 +79,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN ln -sf /opt/calibre/ebook-convert /usr/bin/ebook-convert \
&& /opt/calibre/ebook-convert --version
# Configure UTF-8 locale to support international characters in filenames
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
&& locale-gen en_US.UTF-8
# Set UTF-8 locale environment variables
ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
LANGUAGE=en_US:en
# ==============================================================================
# Create non-root user (stirlingpdfuser) with configurable UID/GID
# ==============================================================================
+2 -13
View File
@@ -2,7 +2,7 @@
# Single JAR contains both frontend and backend with extra fonts for air-gapped environments
# Stage 1: Build application with embedded frontend
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
# Install Node.js and npm for frontend build
RUN apt-get update && apt-get install -y \
@@ -37,7 +37,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=false \
# Stage 2: Runtime image based on Debian stable-slim
# Contains Java runtime + LibreOffice + Calibre + all PDF tools + extra fonts for air-gapped environments
FROM debian:stable-slim@sha256:f6681102cd18b4c0c4720a77b602498f4bdcf701c8fc02776dfb0d4c350c381f
FROM debian:stable-slim@sha256:1c25564b03942d874bf6a2b71f2062b71af8bc1475aa873c523e6f7c8fa29e60
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ENV DEBIAN_FRONTEND=noninteractive
@@ -69,8 +69,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xvfb x11-utils coreutils \
# Temporary packages only needed for Calibre installer
xz-utils gpgv curl xdg-utils \
# UTF-8 locale support for handling international filenames
locales \
\
# Install Calibre from official installer script
&& curl -fsSL https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin \
@@ -84,15 +82,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN ln -sf /opt/calibre/ebook-convert /usr/bin/ebook-convert \
&& /opt/calibre/ebook-convert --version
# Configure UTF-8 locale to support international characters in filenames
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
&& locale-gen en_US.UTF-8
# Set UTF-8 locale environment variables
ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
LANGUAGE=en_US:en
# ==============================================================================
# Create non-root user (stirlingpdfuser) with configurable UID/GID
# ==============================================================================
+4 -8
View File
@@ -2,7 +2,7 @@
# Single JAR contains both frontend and backend with minimal dependencies
# Stage 1: Build application with embedded frontend
FROM gradle:8.14-jdk21@sha256:051d9a116793bdc5175a3f97a545718b750489eee85a7da20913c8a53f722a72 AS build
FROM gradle:8.14-jdk21 AS build
# Install Node.js and npm for frontend build
RUN apt-get update && apt-get install -y \
@@ -36,7 +36,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=true \
./gradlew clean build -PbuildWithFrontend=true -x spotlessApply -x spotlessCheck -x test -x sonarqube
# Stage 2: Runtime image
FROM alpine:3.23.2@sha256:865b95f46d98cf867a156fe4a135ad3fe50d2056aa3f25ed31662dff6da4eb62
FROM alpine:3.22.1
ARG VERSION_TAG
@@ -73,10 +73,7 @@ ENV VERSION_TAG=$VERSION_TAG \
TMPDIR=/tmp/stirling-pdf \
TEMP=/tmp/stirling-pdf \
TMP=/tmp/stirling-pdf \
ENDPOINTS_GROUPS_TO_REMOVE=CLI \
LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
LANGUAGE=en_US:en
ENDPOINTS_GROUPS_TO_REMOVE=CLI
# Install minimal dependencies
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
@@ -91,8 +88,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
curl \
shadow \
su-exec \
openjdk21-jre \
musl-locales musl-locales-lang && \
openjdk21-jre && \
mkdir -p $HOME /configs /configs/heap_dumps /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \
mkdir -p /usr/share/fonts/opentype/noto && \
chmod +x /scripts/*.sh && \
+2 -2
View File
@@ -1,5 +1,5 @@
# Frontend Dockerfile - React/Vite application
FROM node:25-alpine@sha256:f4769ca6eeb6ebbd15eb9c8233afed856e437b75f486f7fccaa81d7c8ad56007 AS build
FROM node:20-alpine AS build
WORKDIR /app
@@ -16,7 +16,7 @@ COPY frontend .
RUN npm run build
# Production stage
FROM nginx:alpine@sha256:c083c3799197cfff91fe5c3c558db3d2eea65ccbbfd419fa42a64d2c39a24027
FROM nginx:alpine
# Copy built files from build stage
COPY --from=build /app/dist /usr/share/nginx/html
+8 -16
View File
@@ -14,20 +14,17 @@ echo "==================================="
setup_ocr() {
echo "Setting up OCR languages..."
# In Alpine, tesseract uses /usr/share/tessdata
TESSDATA_DIR="/usr/share/tessdata"
# Copy tessdata
mkdir -p /usr/share/tessdata
cp -rn /usr/share/tessdata-original/* /usr/share/tessdata 2>/dev/null || true
# Create tessdata directory
mkdir -p "$TESSDATA_DIR"
# Restore system languages from backup (Dockerfile moved them to tessdata-original)
if [ -d /usr/share/tessdata-original ]; then
echo "Restoring system tessdata from backup..."
cp -rn /usr/share/tessdata-original/* "$TESSDATA_DIR"/ 2>/dev/null || true
if [ -d /usr/share/tesseract-ocr/4.00/tessdata ]; then
cp -r /usr/share/tesseract-ocr/4.00/tessdata/* /usr/share/tessdata 2>/dev/null || true
fi
# Note: If user mounted custom languages to /usr/share/tessdata, they'll be overlaid here.
# The cp -rn above won't overwrite user files, just adds missing system files.
if [ -d /usr/share/tesseract-ocr/5/tessdata ]; then
cp -r /usr/share/tesseract-ocr/5/tessdata/* /usr/share/tessdata 2>/dev/null || true
fi
# Install additional languages if specified
if [[ -n "$TESSERACT_LANGS" ]]; then
@@ -35,15 +32,10 @@ setup_ocr() {
pattern='^[a-zA-Z]{2,4}(_[a-zA-Z]{2,4})?$'
for LANG in $SPACE_SEPARATED_LANGS; do
if [[ $LANG =~ $pattern ]]; then
echo "Installing tesseract language: $LANG"
apk add --no-cache "tesseract-ocr-data-$LANG" 2>/dev/null || true
fi
done
fi
# Point to the consolidated location
export TESSDATA_PREFIX="$TESSDATA_DIR"
echo "Using TESSDATA_PREFIX=$TESSDATA_PREFIX"
}
# Function to setup user permissions (from init-without-ocr.sh)
+1409 -1162
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -43,13 +43,13 @@
"@supabase/supabase-js": "^2.47.13",
"@tailwindcss/postcss": "^4.1.13",
"@tanstack/react-virtual": "^3.13.12",
"@tauri-apps/api": "^2.5.0",
"@tauri-apps/api": "^2.9.1",
"@tauri-apps/plugin-fs": "^2.4.0",
"@tauri-apps/plugin-http": "^2.5.4",
"@tauri-apps/plugin-shell": "^2.3.3",
"autoprefixer": "^10.4.21",
"axios": "^1.12.2",
"globals": "^17.0.0",
"globals": "^16.4.0",
"i18next": "^25.5.2",
"i18next-browser-languagedetector": "^8.2.0",
"jszip": "^3.10.1",
@@ -129,7 +129,7 @@
"@iconify-json/material-symbols": "^1.2.48",
"@iconify/utils": "^3.0.2",
"@playwright/test": "^1.55.0",
"@tauri-apps/cli": "^2.5.0",
"@tauri-apps/cli": "^2.9.5",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "متقدم"
edit = "عرض وتعديل"
popular = "المفضل"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "التفضيلات"
@@ -439,25 +435,6 @@ latestVersion = "أحدث إصدار"
checkForUpdates = "التحقق من التحديثات"
viewDetails = "عرض التفاصيل"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "اختصارات لوحة المفاتيح"
description = "خصّص اختصارات لوحة المفاتيح للوصول السريع إلى الأدوات. انقر \"تغيير الاختصار\" واضغط مجموعة مفاتيح جديدة. اضغط Esc للإلغاء."
@@ -511,16 +488,11 @@ low = "منخفض"
title = "تغيير بيانات الاعتماد"
header = "تحديث تفاصيل حسابك"
changePassword = "أنت تستخدم بيانات تسجيل الدخول الافتراضية. يرجى إدخال كلمة مرور جديدة"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "اسم المستخدم الجديد"
oldPassword = "كلمة المرور الحالية"
newPassword = "كلمة المرور الجديدة"
confirmNewPassword = "تأكيد كلمة المرور الجديدة"
submit = "إرسال التغييرات"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "إعدادات الحساب"
@@ -736,11 +708,6 @@ tags = "توقيع،إمضاء"
title = "توقيع"
desc = "إضافة التوقيع إلى PDF عن طريق الرسم أو النص أو الصورة"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "تبسيط،إزالة،تفاعلي"
title = "تسطيح"
@@ -1278,21 +1245,6 @@ cbzOptions = "خيارات التحويل من CBZ إلى PDF"
optimizeForEbook = "تحسين PDF لقارئات الكتب الإلكترونية (يستخدم Ghostscript)"
cbzOutputOptions = "خيارات التحويل من PDF إلى CBZ"
cbzDpi = "DPI لعرض الصور"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "تحويل,صورة,jpg,صورة,صورة فوتوغرافية"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "إضافة مرفق"
remove = "إزالة المرفق"
embed = "تضمين مرفق"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "محفوظ"
label = "رفع صورة التوقيع"
placeholder = "اختر ملف صورة"
hint = "ارفع صورة PNG أو JPG لتوقيعك"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "كيفية إضافة توقيع"
@@ -2408,11 +2351,6 @@ note = "التسطيح يزيل العناصر التفاعلية من PDF وي
label = "تسطيح النماذج فقط"
desc = "تسطيح حقول النماذج فقط مع إبقاء العناصر التفاعلية الأخرى كما هي"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "نتائج التسطيح"
@@ -2987,7 +2925,6 @@ header = "اقتصاص PDF"
submit = "إرسال"
noFileSelected = "حدّد ملف PDF لبدء القص"
reset = "إعادة التعيين إلى كامل PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "معاينة منطقة القص"
@@ -3405,19 +3342,6 @@ placeholder = "أدخل عدد التقسيمات الأفقية"
label = "التقسيمات العمودية"
placeholder = "أدخل عدد التقسيمات العمودية"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "ختم, إضافة صورة, صورة وسط, علامة مائية, PDF, تضمين, تخصيص"
header = "ختم PDF"
@@ -3779,19 +3703,6 @@ filesize = "حجم الملف"
[compress.grayscale]
label = "تطبيق التدرج الرمادي للضغط"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "نظرة عامة على إعدادات الضغط"
@@ -3809,10 +3720,6 @@ bullet2 = "القيم المرتفعة تقلّل حجم الملف"
title = "تدرّج رمادي"
text = "حدد هذا الخيار لتحويل جميع الصور إلى الأبيض والأسود، ما قد يقلّل حجم الملف بشكل ملحوظ خاصة لملفات PDF الممسوحة أو الكثيرة الصور."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "حدث خطأ أثناء ضغط PDF."
@@ -3825,11 +3732,6 @@ failed = "حدث خطأ أثناء ضغط PDF."
_value = "إعدادات الضغط"
1 = "1-3 ضغط PDF،</br> 4-6 ضغط صور خفيف،</br> 7-9 ضغط صور قوي سيقلّل جودة الصور بشكل كبير"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "هذا الملف محمي بكلمة مرور. يرجى إدخال كلمة المرور:"
cancelled = "تم إلغاء العملية لـ PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "حذف الصفحات المحددة"
closePdf = "إغلاق PDF"
exportAll = "تصدير PDF"
downloadSelected = "تنزيل الملفات المحددة"
annotations = "Annotations"
exportSelected = "تصدير الصفحات المحددة"
saveChanges = "حفظ التغييرات"
downloadAll = "تنزيل الكل"
saveAll = "حفظ الكل"
toggleTheme = "تبديل السِمة"
toggleBookmarks = "تبديل الإشارات المرجعية"
language = "اللغة"
toggleAnnotations = "تبديل ظهور التعليقات التوضيحية"
search = "بحث في PDF"
panMode = "وضع السحب"
rotateLeft = "تدوير لليسار"
rotateRight = "تدوير لليمين"
toggleSidebar = "تبديل الشريط الجانبي"
toggleBookmarks = بديل الإشارات المرجعية"
exportSelected = صدير الصفحات المحددة"
toggleAnnotations = "تبديل ظهور التعليقات التوضيحية"
annotationMode = "تبديل وضع التعليقات"
print = "طباعة PDF"
downloadAll = "تنزيل الكل"
saveAll = "حفظ الكل"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "رسم"
save = "حفظ"
saveChanges = "حفظ التغييرات"
[search]
title = "بحث PDF"
@@ -4205,20 +4038,12 @@ settings = "إعدادات"
adminSettings = "إعدادات المشرف"
allTools = "كل الأدوات"
reader = "القارئ"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "جولة الأدوات"
toolsTourDesc = "تعرّف على ما تستطيع الأدوات فعله"
adminTour = "جولة المسؤول"
adminTourDesc = "استكشف إعدادات وميزات المسؤول"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "خطأ"
@@ -5244,7 +5069,6 @@ loading = "جارٍ التحميل..."
back = "رجوع"
continue = "متابعة"
error = "خطأ"
save = "Save"
[config.overview]
title = "تهيئة التطبيق"
@@ -5411,16 +5235,6 @@ finish = "إنهاء"
startTour = "بدء الجولة"
startTourDescription = "قم بجولة إرشادية للتعرّف على الميزات الرئيسية في Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "مرحبًا بك في Stirling PDF!"
description = "هل ترغب في جولة سريعة لمدة دقيقة للتعرّف على الميزات الرئيسية وكيفية البدء؟"
@@ -5441,10 +5255,6 @@ download = "تنزيل →"
showMeAround = "أرني الجولة"
skipTheTour = "تخطي الجولة"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "تخطي الآن"
seePlans = "عرض الخطط →"
@@ -5758,28 +5568,6 @@ contactSales = "اتصل بالمبيعات"
contactToUpgrade = "اتصل بنا للترقية أو تخصيص خطتك"
maxUsers = "الحد الأقصى للمستخدمين"
upTo = "حتى"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "شهر"
@@ -5983,8 +5771,6 @@ notAvailable = "نظام التدقيق غير متاح"
notAvailableMessage = "لم يتم تهيئة نظام التدقيق أو أنه غير متاح."
disabled = "تم تعطيل تسجيل التدقيق"
disabledMessage = "قم بتمكين تسجيل التدقيق في إعدادات التطبيق لتتبع أحداث النظام."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "خطأ في تحميل نظام التدقيق"
@@ -6239,8 +6025,6 @@ reset = "إعادة تعيين التغييرات"
downloadJson = "تنزيل JSON"
generatePdf = "توليد PDF"
saveChanges = "حفظ التغييرات"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "ضبط النص تلقائياً ليتناسب مع الصناديق"
@@ -6259,24 +6043,6 @@ descriptionInline = "نصيحة: اضغط Ctrl (Cmd) أو Shift لتحديد ع
title = "قفل النص المُحرّر ضمن عنصر PDF واحد"
description = "عند التفعيل، يصدّر المحرر كل صندوق نص مُحرّر كعنصر نص PDF واحد لتجنب تراكب المحارف أو اختلاط الخطوط."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "دمج الصناديق المحددة"
merge = "دمج التحديد"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Qabaqcıl"
edit = "Bax & Redaktə et"
popular = "Populyar"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Seçimlər"
@@ -439,25 +435,6 @@ latestVersion = "Ən son versiya"
checkForUpdates = "Yeniləmələri yoxla"
viewDetails = "Ətraflı bax"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Klaviatura qısayolları"
description = "Alətlərə sürətli giriş üçün klaviatura qısayollarını fərdiləşdirin. \"Qısayolu dəyiş\" düyməsini klikləyin və yeni düymə kombinasiyasını basın. Ləğv etmək üçün Esc basın."
@@ -511,16 +488,11 @@ low = "Aşağı"
title = "Məlumatları dəyişdirin"
header = "Hesab Məlumatlarınızı Yeniləyin"
changePassword = "Siz standart giriş məlumatlarından istifadə edirsiniz. Zəhmət olmasa, yeni şifr daxil edin"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Yeni İstifadəçi Adı"
oldPassword = "Cari Şifr"
newPassword = "Yeni Şifr"
confirmNewPassword = "Yeni Şifri Təsdiqləyin"
submit = "Dəyişiklikləri Təsdiqlə"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Hesab Parametrləri"
@@ -736,11 +708,6 @@ tags = "imza,avtoqraf"
title = "İmzala"
desc = "Mətn, şəkil və ya əllə çəkmə üsulu ilə PDF-ə imza əlavə edir"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "sadələşdir,sil,interaktiv"
title = "Sadələşdir"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ to PDF seçimləri"
optimizeForEbook = "PDF-i e-oxuyucular üçün optimallaşdır (Ghostscript istifadə olunur)"
cbzOutputOptions = "PDF to CBZ seçimləri"
cbzDpi = "Şəkil göstərilməsi üçün DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "çevirmə,şəkil,jpg,fotoşəkil,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Əlavə et"
remove = "Əlavəni sil"
embed = "Əlavəni yerləşdir"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Saxlanmış"
label = "İmza şəklini yüklə"
placeholder = "Şəkil faylı seç"
hint = "İmzanızın PNG və ya JPG şəklini yükləyin"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "İmza necə əlavə olunur"
@@ -2408,11 +2351,6 @@ note = "Yastılaşdırma PDF-dəki interaktiv elementləri silir və onları red
label = "Yalnız formaları düzəldin"
desc = "Yalnız forma sahələrini yastılaşdırın, digər interaktiv elementlər toxunulmaz qalsın"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Yastılaşdırma nəticələri"
@@ -2987,7 +2925,6 @@ header = "Pdf-ləri Kəs"
submit = "Təsdiq Et"
noFileSelected = "Kəsməyə başlamaq üçün bir PDF faylı seçin"
reset = "Tam PDF-ə sıfırla"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Kəsmə sahəsinin seçimi"
@@ -3405,19 +3342,6 @@ placeholder = "Üfüqi bölmələrin sayını daxil edin"
label = "Şaquli bölmələr"
placeholder = "Şaquli bölmələrin sayını daxil edin"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Möhür, Şəkil əlavə et, şəkli ortala, Watermark, PDF, Embed, Fərdiləşdir"
header = "PDF-i Möhürlə"
@@ -3779,19 +3703,6 @@ filesize = "Fayl Ölçüsü"
[compress.grayscale]
label = "Sıxma üçün Boz Rəng Tətbiq Edin"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Sıxma ayarlarına ümumi baxış"
@@ -3809,10 +3720,6 @@ bullet2 = "Yüksək dəyərlər fayl ölçüsünü azaldır"
title = "Boz tonlama"
text = "Bütün şəkilləri ağ-qara çevirmək üçün bu seçimi seçin; xüsusilə skan edilmiş PDF-lər və ya şəkil çox olan sənədlər üçün fayl ölçüsünü əhəmiyyətli dərəcədə azalda bilər."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF sıxılarkən xəta baş verdi."
@@ -3825,11 +3732,6 @@ failed = "PDF sıxılarkən xəta baş verdi."
_value = "Sıxma ayarları"
1 = "1-3 PDF sıxılması,</br> 4-6 yüngül şəkil sıxması,</br> 7-9 güclü şəkil sıxması Şəkil keyfiyyətini əhəmiyyətli dərəcədə azaldacaq"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Bu fayl parol ilə qorunub. Zəhmət olmasa parolu daxil edin:"
cancelled = "PDF üçün əməliyyat ləğv edildi: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Seçilmiş səhifələri sil"
closePdf = "PDF-i bağla"
exportAll = "PDF-i ixrac et"
downloadSelected = "Seçilmiş faylları yüklə"
annotations = "Annotations"
exportSelected = "Seçilmiş səhifələri ixrac et"
saveChanges = "Dəyişiklikləri yadda saxla"
downloadAll = "Hamısını yüklə"
saveAll = "Hamısını saxla"
toggleTheme = "Mövzunu dəyiş"
toggleBookmarks = "Əlfəcinləri aç/bağla"
language = "Dil"
toggleAnnotations = "Annotasiyaların görünməsini dəyiş"
search = "PDF-də axtar"
panMode = "Sürüşdürmə rejimi"
rotateLeft = "Sola döndər"
rotateRight = "Sağa döndər"
toggleSidebar = "Yan paneli aç/bağla"
toggleBookmarks = "Əlfəcinləri aç/bağla"
exportSelected = "Seçilmiş səhifələri ixrac et"
toggleAnnotations = "Annotasiyaların görünməsini dəyiş"
annotationMode = "Annotasiya rejimini dəyiş"
print = "PDF-i çap et"
downloadAll = "Hamısını yüklə"
saveAll = "Hamısını saxla"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Rəsm çək"
save = "Yadda saxla"
saveChanges = "Dəyişiklikləri yadda saxla"
[search]
title = "PDF-də axtar"
@@ -4205,20 +4038,12 @@ settings = "Ayarlar"
adminSettings = "Admin Ayarları"
allTools = "All Tools"
reader = "Oxuyucu"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Alətlər Turu"
toolsTourDesc = "Alətlərin nələr etdiyini öyrənin"
adminTour = "Admin Turu"
adminTourDesc = "Admin ayarlarını və funksiyaları kəşf edin"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Xəta"
@@ -5244,7 +5069,6 @@ loading = "Yüklənir..."
back = "Geri"
continue = "Davam et"
error = "Xəta"
save = "Save"
[config.overview]
title = "Tətbiq Konfiqurasiyası"
@@ -5411,16 +5235,6 @@ finish = "Bitir"
startTour = "Tura başla"
startTourDescription = "Stirling PDF-in əsas xüsusiyyətləri üzrə bələdçili tura başlayın"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDF-ə xoş gəlmisiniz!"
description = "Əsas xüsusiyyətləri və necə başlamağı öyrənmək üçün 1 dəqiqəlik qısa tura baxmaq istəyirsiniz?"
@@ -5441,10 +5255,6 @@ download = "Yüklə →"
showMeAround = "Turu göstər"
skipTheTour = "Turu keç"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Hələlik ötür"
seePlans = "Planlara baxın →"
@@ -5758,28 +5568,6 @@ contactSales = "Satışla əlaqə"
contactToUpgrade = "Planınızı yüksəltmək və ya fərdiləşdirmək üçün bizimlə əlaqə saxlayın"
maxUsers = "Maksimum İstifadəçi"
upTo = "Maksimum"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "ay"
@@ -5983,8 +5771,6 @@ notAvailable = "Audit sistemi əlçatan deyil"
notAvailableMessage = "Audit sistemi konfiqurasiya edilməyib və ya əlçatan deyil."
disabled = "Audit jurnalı deaktiv edilib"
disabledMessage = "Sistem hadisələrini izləmək üçün tətbiqin konfiqurasiyasında audit jurnalını aktivləşdirin."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Audit sistemi yüklənərkən xəta"
@@ -6239,8 +6025,6 @@ reset = "Dəyişiklikləri sıfırla"
downloadJson = "JSON-u endir"
generatePdf = "PDF yarat"
saveChanges = "Dəyişiklikləri yadda saxla"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Mətni avtomatik miqyasla"
@@ -6259,24 +6043,6 @@ descriptionInline = "Məsləhət: Mətn qutularını çoxseçim üçün Ctrl (Cm
title = "Redaktə olunmuş mətni tək PDF elementinə kilidlə"
description = "Aktiv olduqda, redaktor hər redaktə edilmiş mətn qutusunu üst-üstə düşən qliflərdən və ya qarışıq şriftlərdən qaçmaq üçün bir PDF mətn elementi kimi ixrac edir."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Seçilmiş qutuları birləşdir"
merge = "Seçimi birləşdir"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Разширено"
edit = "Преглед и редактиране"
popular = "Популярни"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Предпочитания"
@@ -439,25 +435,6 @@ latestVersion = "Последна версия"
checkForUpdates = "Провери за актуализации"
viewDetails = "Виж подробности"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Клавишни комбинации"
description = "Персонализирайте клавишните комбинации за бърз достъп до инструментите. Щракнете \"Промяна на комбинацията\" и натиснете нова клавишна комбинация. Натиснете Esc за отказ."
@@ -511,16 +488,11 @@ low = "Нисък"
title = "Промяна на идентификационните данни"
header = "Актуализирайте данните за акаунта си"
changePassword = "Използвате идентификационни данни за вход по подразбиране. Моля, въведете нова парола"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Ново потребителско име"
oldPassword = "Текуща парола"
newPassword = "Нова парола"
confirmNewPassword = "Подтвърдете новата парола"
submit = "Изпращане на промените"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Настройки на акаунта"
@@ -736,11 +708,6 @@ tags = "подпис,автограф"
title = "Подпишете"
desc = "Добавя подпис към PDF чрез рисунка, текст или изображение"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "опростяване,премахване,интерактивни"
title = "Изравняване"
@@ -1278,21 +1245,6 @@ cbzOptions = "Опции за CBZ към PDF"
optimizeForEbook = "Оптимизиране на PDF за четци на електронни книги (използва Ghostscript)"
cbzOutputOptions = "Опции за PDF към CBZ"
cbzDpi = "DPI за изобразяване на изображение"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "преобразуване,img,jpg,изображение,снимка"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Добавяне на прикачен файл"
remove = "Премахване на прикачен файл"
embed = "Вграждане на прикачен файл"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Запазени"
label = "Качете изображение на подпис"
placeholder = "Изберете файл с изображение"
hint = "Качете PNG или JPG изображение на вашия подпис"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Как да добавите подпис"
@@ -2408,11 +2351,6 @@ note = "Сплескването премахва интерактивните
label = "Изравнете само форми"
desc = "Сплесквай само полетата на формите, оставяйки другите интерактивни елементи непокътнати"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Резултати от сплескване"
@@ -2987,7 +2925,6 @@ header = "Изрязване на PDF"
submit = "Подайте"
noFileSelected = "Изберете PDF файл, за да започнете изрязването"
reset = "Нулиране към целия PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Избор на област за изрязване"
@@ -3405,19 +3342,6 @@ placeholder = "Въведете брой хоризонтални деления
label = "Вертикални разделения"
placeholder = "Въведете брой вертикални деления"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Печат,добавяне на изображение,централно изображение,воден знак,PDF,вграждане,персонализиране"
header = "Поставяне на печат на PDF"
@@ -3779,19 +3703,6 @@ filesize = "Размер на файла"
[compress.grayscale]
label = "Приложи сива скала за компресиране"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Преглед на настройките за компресия"
@@ -3809,10 +3720,6 @@ bullet2 = "По-високите стойности намаляват разм
title = "Сива скала"
text = "Изберете тази опция, за да конвертирате всички изображения в черно-бяло, което може значително да намали размера на файла, особено за сканирани PDF-и или документи с много изображения."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Възникна грешка при компресиране на PDF."
@@ -3825,11 +3732,6 @@ failed = "Възникна грешка при компресиране на PDF
_value = "Настройки за компресия"
1 = "1-3 компресия на PDF,</br> 4-6 лека компресия на изображения,</br> 7-9 силна компресия на изображения Ще намали значително качеството на изображенията"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Този файл е защитен с парола. Моля, въведете паролата:"
cancelled = "Операцията за PDF е отменена: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Изтрий избраните страници"
closePdf = "Затвори PDF"
exportAll = "Експорт на PDF"
downloadSelected = "Изтегли избраните файлове"
annotations = "Annotations"
exportSelected = "Експорт на избраните страници"
saveChanges = "Запази промените"
downloadAll = "Изтегли всички"
saveAll = "Запази всички"
toggleTheme = "Превключи тема"
toggleBookmarks = "Превключи отметките"
language = "Език"
toggleAnnotations = "Показване/скриване на анотациите"
search = "Търсене в PDF"
panMode = "Режим на придвижване"
rotateLeft = "Завърти наляво"
rotateRight = "Завърти надясно"
toggleSidebar = "Показване/скриване на страничната лента"
toggleBookmarks = "Превключи отметките"
exportSelected = "Експорт на избраните страници"
toggleAnnotations = "Показване/скриване на анотациите"
annotationMode = "Превключи режим на анотации"
print = "Печат на PDF"
downloadAll = "Изтегли всички"
saveAll = "Запази всички"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Рисуване"
save = "Запази"
saveChanges = "Запази промените"
[search]
title = "Търсене в PDF"
@@ -4205,20 +4038,12 @@ settings = "Опции"
adminSettings = "Админ опции"
allTools = "All Tools"
reader = "Четец"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Обиколка на инструментите"
toolsTourDesc = "Научете какво могат инструментите"
adminTour = "Обиколка за админи"
adminTourDesc = "Разгледайте админ настройките и функциите"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Грешка"
@@ -5244,7 +5069,6 @@ loading = "Зареждане..."
back = "Назад"
continue = "Продължи"
error = "Грешка"
save = "Save"
[config.overview]
title = "Конфигурация на приложението"
@@ -5411,16 +5235,6 @@ finish = "Готово"
startTour = "Започни обиколката"
startTourDescription = "Направете обиколка с водач на основните функции на Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Добре дошли в Stirling PDF!"
description = "Искате ли бърза 1-минутна обиколка, за да научите основните функции и как да започнете?"
@@ -5441,10 +5255,6 @@ download = "Изтегли →"
showMeAround = "Разходи ме из новото"
skipTheTour = "Пропусни обиколката"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Пропусни засега"
seePlans = "Виж плановете →"
@@ -5758,28 +5568,6 @@ contactSales = "Свържете се с отдел Продажби"
contactToUpgrade = "Свържете се с нас, за да надградите или персонализирате плана си"
maxUsers = "Макс. потребители"
upTo = "До"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "месец"
@@ -5983,8 +5771,6 @@ notAvailable = "Системата за одит не е налична"
notAvailableMessage = "Системата за одит не е конфигурирана или не е налична."
disabled = "Одитният лог е изключен"
disabledMessage = "Активирайте одитното логване в конфигурацията на приложението, за да проследявате системни събития."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Грешка при зареждане на системата за одит"
@@ -6239,8 +6025,6 @@ reset = "Отмени промените"
downloadJson = "Изтегли JSON"
generatePdf = "Генерирай PDF"
saveChanges = "Запази промените"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Авто-мащабиране на текст за напасване в полетата"
@@ -6259,24 +6043,6 @@ descriptionInline = "Съвет: Задръжте Ctrl (Cmd) или Shift за
title = "Заключи редактирания текст към един PDF елемент"
description = "Когато е включено, редакторът експортира всяко редактирано текстово поле като един PDF текстов елемент, за да избегне застъпване на глифове или смесени шрифтове."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Слей избраните полета"
merge = "Слей избраното"
File diff suppressed because it is too large Load Diff
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avançat"
edit = "Visualitzar i Editar"
popular = "Popular"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferències"
@@ -439,25 +435,6 @@ latestVersion = "Última versió"
checkForUpdates = "Comprova actualitzacions"
viewDetails = "Veure detalls"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Dreceres de teclat"
description = "Personalitza les dreceres de teclat per accedir ràpidament a les eines. Fes clic a \"Canvia la drecera\" i prem una nova combinació de tecles. Prem Esc per cancel·lar."
@@ -511,16 +488,11 @@ low = "Baixa"
title = "Canvia les Credencials"
header = "Actualitza les Dades del Compte"
changePassword = "Estàs utilitzant les credencials d'inici de sessió per defecte. Si us plau, introdueix una nova contrasenya"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nou Nom d'Usuari"
oldPassword = "Contrasenya Actual"
newPassword = "Nova Contrasenya"
confirmNewPassword = "Confirma la Nova Contrasenya"
submit = "Envia els Canvis"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Opcions del compte"
@@ -736,11 +708,6 @@ tags = "signatura,autògraf"
title = "Signa"
desc = "Afegeix signatura al PDF mitjançant dibuix, text o imatge"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplifica,elimina,interactiu"
title = "Aplanar"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opcions de CBZ a PDF"
optimizeForEbook = "Optimitza el PDF per a lectors d'ebook (usa Ghostscript)"
cbzOutputOptions = "Opcions de PDF a CBZ"
cbzDpi = "DPI per al renderitzat d'imatges"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversió,img,jpg,imatge,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Afegeix adjunt"
remove = "Elimina adjunt"
embed = "Incrusta adjunt"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Desades"
label = "Carrega la imatge de la signatura"
placeholder = "Selecciona el fitxer d'imatge"
hint = "Carrega una imatge PNG o JPG de la teva signatura"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Com afegir la signatura"
@@ -2408,11 +2351,6 @@ note = "Aplanar elimina els elements interactius del PDF, fent-los no editables.
label = "Aplana només els formularis"
desc = "Aplana només els camps de formulari, deixant intactes altres elements interactius"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultats d'aplanament"
@@ -2987,7 +2925,6 @@ header = "Talla PDF"
submit = "Envia"
noFileSelected = "Seleccioneu un fitxer PDF per començar a retallar"
reset = "Restableix al PDF complet"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Selecció de l'àrea de retall"
@@ -3405,19 +3342,6 @@ placeholder = "Introdueix el nombre de divisions horitzontals"
label = "Divisions Verticals"
placeholder = "Introdueix el nombre de divisions verticals"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Segell, Afegeix imatge, Centra imatge, Marca d'aigua, PDF, Insereix, Personalitza"
header = "Segella PDF"
@@ -3779,19 +3703,6 @@ filesize = "Mida del Fitxer"
[compress.grayscale]
label = "Aplicar escala de grisos per a la compressió"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Resum de configuració de compressió"
@@ -3809,10 +3720,6 @@ bullet2 = "Els valors alts redueixen la mida del fitxer"
title = "Escala de grisos"
text = "Seleccioneu aquesta opció per convertir totes les imatges a blanc i negre, cosa que pot reduir significativament la mida del fitxer, especialment per a PDFs escanejats o documents amb moltes imatges."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "S'ha produït un error en comprimir el PDF."
@@ -3825,11 +3732,6 @@ failed = "S'ha produït un error en comprimir el PDF."
_value = "Configuració de compressió"
1 = "1-3 compressió de PDF,</br> 4-6 compressió lleugera d'imatges,</br> 7-9 compressió intensa d'imatges Reduirà dràsticament la qualitat de la imatge"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Aquest fitxer està protegit amb contrasenya. Si us plau, introdueix la contrasenya:"
cancelled = "Operació cancel·lada per al PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Suprimeix les pàgines seleccionades"
closePdf = "Tanca el PDF"
exportAll = "Exporta el PDF"
downloadSelected = "Descarrega els fitxers seleccionats"
annotations = "Annotations"
exportSelected = "Exporta les pàgines seleccionades"
saveChanges = "Desa els canvis"
downloadAll = "Descarrega-ho tot"
saveAll = "Desa-ho tot"
toggleTheme = "Canvia el tema"
toggleBookmarks = "Mostra/amaga marcadors"
language = "Idioma"
toggleAnnotations = "Mostra/oculta les anotacions"
search = "Cerca al PDF"
panMode = "Mode de desplaçament"
rotateLeft = "Gira a l'esquerra"
rotateRight = "Gira a la dreta"
toggleSidebar = "Mostra/oculta la barra lateral"
toggleBookmarks = "Mostra/amaga marcadors"
exportSelected = "Exporta les pàgines seleccionades"
toggleAnnotations = "Mostra/oculta les anotacions"
annotationMode = "Activa/desactiva el mode d'anotació"
print = "Imprimeix el PDF"
downloadAll = "Descarrega-ho tot"
saveAll = "Desa-ho tot"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Dibuixa"
save = "Desa"
saveChanges = "Desa els canvis"
[search]
title = "Cerca al PDF"
@@ -4205,20 +4038,12 @@ settings = "Ajustos"
adminSettings = "Ajustos admin"
allTools = "All Tools"
reader = "Lector"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Visita guiada de les eines"
toolsTourDesc = "Descobriu què poden fer les eines"
adminTour = "Visita per a administradors"
adminTourDesc = "Exploreu la configuració i les funcions d'administració"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Error"
@@ -5244,7 +5069,6 @@ loading = "Carregant..."
back = "Enrere"
continue = "Continua"
error = "Error"
save = "Save"
[config.overview]
title = "Configuració de laplicació"
@@ -5411,16 +5235,6 @@ finish = "Finalitza"
startTour = "Inicia la visita"
startTourDescription = "Feu una visita guiada per les funcions clau de Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Us donem la benvinguda a Stirling PDF!"
description = "Voleu fer una visita guiada d1 minut per conèixer les funcions clau i com començar?"
@@ -5441,10 +5255,6 @@ download = "Baixa →"
showMeAround = "Fes-me un recorregut"
skipTheTour = "Omet la visita guiada"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Omet per ara"
seePlans = "Veure plans →"
@@ -5758,28 +5568,6 @@ contactSales = "Contacta amb vendes"
contactToUpgrade = "Contacteu-nos per actualitzar o personalitzar el vostre pla"
maxUsers = "Nombre màxim dusuaris"
upTo = "Fins a"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mes"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistema dauditoria no disponible"
notAvailableMessage = "El sistema dauditoria no està configurat o no està disponible."
disabled = "El registre dauditoria està desactivat"
disabledMessage = "Activeu el registre dauditoria a la configuració de laplicació per fer el seguiment dels esdeveniments del sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Error en carregar el sistema dauditoria"
@@ -6239,8 +6025,6 @@ reset = "Restableix els canvis"
downloadJson = "Descarrega JSON"
generatePdf = "Genera PDF"
saveChanges = "Deseu els canvis"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Autoajusta el text a les caixes"
@@ -6259,24 +6043,6 @@ descriptionInline = "Consell: Mantén premut Ctrl (Cmd) o Shift per seleccionar
title = "Bloqueja el text editat a un únic element del PDF"
description = "Quan s'habilita, l'editor exporta cada quadre de text editat com un sol element de text del PDF per evitar glifs superposats o tipus de lletra barrejats."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Fusiona els quadres seleccionats"
merge = "Fusiona la selecció"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Pokročilé"
edit = "Zobrazit a upravit"
popular = "Oblíbené"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Předvolby"
@@ -439,25 +435,6 @@ latestVersion = "Nejnovější verze"
checkForUpdates = "Zkontrolovat aktualizace"
viewDetails = "Zobrazit podrobnosti"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Klávesové zkratky"
description = "Přizpůsobte si klávesové zkratky pro rychlý přístup k nástrojům. Klikněte na „Změnit zkratku“ a stiskněte novou kombinaci kláves. Stisknutím Esc zrušíte."
@@ -511,16 +488,11 @@ low = "Nízká"
title = "Změnit přihlašovací údaje"
header = "Aktualizovat údaje vašeho účtu"
changePassword = "Používáte výchozí přihlašovací údaje. Zadejte prosím nové heslo"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nové uživatelské jméno"
oldPassword = "Současné heslo"
newPassword = "Nové heslo"
confirmNewPassword = "Potvrdit nové heslo"
submit = "Potvrdit změny"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Nastavení účtu"
@@ -736,11 +708,6 @@ tags = "podpis,autogram"
title = "Podepsat"
desc = "Přidá podpis do PDF kreslením, textem nebo obrázkem"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "zjednodušit,odstranit,interaktivní"
title = "Zploštit"
@@ -1278,21 +1245,6 @@ cbzOptions = "Možnosti CBZ → PDF"
optimizeForEbook = "Optimalizovat PDF pro čtečky eknih (používá Ghostscript)"
cbzOutputOptions = "Možnosti PDF → CBZ"
cbzDpi = "DPI pro vykreslení obrázků"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "převod,img,jpg,obrázek,fotka"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Přidat přílohu"
remove = "Odebrat přílohu"
embed = "Vložit přílohu"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Uložené"
label = "Nahrát obrázek podpisu"
placeholder = "Vyberte obrazový soubor"
hint = "Nahrajte PNG nebo JPG s vaším podpisem"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Jak přidat podpis"
@@ -2408,11 +2351,6 @@ note = "Zploštění odstraní interaktivní prvky z PDF a učiní je needitovat
label = "Zploštit pouze formuláře"
desc = "Zploštit pouze formulářová pole, ostatní interaktivní prvky ponechat"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Výsledky zploštění"
@@ -2987,7 +2925,6 @@ header = "Oříznout PDF"
submit = "Odeslat"
noFileSelected = "Vyberte soubor PDF pro zahájení ořezu"
reset = "Obnovit na celé PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Výběr oblasti ořezu"
@@ -3405,19 +3342,6 @@ placeholder = "Zadejte počet horizontálních dělení"
label = "Vertikální dělení"
placeholder = "Zadejte počet vertikálních dělení"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Razítko,Přidat obrázek,centrovat obrázek,Vodoznak,PDF,Vložit,Přizpůsobit"
header = "Razítko PDF"
@@ -3779,19 +3703,6 @@ filesize = "Velikost souboru"
[compress.grayscale]
label = "Použít stupnici šedi pro kompresi"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Přehled nastavení komprese"
@@ -3809,10 +3720,6 @@ bullet2 = "Vyšší hodnoty snižují velikost souboru"
title = "Stupně šedi"
text = "Vyberte tuto možnost pro převod všech obrázků do černobílé, což může výrazně snížit velikost souboru, zejména u skenovaných PDF nebo dokumentů s mnoha obrázky."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Při kompresi PDF došlo k chybě."
@@ -3825,11 +3732,6 @@ failed = "Při kompresi PDF došlo k chybě."
_value = "Nastavení komprese"
1 = "13 komprese PDF,</br> 46 mírná komprese obrázků,</br> 79 silná komprese obrázků výrazně sníží kvalitu obrazu"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Tento soubor je chráněn heslem. Zadejte prosím heslo:"
cancelled = "Operace byla zrušena pro PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Smazat vybrané stránky"
closePdf = "Zavřít PDF"
exportAll = "Exportovat PDF"
downloadSelected = "Stáhnout vybrané soubory"
annotations = "Annotations"
exportSelected = "Exportovat vybrané stránky"
saveChanges = "Uložit změny"
downloadAll = "Stáhnout vše"
saveAll = "Uložit vše"
toggleTheme = "Přepnout motiv"
toggleBookmarks = "Přepnout záložky"
language = "Jazyk"
toggleAnnotations = "Přepnout viditelnost anotací"
search = "Hledat v PDF"
panMode = "Režim posunu"
rotateLeft = "Otočit doleva"
rotateRight = "Otočit doprava"
toggleSidebar = "Přepnout postranní panel"
toggleBookmarks = "Přepnout záložky"
exportSelected = "Exportovat vybrané stránky"
toggleAnnotations = "Přepnout viditelnost anotací"
annotationMode = "Přepnout režim anotací"
print = "Tisk PDF"
downloadAll = "Stáhnout vše"
saveAll = "Uložit vše"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Kreslit"
save = "Uložit"
saveChanges = "Uložit změny"
[search]
title = "Hledat v PDF"
@@ -4205,20 +4038,12 @@ settings = "Nastav."
adminSettings = "Admin nastav."
allTools = "All Tools"
reader = "Čtečka"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Prohlídka nástrojů"
toolsTourDesc = "Zjistěte, co nástroje umí"
adminTour = "Prohlídka administrace"
adminTourDesc = "Prozkoumejte nastavení a funkce pro správce"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Chyba"
@@ -5244,7 +5069,6 @@ loading = "Načítání..."
back = "Zpět"
continue = "Pokračovat"
error = "Chyba"
save = "Save"
[config.overview]
title = "Konfigurace aplikace"
@@ -5411,16 +5235,6 @@ finish = "Dokončit"
startTour = "Spustit prohlídku"
startTourDescription = "Vydejte se na průvodce hlavními funkcemi Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Vítejte ve Stirling PDF!"
description = "Chcete si dát rychlou 1minutovou prohlídku a naučit se klíčové funkce a jak začít?"
@@ -5441,10 +5255,6 @@ download = "Stáhnout →"
showMeAround = "Proveďte mě"
skipTheTour = "Přeskočit průvodce"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Zatím přeskočit"
seePlans = "Zobrazit plány →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontaktovat obchod"
contactToUpgrade = "Kontaktujte nás pro upgrade nebo úpravu plánu"
maxUsers = "Max. počet uživatelů"
upTo = "Až"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "měsíc"
@@ -5983,8 +5771,6 @@ notAvailable = "Systém auditu není k dispozici"
notAvailableMessage = "Systém auditu není nakonfigurován nebo není k dispozici."
disabled = "Záznam auditu je vypnutý"
disabledMessage = "Pro sledování systémových událostí povolte záznam auditu v konfiguraci aplikace."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Chyba při načítání systému auditu"
@@ -6239,8 +6025,6 @@ reset = "Obnovit změny"
downloadJson = "Stáhnout JSON"
generatePdf = "Vytvořit PDF"
saveChanges = "Uložit změny"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Automaticky přizpůsobit text rámečkům"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tip: Podržením Ctrl (Cmd) nebo Shift vyberete více texto
title = "Uzamknout upravený text do jednoho prvku PDF"
description = "Při zapnutí editor exportuje každý upravený textový rámeček jako jeden textový prvek PDF, aby se předešlo překrývání znaků nebo míchání fontů."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Sloučit vybrané rámečky"
merge = "Sloučit výběr"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avanceret"
edit = "Vis & Redigér"
popular = "Populære"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Præferencer"
@@ -439,25 +435,6 @@ latestVersion = "Seneste version"
checkForUpdates = "Søg efter opdateringer"
viewDetails = "Vis detaljer"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Tastaturgenveje"
description = "Tilpas tastaturgenveje for hurtig adgang til værktøjer. Klik på \"Skift genvej\" og tryk en ny tastekombination. Tryk Esc for at annullere."
@@ -511,16 +488,11 @@ low = "Lav"
title = "Skift Legitimationsoplysninger"
header = "Opdater Dine Kontooplysninger"
changePassword = "Du bruger standard loginoplysninger. Indtast venligst en ny adgangskode"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nyt Brugernavn"
oldPassword = "Nuværende Adgangskode"
newPassword = "Ny Adgangskode"
confirmNewPassword = "Bekræft Ny Adgangskode"
submit = "Indsend Ændringer"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Kontoindstillinger"
@@ -736,11 +708,6 @@ tags = "underskrift,autograf"
title = "Underskriv"
desc = "Tilføjer underskrift til PDF ved tegning, tekst eller billede"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "forenkle,fjern,interaktiv"
title = "Udjævn"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ til PDF-indstillinger"
optimizeForEbook = "Optimer PDF til e-bogslæsere (bruger Ghostscript)"
cbzOutputOptions = "PDF til CBZ-indstillinger"
cbzDpi = "DPI for billedgengivelse"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konvertering,img,jpg,billede,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Tilføj vedhæftning"
remove = "Fjern vedhæftning"
embed = "Indlejr vedhæftning"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Gemt"
label = "Upload billede af underskrift"
placeholder = "Vælg billedfil"
hint = "Upload et PNG- eller JPG-billede af din underskrift"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Sådan tilføjer du underskrift"
@@ -2408,11 +2351,6 @@ note = "Udfladning fjerner interaktive elementer fra PDF'en, så de ikke kan red
label = "Udjævn kun formularer"
desc = "Udflad kun formularfelter og lad andre interaktive elementer være intakte"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultater for udfladning"
@@ -2987,7 +2925,6 @@ header = "Beskær PDF"
submit = "Indsend"
noFileSelected = "Vælg en PDF for at begynde beskæring"
reset = "Nulstil til fuld PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Valg af beskæringsområde"
@@ -3405,19 +3342,6 @@ placeholder = "Indtast antal horisontale delinger"
label = "Vertikal Deling"
placeholder = "Indtast antal af vertikale delinger"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stempel, Tilføj billede, centrer billede, Vandmærke, PDF, Indlejr, Tilpas"
header = "Stempel PDF"
@@ -3779,19 +3703,6 @@ filesize = "Filstørrelse"
[compress.grayscale]
label = "Anvend gråskala til komprimering"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Overblik over komprimeringsindstillinger"
@@ -3809,10 +3720,6 @@ bullet2 = "Højere værdier reducerer filstørrelsen"
title = "Gråtoner"
text = "Vælg denne indstilling for at konvertere alle billeder til sort/hvid, hvilket kan reducere filstørrelsen betydeligt, især for scannede PDF'er eller dokumenter med mange billeder."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Der opstod en fejl under komprimering af PDF'en."
@@ -3825,11 +3732,6 @@ failed = "Der opstod en fejl under komprimering af PDF'en."
_value = "Komprimeringsindstillinger"
1 = "1-3 PDF-komprimering,</br> 4-6 let billedkomprimering,</br> 7-9 intens billedkomprimering vil markant reducere billedkvaliteten"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Denne fil er adgangskodebeskyttet. Indtast adgangskoden:"
cancelled = "Handling annulleret for PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Slet valgte sider"
closePdf = "Luk PDF"
exportAll = "Eksporter PDF"
downloadSelected = "Download valgte filer"
annotations = "Annotations"
exportSelected = "Eksporter valgte sider"
saveChanges = "Gem ændringer"
downloadAll = "Download alle"
saveAll = "Gem alle"
toggleTheme = "Skift tema"
toggleBookmarks = "Skift bogmærker"
language = "Sprog"
toggleAnnotations = "Skift visning af annoteringer"
search = "Søg i PDF"
panMode = "Pan-tilstand"
rotateLeft = "Rotér venstre"
rotateRight = "Rotér højre"
toggleSidebar = "Skift sidepanel"
toggleBookmarks = "Skift bogmærker"
exportSelected = "Eksporter valgte sider"
toggleAnnotations = "Skift visning af annoteringer"
annotationMode = "Skift annoteringstilstand"
print = "Udskriv PDF"
downloadAll = "Download alle"
saveAll = "Gem alle"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Tegn"
save = "Gem"
saveChanges = "Gem ændringer"
[search]
title = "Søg i PDF"
@@ -4205,20 +4038,12 @@ settings = "Indstil."
adminSettings = "Admin Indstil."
allTools = "All Tools"
reader = "Læser"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Rundtur i værktøjer"
toolsTourDesc = "Lær hvad værktøjerne kan"
adminTour = "Admin-rundtur"
adminTourDesc = "Udforsk adminindstillinger og funktioner"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Fejl"
@@ -5244,7 +5069,6 @@ loading = "Indlæser..."
back = "Tilbage"
continue = "Fortsæt"
error = "Fejl"
save = "Save"
[config.overview]
title = "Applikationskonfiguration"
@@ -5411,16 +5235,6 @@ finish = "Færdig"
startTour = "Start rundtur"
startTourDescription = "Tag en guidet tur gennem Stirling PDFs nøglefunktioner"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Velkommen til Stirling PDF!"
description = "Vil du tage en hurtig rundtur på 1 minut for at lære nøglefunktionerne og hvordan du kommer i gang?"
@@ -5441,10 +5255,6 @@ download = "Download →"
showMeAround = "Vis mig rundt"
skipTheTour = "Spring rundvisningen over"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Spring over for nu"
seePlans = "Se planer →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontakt salg"
contactToUpgrade = "Kontakt os for at opgradere eller tilpasse din plan"
maxUsers = "Maks. brugere"
upTo = "Op til"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "måned"
@@ -5983,8 +5771,6 @@ notAvailable = "Auditsystem ikke tilgængeligt"
notAvailableMessage = "Auditsystemet er ikke konfigureret eller ikke tilgængeligt."
disabled = "Auditlogning er deaktiveret"
disabledMessage = "Aktivér auditlogning i din applikationskonfiguration for at spore systemhændelser."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Fejl ved indlæsning af auditsystem"
@@ -6239,8 +6025,6 @@ reset = "Nulstil ændringer"
downloadJson = "Download JSON"
generatePdf = "Generer PDF"
saveChanges = "Gem ændringer"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Autoskalér tekst, så den passer i bokse"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tip: Hold Ctrl (Cmd) eller Shift for at multivælge tekstbo
title = "Lås redigeret tekst til ét enkelt PDF-element"
description = "Når aktiveret, eksporterer editoren hver redigeret tekstboks som ét PDF-textelement for at undgå overlap af glyffer eller blandede skrifttyper."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Flet valgte bokse"
merge = "Flet markering"
+50 -555
View File
@@ -1,5 +1,5 @@
unsavedChanges = "Sie haben ungespeicherte Änderungen an Ihrer PDF. Was möchten Sie tun?"
areYouSure = "Möchten Sie die Seite wirklich verlassen?"
areYouSure = "Möchten Sie wirklich verlassen?"
unsavedChangesTitle = "Ungespeicherte Änderungen"
keepWorking = "Weiterarbeiten"
discardChanges = "Änderungen verwerfen"
@@ -18,8 +18,8 @@ multiPdfDropPrompt = "Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie si
imgPrompt = "Wählen Sie ein Bild"
genericSubmit = "Absenden"
uploadLimit = "Maximale Dateigröße:"
uploadLimitExceededSingular = "ist zu groß. Die maximal zulässige Größe beträgt"
uploadLimitExceededPlural = "sind zu groß. Die maximal zulässige Größe beträgt"
uploadLimitExceededSingular = "ist zu groß. Die maximal zulässige Größe ist"
uploadLimitExceededPlural = "sind zu groß. Die maximal zulässige Größe ist"
processTimeWarning = "Achtung: Abhängig von der Dateigröße kann dieser Prozess bis zu einer Minute dauern"
pageOrderPrompt = "Seitenreihenfolge (Geben Sie eine durch Komma getrennte Liste von Seitenzahlen ein):"
goToPage = "Gehe zu"
@@ -29,16 +29,16 @@ unknown = "Unbekannt"
save = "Speichern"
saveToBrowser = "Im Browser speichern"
download = "Herunterladen"
downloadUnavailable = "Download für dieses Element ist nicht verfügbar"
saveUnavailable = "Speichern für dieses Element ist nicht verfügbar"
downloadUnavailable = "Download für dieses Element nicht verfügbar"
saveUnavailable = "Speichern für dieses Element nicht verfügbar"
pin = "Datei anheften (nach Tool-Ausführung aktiv halten)"
unpin = "Datei lösen (nach Tool-Ausführung ersetzen)"
undoOperationTooltip = "Klicken Sie, um die letzte Operation rückgängig zu machen und die ursprünglichen Dateien wiederherzustellen"
undoOperationTooltip = "Klicken zum Rückgängigmachen der letzten Operation und Wiederherstellen der ursprünglichen Dateien"
undo = "Rückgängig"
back = "Zurück"
nothingToUndo = "Nichts zum Rückgängig machen"
moreOptions = "Weitere Optionen"
editYourNewFiles = "Ihre neuen Dateien bearbeiten"
editYourNewFiles = "Ihre neue(n) Datei(en) bearbeiten"
close = "Schließen"
openInViewer = "Im Viewer öffnen"
confirmClose = "Schließen bestätigen"
@@ -69,9 +69,9 @@ white = "Weiß"
red = "Rot"
green = "Grün"
blue = "Blau"
custom = "Benutzerdefiniert..."
custom = "benutzerdefiniert..."
comingSoon = "Demnächst verfügbar"
WorkInProgess = "In Arbeit: funktioniert möglicherweise nicht oder ist fehlerhaft. Bitte melden Sie alle Probleme."
WorkInProgess = "In Arbeit, funktioniert möglicherweise nicht oder ist fehlerhaft. Bitte melden Sie alle Probleme!"
poweredBy = "Bereitgestellt von"
yes = "Ja"
no = "Nein"
@@ -128,9 +128,6 @@ undoQuotaError = "Rückgängig nicht möglich: unzureichender Speicherplatz"
undoStorageError = "Rückgängig abgeschlossen, aber einige Dateien konnten nicht im Speicher gespeichert werden"
undoSuccess = "Vorgang erfolgreich rückgängig gemacht"
unsupported = "Nicht unterstützt"
discardRedactions = "Discard & Leave"
pendingRedactions = "You have unapplied redactions that will be lost."
pendingRedactionsTitle = "Unapplied Redactions"
[toolPanel]
placeholder = "Wählen Sie ein Tool, um zu starten"
@@ -261,7 +258,7 @@ _value = "Fehler"
dismissAllErrors = "Alle Fehler ausblenden"
sorry = "Entschuldigung für das Problem!"
needHelp = "Brauchen Sie Hilfe / Ein Problem gefunden?"
contactTip = "Wenn Sie weiterhin Probleme haben, zögern Sie nicht, uns um Hilfe zu bitten. Sie können ein Ticket auf unserer GitHub-Seite einreichen oder uns über Discord kontaktieren:"
contactTip = "Wenn Sie weiterhin Probleme haben, zögern Sie nicht, uns um Hilfe zu bitten. Du kannst ein Ticket auf unserer GitHub-Seite einreichen oder uns über Discord kontaktieren:"
github = "Ein Ticket auf GitHub einreichen"
showStack = "Stack-Trace anzeigen"
copyStack = "Stack-Trace kopieren"
@@ -283,7 +280,7 @@ terms = "AGB"
accessibility = "Barrierefreiheit"
cookie = "Cookie-Richtlinie"
impressum = "Impressum"
showCookieBanner = "Cookie-Einstellungen"
showCookieBanner = "Cookie Einstellungen"
[pipeline]
header = "Pipeline-Menü (Beta)"
@@ -294,7 +291,7 @@ submitButton = "Ausführen"
help = "Hilfe für Pipeline"
scanHelp = "Hilfe zum Ordnerscan"
deletePrompt = "Möchten Sie die Pipeline wirklich löschen?"
tags = "automatisieren,sequenzieren,skriptgesteuert,batch-prozess"
tags = "automatisieren,sequenzieren,skriptgesteuert,batch prozess"
title = "Pipeline"
[pipelineOptions]
@@ -343,10 +340,6 @@ advance = "Erweiterte Funktionen"
edit = "Anzeigen und Bearbeiten"
popular = "Beliebt"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Einstellungen"
@@ -367,7 +360,6 @@ advanced = "Erweitert"
title = "Sicherheit & Authentifizierung"
security = "Sicherheit"
connections = "Verbindungen"
telegram = "Telegram"
[settings.licensingAnalytics]
title = "Lizenzierung & Analytics"
@@ -442,32 +434,6 @@ currentVersion = "Aktuelle Version"
latestVersion = "Neueste Version"
checkForUpdates = "Nach Updates suchen"
viewDetails = "Details anzeigen"
serverNeedsUpdate = "Server needs to be updated by administrator"
[settings.general.versionInfo]
description = "Desktop and server version details"
desktop = "Desktop Version"
server = "Server Version"
title = "Version Information"
[settings.security]
title = "Sicherheit"
description = "Aktualisieren Sie Ihr Passwort, um Ihr Konto zu schützen."
[settings.security.password]
subtitle = "Ändern Sie Ihr Passwort. Nach dem Update werden Sie abgemeldet."
required = "Alle Felder sind erforderlich."
mismatch = "Die neuen Passwörter stimmen nicht überein."
error = "Passwort konnte nicht aktualisiert werden. Bitte überprüfen Sie Ihr aktuelles Passwort und versuchen Sie es erneut."
success = "Passwort erfolgreich aktualisiert. Bitte melden Sie sich erneut an."
ssoDisabled = "Passwortänderungen werden von Ihrem Identity-Provider verwaltet."
current = "Aktuelles Passwort"
currentPlaceholder = "Geben Sie Ihr aktuelles Passwort ein"
new = "Neues Passwort"
newPlaceholder = "Neues Passwort eingeben"
confirm = "Neues Passwort bestätigen"
confirmPlaceholder = "Neues Passwort erneut eingeben"
update = "Passwort aktualisieren"
[settings.hotkeys]
title = "Tastenkürzel"
@@ -522,21 +488,16 @@ low = "Niedrig"
title = "Anmeldeinformationen ändern"
header = "Aktualisieren Sie Ihre Kontodaten"
changePassword = "Sie verwenden die Standard-Zugangsdaten. Bitte geben Sie ein neues Passwort ein."
ssoManaged = "Ihr Konto wird von Ihrem Identity-Provider verwaltet."
newUsername = "Neuer Benutzername"
oldPassword = "Aktuelles Passwort"
newPassword = "Neues Passwort"
confirmNewPassword = "Neues Passwort bestätigen"
submit = "Änderung speichern"
credsUpdated = "Konto aktualisiert"
description = "Änderungen gespeichert. Bitte melden Sie sich erneut an."
error = "Benutzername konnte nicht aktualisiert werden. Bitte überprüfen Sie Ihr Passwort und versuchen Sie es erneut."
changeUsername = "Aktualisieren Sie Ihren Benutzernamen. Nach dem Update werden Sie abgemeldet."
[account]
title = "Kontoeinstellungen"
accountSettings = "Kontoeinstellungen"
adminSettings = "Admin-Einstellungen Benutzer anzeigen und hinzufügen"
adminSettings = "Admin Einstellungen - Benutzer anzeigen und hinzufügen"
userControlSettings = "Benutzerkontrolle"
changeUsername = "Benutzername ändern"
newUsername = "Neuer Benutzername"
@@ -546,15 +507,13 @@ newPassword = "Neues Passwort"
changePassword = "Passwort ändern"
confirmNewPassword = "Neues Passwort bestätigen"
signOut = "Abmelden"
yourApiKey = "Ihr API-Schlüssel"
yourApiKey = "Dein API-Schlüssel"
syncTitle = "Browsereinstellungen mit Konto synchronisieren"
settingsCompare = "Einstellungen vergleichen:"
property = "Eigenschaft"
webBrowserSettings = "Webbrowser-Einstellung"
syncToBrowser = "Konto → Browser synchronisieren"
syncToAccount = "Konto ← Browser synchronisieren"
changeUsernameDescription = "Update your username. You will be logged out after updating."
newUsernamePlaceholder = "Enter your new username"
syncToBrowser = "Synchronisiere Konto -> Browser"
syncToAccount = "Synchronisiere Konto <- Browser"
[adminUserSettings]
title = "Benutzerkontrolle"
@@ -749,11 +708,6 @@ tags = "unterschrift,autogramm"
title = "Signieren"
desc = "Fügt PDF-Signaturen durch Zeichnung, Text oder Bild hinzu"
[home.annotate]
tags = "annotieren,highlight,zeichnen"
title = "Annotieren"
desc = "Im Viewer markieren, zeichnen, Notizen und Formen hinzufügen"
[home.flatten]
tags = "vereinfachen,entfernen,interaktiv"
title = "Abflachen"
@@ -976,7 +930,6 @@ desc = "Beliebigen Text überall in Ihrem PDF hinzufügen"
addFiles = "Dateien hinzufügen"
uploadFromComputer = "Vom Computer hochladen"
openFromComputer = "Vom Computer öffnen"
mobileUpload = "Upload from Mobile"
[viewPdf]
tags = "anzeigen,lesen,kommentieren,text,bild"
@@ -984,7 +937,7 @@ title = "PDF anzeigen/bearbeiten"
header = "PDF anzeigen"
[multiTool]
tags = "Multi-Tool,Mehrfachoperation,UI,Klicken und Ziehen,Frontend,clientseitig"
tags = "Multi Tool,Multi operation,UI,click drag,front end,client side"
title = "PDF-Multitool"
header = "PDF-Multitool"
uploadPrompts = "Dateiname"
@@ -1292,33 +1245,6 @@ cbzOptions = "Optionen: CBZ zu PDF"
optimizeForEbook = "PDF für E-Book-Reader optimieren (verwendet Ghostscript)"
cbzOutputOptions = "Optionen: PDF zu CBZ"
cbzDpi = "DPI für Bildrendering"
cbrOptions = "CBR-Optionen"
cbrOutputOptions = "Optionen: PDF zu CBR"
cbrDpi = "DPI für Bildrendering"
[convert.ebookOptions]
ebookOptions = "Optionen: E-Book zu PDF"
ebookOptionsDesc = "Optionen zum Konvertieren von E-Books in PDF"
embedAllFonts = "Alle Schriftarten einbetten"
embedAllFontsDesc = "Alle Schriftarten aus dem E-Book in das erzeugte PDF einbetten"
includeTableOfContents = "Inhaltsverzeichnis einfügen"
includeTableOfContentsDesc = "Ein erzeugtes Inhaltsverzeichnis zum Ergebnis-PDF hinzufügen"
includePageNumbers = "Seitenzahlen einfügen"
includePageNumbersDesc = "Seitenzahlen zum erzeugten PDF hinzufügen"
optimizeForEbookPdf = "Für E-Book-Reader optimieren"
optimizeForEbookPdfDesc = "PDF für das Lesen auf E-Book-Readern optimieren (kleinere Dateigröße, bessere Darstellung auf E-Ink-Geräten)"
[convert.epubOptions]
detectChapters = "Detect chapters"
detectChaptersDesc = "Detect headings that look like chapters and insert EPUB page breaks"
epubOptions = "PDF to eBook Options"
epubOptionsDesc = "Options for converting PDF to EPUB/AZW3"
kindleEink = "Kindle e-Ink (text optimized)"
outputFormat = "Output format"
outputFormatDesc = "Choose the output format for the ebook"
tabletPhone = "Tablet/Phone (with images)"
targetDevice = "Target device"
targetDeviceDesc = "Choose an output profile optimized for the reader device"
[imageToPdf]
tags = "konvertierung,img,jpg,bild,foto"
@@ -1435,11 +1361,6 @@ header = "Anhänge hinzufügen"
add = "Anhang hinzufügen"
remove = "Anhang entfernen"
embed = "Anhang einbetten"
convertToPdfA3b = "In PDF/A-3b konvertieren"
convertToPdfA3bDescription = "Erstellt ein Archiv-PDF mit eingebetteten Anhängen"
convertToPdfA3bTooltip = "PDF/A-3b ist ein Archivformat, das die langfristige Aufbewahrung sicherstellt. Es erlaubt das Einbetten beliebiger Dateiformate als Anhänge. Die Konvertierung erfordert Ghostscript und kann bei großen Dateien länger dauern."
convertToPdfA3bTooltipHeader = "Über die PDF/A-3b-Konvertierung"
convertToPdfA3bTooltipTitle = "Funktion"
submit = "Anhänge hinzufügen"
[watermark]
@@ -2385,10 +2306,6 @@ saved = "Gespeichert"
label = "Unterschriftsbild hochladen"
placeholder = "Bilddatei auswählen"
hint = "Laden Sie ein PNG- oder JPG-Bild Ihrer Unterschrift hoch"
removeBackground = "Weißen Hintergrund entfernen (transparent machen)"
processing = "Bild wird verarbeitet..."
backgroundRemovalFailedTitle = "Hintergrund konnte nicht entfernt werden"
backgroundRemovalFailedMessage = "Der Hintergrund konnte nicht aus dem Bild entfernt werden. Das Originalbild wird stattdessen verwendet."
[sign.instructions]
title = "So fügen Sie eine Unterschrift hinzu"
@@ -2434,11 +2351,6 @@ note = "Das Abflachen entfernt interaktive Elemente aus der PDF und macht sie ni
label = "Nur Formulare vereinfachen"
desc = "Nur Formularfelder vereinfachen, andere interaktive Elemente unverändert lassen"
[flatten.renderDpi]
label = "Rendering-DPI (optional, empfohlen 150 DPI)"
help = "Lassen Sie das Feld leer, um die Systemvorgabe zu verwenden. Höhere DPI schärfen das Ergebnis, erhöhen aber die Verarbeitungszeit und die Dateigröße."
placeholder = "z. B. 150"
[flatten.results]
title = "Reduzierungs-Ergebnisse"
@@ -3013,7 +2925,6 @@ header = "PDF zuschneiden"
submit = "Abschicken"
noFileSelected = "Wählen Sie eine PDF-Datei aus, um mit dem Zuschneiden zu beginnen"
reset = "Auf vollständiges PDF zurücksetzen"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Zuschneidebereich-Auswahl"
@@ -3078,7 +2989,7 @@ submit = "Aufteilen"
tags = "sauber,sicher,sicher,bedrohungen entfernen"
[URLToPDF]
tags = "webaufnahme,seite speichern,web-zu-dokument,archiv"
tags = "web capture,seite speichern,web to doc,archiv"
title = "URL zu PDF"
header = "URL zu PDF"
submit = "Konvertieren"
@@ -3247,7 +3158,6 @@ automaticDesc = "Text basierend auf Suchbegriffen schwärzen"
manual = "Manuell"
manualDesc = "Klicken und ziehen zum Schwärzen bestimmter Bereiche"
manualComingSoon = "Manuelle Schwärzung kommt bald"
automaticDisabledTooltip = "Select files in the file manager to redact multiple files at once"
[redact.auto]
header = "Auto-Schwärzung"
@@ -3315,24 +3225,6 @@ text = "Nur vollständige Wörter abgleichen, keine Teilübereinstimmungen. 'Joh
title = "In PDF-Bild konvertieren"
text = "Konvertiert das PDF nach der Schwärzung in ein bildbasiertes PDF. Dies stellt sicher, dass Text hinter Schwärzungskästen vollständig entfernt und nicht wiederherstellbar ist."
[redact.tooltip.manual.apply]
bullet1 = "Mark as many areas as needed before applying"
bullet2 = "All pending redactions are applied at once"
bullet3 = "Redactions cannot be undone after applying"
text = "After marking content, click 'Apply' to permanently redact all marked areas. The pending count shows how many redactions are ready to be applied."
title = "Apply Redactions"
[redact.tooltip.manual.header]
title = "Manual Redaction Controls"
[redact.tooltip.manual.markArea]
text = "Draw rectangular areas on the PDF to mark regions for redaction. Useful for redacting images, signatures, or irregular shapes."
title = "Mark Area Tool"
[redact.tooltip.manual.markText]
text = "Select text directly on the PDF to mark it for redaction. Click and drag to highlight specific text that you want to redact."
title = "Mark Text Tool"
[redact.manual]
header = "Manuelle Schwärzung"
textBasedRedaction = "Textbasierte Schwärzung"
@@ -3354,15 +3246,6 @@ showLayers = "Ebenen anzeigen (Doppelklick, um alle Ebenen auf den Standardzusta
colourPicker = "Farbwähler"
findCurrentOutlineItem = "Aktuelles Gliederungselement finden"
applyChanges = "Änderungen anwenden"
apply = "Apply"
applyWarning = "⚠️ Permanent application, cannot be undone and the data underneath will be deleted"
controlsTitle = "Manual Redaction Controls"
instructions = "Select text or draw areas on the PDF to mark content for redaction."
markArea = "Mark Area"
markText = "Mark Text"
noMarks = "No redaction marks. Use the tools above to mark content for redaction."
pendingLabel = "Pending:"
title = "Redaction Tools"
[redact.manual.pageRedactionNumbers]
title = "Seiten"
@@ -3459,19 +3342,6 @@ placeholder = "Anzahl horizontaler Teiler eingeben"
label = "Vertikale Teiler"
placeholder = "Anzahl vertikaler Teiler eingeben"
[split-by-sections.splitMode]
label = "Teilmodus"
description = "Wählen Sie, wie die Seiten geteilt werden sollen"
splitAll = "Alle Seiten teilen"
splitAllExceptFirst = "Alle außer der ersten teilen"
splitAllExceptLast = "Alle außer der letzten teilen"
splitAllExceptFirstAndLast = "Alle außer der ersten und letzten teilen"
custom = "Benutzerdefinierte Seiten"
[split-by-sections.customPages]
label = "Benutzerdefinierte Seitenzahlen"
placeholder = "z. B. 2,4,6"
[AddStampRequest]
tags = "stempeln,bild hinzufügen,bild zentrieren,wasserzeichen,pdf,einbetten,anpassen"
header = "PDF Stempel"
@@ -3833,19 +3703,6 @@ filesize = "Dateigröße"
[compress.grayscale]
label = "Graustufen für Komprimierung anwenden"
[compress.linearize]
label = "PDF für schnelles Web-Viewing linearisieren"
[compress.lineArt]
label = "Bilder in Strichzeichnungen umwandeln"
description = "Verwendet ImageMagick, um Seiten in kontrastreiches Schwarzweiß umzuwandeln und die Dateigröße maximal zu reduzieren."
unavailable = "ImageMagick ist auf diesem Server nicht installiert oder aktiviert"
detailLevel = "Detailgrad"
edgeEmphasis = "Kantenbetonung"
edgeLow = "Sanft"
edgeMedium = "Ausgewogen"
edgeHigh = "Stark"
[compress.tooltip.header]
title = "Kompressions-Einstellungen - Übersicht"
@@ -3863,10 +3720,6 @@ bullet2 = "Höhere Werte reduzieren die Dateigröße"
title = "Graustufen"
text = "Wählen Sie diese Option, um alle Bilder in Schwarz-Weiß zu konvertieren, was die Dateigröße erheblich reduzieren kann, insbesondere bei gescannten PDFs oder bildreichen Dokumenten."
[compress.tooltip.lineArt]
title = "Strichzeichnung"
text = "Konvertiert Seiten mit ImageMagick in kontrastreiches Schwarzweiß. Mit der Detailstufe steuern Sie, wie viel Inhalt schwarz wird, und mit der Kantenbetonung, wie aggressiv Kanten erkannt werden."
[compress.error]
failed = "Ein Fehler ist beim Komprimieren der PDF aufgetreten."
@@ -3879,11 +3732,6 @@ failed = "Ein Fehler ist beim Komprimieren der PDF aufgetreten."
_value = "Kompressionseinstellungen"
1 = "1-3 PDF-Komprimierung, </br> 4-6 Leichte Bildkomprimierung, </br> 7-9 Intensive Bildkomprimierung verringert die Bildqualität dramatisch"
[compress.compressionLevel]
range1to3 = "Niedrigere Werte bewahren die Qualität, führen aber zu größeren Dateien"
range4to6 = "Mittlere Komprimierung mit moderater Qualitätsreduktion"
range7to9 = "Höhere Werte reduzieren die Dateigröße deutlich, können aber die Bildschärfe verringern"
[decrypt]
passwordPrompt = "Diese Datei ist passwortgeschützt. Bitte geben Sie das Passwort ein:"
cancelled = "Vorgang für PDF abgebrochen: {0}"
@@ -4123,98 +3971,23 @@ deleteSelected = "Ausgewählte Seiten löschen"
closePdf = "PDF schließen"
exportAll = "PDF exportieren"
downloadSelected = "Ausgewählte Dateien herunterladen"
annotations = "Annotations"
exportSelected = "Ausgewählte Seiten exportieren"
saveChanges = "Änderungen speichern"
downloadAll = "Alle herunterladen"
saveAll = "Alle speichern"
toggleTheme = "Design wechseln"
toggleBookmarks = "Lesezeichen ein-/ausblenden"
language = "Sprache"
toggleAnnotations = "Anmerkungen ein-/ausblenden"
search = "PDF durchsuchen"
panMode = "Verschiebemodus"
rotateLeft = "Nach links drehen"
rotateRight = "Nach rechts drehen"
toggleSidebar = "Seitenleiste umschalten"
toggleBookmarks = "Lesezeichen ein-/ausblenden"
exportSelected = "Ausgewählte Seiten exportieren"
toggleAnnotations = "Anmerkungen ein-/ausblenden"
annotationMode = "Anmerkungsmodus umschalten"
print = "PDF drucken"
downloadAll = "Alle herunterladen"
saveAll = "Alle speichern"
applyRedactionsFirst = "Apply redactions first"
draw = "Draw"
exitRedaction = "Exit Redaction Mode"
redact = "Redact"
save = "Save"
[textAlign]
left = "Links"
center = "Zentriert"
right = "Rechts"
[annotation]
title = "Annotieren"
desc = "Markieren, Stift, Text und Notizen verwenden. Änderungen bleiben live kein Abflachen erforderlich."
highlight = "Markieren"
pen = "Stift"
text = "Textfeld"
note = "Notiz"
rectangle = "Rechteck"
ellipse = "Ellipse"
select = "Auswählen"
exit = "Anmerkungsmodus beenden"
strokeWidth = "Breite"
opacity = "Deckkraft"
strokeOpacity = "Linien-Deckkraft"
fillOpacity = "Fülldeckkraft"
fontSize = "Schriftgröße"
chooseColor = "Farbe wählen"
color = "Farbe"
strokeColor = "Linienfarbe"
fillColor = "Füllfarbe"
underline = "Unterstreichen"
strikeout = "Durchstreichen"
squiggly = "Wellenlinie"
inkHighlighter = "Freihand-Textmarker"
freehandHighlighter = "Freihand-Textmarker"
square = "Quadrat"
circle = "Kreis"
polygon = "Polygon"
line = "Linie"
stamp = "Bild hinzufügen"
textMarkup = "Textmarkierung"
drawing = "Zeichnung"
shapes = "Formen"
notesStamps = "Notizen & Stempel"
settings = "Einstellungen"
borderOn = "Rahmen: Ein"
borderOff = "Rahmen: Aus"
editInk = "Stift bearbeiten"
editLine = "Linie bearbeiten"
editNote = "Notiz bearbeiten"
editText = "Textfeld bearbeiten"
editTextMarkup = "Textmarkierung bearbeiten"
editSelected = "Anmerkung bearbeiten"
editSquare = "Quadrat bearbeiten"
editCircle = "Kreis bearbeiten"
editPolygon = "Polygon bearbeiten"
unsupportedType = "Dieser Anmerkungstyp wird für die Bearbeitung nicht vollständig unterstützt."
textAlignment = "Textausrichtung"
noteIcon = "Notizsymbol"
imagePreview = "Vorschau"
contents = "Text"
backgroundColor = "Hintergrundfarbe"
clearBackground = "Hintergrund entfernen"
noBackground = "Kein Hintergrund"
stampSettings = "Stempel-Einstellungen"
savingCopy = "Download wird vorbereitet..."
saveFailed = "Kopie konnte nicht gespeichert werden"
saveReady = "Download bereit"
selectAndMove = "Auswählen und Bearbeiten"
editSelectDescription = "Klicken Sie auf eine vorhandene Anmerkung, um Farbe, Deckkraft, Text oder Größe zu bearbeiten."
editStampHint = "Um das Bild zu ändern, löschen Sie diesen Stempel und fügen Sie einen neuen hinzu."
editSwitchToSelect = "Wechseln Sie zu „Auswählen und Bearbeiten“, um diese Anmerkung zu bearbeiten."
undo = "Rückgängig"
redo = "Wiederholen"
applyChanges = "Änderungen anwenden"
saveChanges = "Save Changes"
draw = "Zeichnen"
save = "Speichern"
saveChanges = "Änderungen speichern"
[search]
title = "PDF durchsuchen"
@@ -4265,20 +4038,12 @@ settings = "Optionen"
adminSettings = "Admin Optionen"
allTools = "Werkzeuge"
reader = "Reader"
tours = "Touren"
showMeAround = "Rundgang starten"
[quickAccess.toursTooltip]
admin = "Sehen Sie sich hier Touren an: Tools-Tour, V2-Layout-Tour und Admin-Tour."
user = "Sehen Sie sich hier Touren an: Tools-Tour und V2-Layout-Tour."
[quickAccess.helpMenu]
toolsTour = "Tool-Tour"
toolsTourDesc = "Erfahren Sie, was die Tools können"
adminTour = "Admin-Tour"
adminTourDesc = "Entdecken Sie Admin-Einstellungen & Funktionen"
whatsNewTour = "Neu in V2"
whatsNewTourDesc = "Tour zum aktualisierten Layout"
[admin]
error = "Fehler"
@@ -4304,8 +4069,6 @@ loginRequired = "Der Anmeldemodus muss aktiviert sein, um Admin-Einstellungen zu
restarting = "Server wird neu gestartet"
restartingMessage = "Der Server wird neu gestartet. Bitte einen Moment warten..."
restartError = "Server konnte nicht neu gestartet werden. Bitte manuell neu starten."
error = "Failed to save settings"
success = "Settings saved successfully"
[admin.settings.unsavedChanges]
title = "Ungespeicherte Änderungen"
@@ -4422,10 +4185,6 @@ description = "Pfad zur WeasyPrint-Ausführungsdatei für HTML-zu-PDF-Konvertier
label = "Unoconvert-Ausführbare Datei"
description = "Pfad zu LibreOffice unoconvert für Dokumentkonvertierungen (leer lassen für Standard: /opt/venv/bin/unoconvert)"
[admin.settings.general.frontendUrl]
description = "Base URL for frontend (e.g., https://pdf.example.com). Used for email invite links and mobile QR code uploads. Leave empty to use backend URL."
label = "Frontend URL"
[admin.settings.security]
title = "Sicherheit"
description = "Authentifizierung, Anmeldeverhalten und Sicherheitsrichtlinien konfigurieren."
@@ -4562,19 +4321,6 @@ connect = "Verbinden"
disconnect = "Trennen"
disconnected = "Anbieter erfolgreich getrennt"
disconnectError = "Anbieter konnte nicht getrennt werden"
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
pageFormatA4 = "A4 (210×297mm)"
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatLetter = "Letter (8.5×11in)"
[admin.settings.connections.ssoAutoLogin]
label = "SSO-Autoanmeldung"
@@ -4643,26 +4389,6 @@ description = "Benutzerkonten bei der ersten SAML2-Anmeldung automatisch erstell
label = "Registrierung blockieren"
description = "Neue Benutzerregistrierung über SAML2 verhindern"
[admin.settings.connections.mobileScanner]
description = "Allow users to upload files from mobile devices by scanning a QR code"
enable = "Enable QR Code Upload"
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
label = "Mobile Phone Upload"
link = "Configure in System Settings"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
note = "Note: Requires Frontend URL to be configured. "
pageFormatA4 = "A4 (210×297mm)"
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatLetter = "Letter (8.5×11in)"
[admin.settings.database]
title = "Datenbank"
description = "Benutzerdefinierte Datenbankverbindungseinstellungen für Enterprise-Bereitstellungen konfigurieren."
@@ -4844,10 +4570,6 @@ description = "Admins erlauben, Benutzer per E-Mail mit automatisch generierten
label = "Frontend-URL"
description = "Basis-URL für das Frontend (z. B. https://pdf.example.com). Wird zum Erzeugen von Einladungslinks in E-Mails verwendet. Leer lassen, um Backend-URL zu verwenden."
[admin.settings.mail.frontendUrlNote]
link = "Configure in System Settings"
note = "Note: Requires Frontend URL to be configured. "
[admin.settings.legal]
title = "Rechtliche Dokumente"
description = "Links zu rechtlichen Dokumenten und Richtlinien konfigurieren."
@@ -4963,105 +4685,6 @@ description = "Einzelne zu deaktivierende Endpunkte auswählen"
label = "Deaktivierte Endpunktgruppen"
description = "Zu deaktivierende Endpunktgruppen auswählen"
[admin.settings.badge]
clickToUpgrade = "Click to view plan details"
[admin.settings.telegram]
description = "Configure Telegram bot connectivity, access controls, and feedback behavior."
title = "Telegram Bot"
[admin.settings.telegram.accessControl]
description = "Restrict which users or channels can interact with the bot."
title = "Access Control"
[admin.settings.telegram.allowChannelIDs]
description = "Enter Telegram channel IDs allowed to interact with the bot."
label = "Allowed Channel IDs"
placeholder = "Add channel ID and press enter"
[admin.settings.telegram.allowUserIDs]
description = "Enter Telegram user IDs allowed to interact with the bot."
label = "Allowed User IDs"
placeholder = "Add user ID and press enter"
[admin.settings.telegram.botToken]
description = "API token provided by BotFather for your Telegram bot."
label = "Bot Token"
[admin.settings.telegram.botUsername]
description = "The public username of your Telegram bot."
label = "Bot Username"
[admin.settings.telegram.customFolderSuffix]
description = "Append the chat ID to incoming file folders to isolate uploads per chat."
label = "Use Custom Folder Suffix"
[admin.settings.telegram.enableAllowChannelIDs]
description = "When enabled, only listed channel IDs can use the bot."
label = "Allow Specific Channel IDs"
[admin.settings.telegram.enableAllowUserIDs]
description = "When enabled, only listed user IDs can use the bot."
label = "Allow Specific User IDs"
[admin.settings.telegram.enabled]
description = "Allow users to interact with Stirling PDF through your configured Telegram bot."
label = "Enable Telegram Bot"
[admin.settings.telegram.feedback]
description = "Choose when the bot should send feedback to users and channels."
title = "Feedback Messages"
[admin.settings.telegram.feedback.channel]
title = "Channel Feedback Rules"
[admin.settings.telegram.feedback.channel.errorMessage]
description = "Show detailed error messages for channels."
label = "Show error messages (Channel)"
[admin.settings.telegram.feedback.channel.errorProcessing]
description = "Send processing error messages to channels."
label = "Show processing errors (Channel)"
[admin.settings.telegram.feedback.channel.noValidDocument]
description = "Suppress the no valid document response for channel uploads."
label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.general.enabled]
description = "Control whether the bot sends feedback messages at all."
label = "Enable Feedback"
[admin.settings.telegram.feedback.user]
title = "User Feedback Rules"
[admin.settings.telegram.feedback.user.errorMessage]
description = "Show detailed error messages for users."
label = "Show error messages (User)"
[admin.settings.telegram.feedback.user.errorProcessing]
description = "Send processing error messages to users."
label = "Show processing errors (User)"
[admin.settings.telegram.feedback.user.noValidDocument]
description = "Suppress the no valid document response for user uploads."
label = "Show \"No valid document\" (User)"
[admin.settings.telegram.pipelineInboxFolder]
description = "Folder under the pipeline directory where incoming Telegram files are stored."
label = "Inbox Folder"
[admin.settings.telegram.pollingIntervalMillis]
description = "Interval between checks for new Telegram updates."
label = "Polling Interval (ms)"
[admin.settings.telegram.processing]
description = "Control polling intervals and processing timeouts for Telegram uploads."
title = "Processing"
[admin.settings.telegram.processingTimeoutSeconds]
description = "Maximum time to wait for a processing job before reporting an error."
label = "Processing Timeout (seconds)"
[fileUpload]
selectFile = "Datei auswählen"
selectFiles = "Dateien auswählen"
@@ -5161,9 +4784,6 @@ showAll = "Alle anzeigen"
sortByDate = "Nach Datum sortieren"
sortByName = "Nach Name sortieren"
sortBySize = "Nach Größe sortieren"
mobileShort = "Mobile"
mobileUpload = "Mobile Upload"
mobileUploadNotAvailable = "Mobile upload not enabled"
[storage]
temporaryNotice = "Dateien werden temporär in Ihrem Browser gespeichert und können automatisch gelöscht werden"
@@ -5418,7 +5038,7 @@ securePdfIngestionDesc = "Umfassender PDF-Verarbeitungsworkflow, der Dokumente b
emailPreparation = "E-Mail-Vorbereitung"
emailPreparationDesc = "Optimiert PDFs für E-Mail-Verteilung durch Komprimierung von Dateien, Aufteilen großer Dokumente in 20MB-Blöcke für E-Mail-Kompatibilität und Entfernen von Metadaten für den Datenschutz."
secureWorkflow = "Sicherheits-Workflow"
secureWorkflowDesc = "Sichert PDF-Dokumente durch Entfernen potenziell schädlicher Inhalte wie JavaScript und eingebetteter Dateien und fügt anschließend Passwortschutz hinzu, um unbefugten Zugriff zu verhindern. Das Passwort ist standardmäßig auf password gesetzt."
secureWorkflowDesc = "Sichert PDF-Dokumente durch Entfernen potentiell schädlicher Inhalte wie JavaScript und eingebettete Dateien, dann fügt Passwortschutz hinzu, um unbefugten Zugriff zu verhindern. Passwort ist standardmäßig auf 'password' gesetzt."
processImages = "Bilder verarbeiten"
processImagesDesc = "Konvertiert mehrere Bilddateien in ein einzelnes PDF-Dokument und wendet dann OCR-Technologie an, um durchsuchbaren Text aus den Bildern zu extrahieren."
prePublishSanitization = "Bereinigung vor Veröffentlichung"
@@ -5449,7 +5069,6 @@ loading = "Laden..."
back = "Zurück"
continue = "Weiter"
error = "Fehler"
save = "Save"
[config.overview]
title = "Anwendungskonfiguration"
@@ -5512,15 +5131,6 @@ impact = "Alle Anwendungen oder Dienste, die derzeit diese Schlüssel verwenden,
confirmPrompt = "Sind Sie sicher, dass Sie fortfahren möchten?"
confirmCta = "Schlüssel aktualisieren"
[config.apiKeys.alert]
apiKeyErrorTitle = "API Key Error"
apiKeyRefreshed = "API Key Refreshed"
apiKeyRefreshedBody = "Your API key has been successfully refreshed."
failedToCreateApiKey = "Failed to create API key."
failedToFetchApiKey = "Failed to fetch API key."
failedToRefreshApiKey = "Failed to refresh API key."
failedToRetrieveApiKey = "Failed to retrieve API key from response."
[AddAttachmentsRequest]
attachments = "Anhänge auswählen"
info = "Wählen Sie Dateien aus, die Sie Ihrer PDF anhängen möchten. Diese Dateien werden eingebettet und über das Anhangs-Panel der PDF zugänglich sein."
@@ -5601,44 +5211,34 @@ noSearchResults = "Keine Tools gefunden"
noTools = "Keine Tools verfügbar"
[onboarding]
allTools = "Dies ist das Panel <strong>Alle Tools</strong>, in dem Sie alle verfügbaren PDF-Tools durchsuchen und auswählen können."
selectCropTool = "Wählen wir das Tool <strong>Zuschneiden</strong> aus, um zu zeigen, wie eines der Tools verwendet wird."
toolInterface = "Dies ist die Oberfläche des Tools <strong>Zuschneiden</strong>. Wie Sie sehen, ist hier noch nicht viel zu sehen, da wir noch keine PDF-Dateien hinzugefügt haben."
allTools = "This is the <strong>All Tools</strong> panel, where you can browse and select from all available PDF tools."
selectCropTool = "Wählen wir das Tool <strong>Crop</strong> aus, um zu zeigen, wie eines der Tools verwendet wird."
toolInterface = "Dies ist die Oberfläche des Tools <strong>Crop</strong>. Wie Sie sehen, ist hier noch nicht viel zu sehen, da wir noch keine PDF-Dateien hinzugefügt haben."
filesButton = "Mit der Schaltfläche <strong>Dateien</strong> in der Schnellzugriffsleiste können Sie PDFs hochladen, um die Tools darauf anzuwenden."
fileSources = "Sie können hier neue Dateien hochladen oder auf zuletzt verwendete Dateien zugreifen. Für die Tour verwenden wir eine Beispieldatei."
workbench = "Dies ist der <strong>Arbeitsbereich</strong> der Hauptbereich, in dem Sie Ihre PDFs ansehen und bearbeiten."
workbench = "Dies ist die <strong>Workbench</strong> der Hauptbereich, in dem Sie Ihre PDFs ansehen und bearbeiten."
viewSwitcher = "Verwenden Sie diese Steuerelemente, um auszuwählen, wie Sie Ihre PDFs ansehen möchten."
viewer = "Der <strong>Viewer</strong> ermöglicht es, Ihre PDFs zu lesen und zu annotieren."
pageEditor = "Der <strong>Seiteneditor</strong> ermöglicht verschiedene Aktionen an den Seiten Ihrer PDFs, wie Neuanordnen, Drehen und Löschen."
activeFiles = "Die Ansicht <strong>Aktive Dateien</strong> zeigt alle PDFs, die Sie im Tool geladen haben, und ermöglicht es Ihnen, auszuwählen, welche verarbeitet werden sollen."
pageEditor = "Der <strong>Page Editor</strong> ermöglicht verschiedene Aktionen an den Seiten Ihrer PDFs, wie Neuanordnen, Drehen und Löschen."
activeFiles = "Die Ansicht <strong>Active Files</strong> zeigt alle PDFs, die Sie im Tool geladen haben, und ermöglicht es Ihnen, auszuwählen, welche verarbeitet werden sollen."
fileCheckbox = "Durch Klicken auf eine der Dateien wählen Sie diese zur Verarbeitung aus. Sie können mehrere Dateien für Batch-Operationen auswählen."
selectControls = "Die <strong>rechte Leiste</strong> enthält Schaltflächen, um alle aktiven PDFs schnell zu (de-)selektieren, sowie Schaltflächen zum Ändern des App-Themas oder der Sprache."
cropSettings = "Nachdem wir die Datei ausgewählt haben, die wir zuschneiden möchten, können wir das Tool Zuschneiden konfigurieren, um den Bereich auszuwählen, auf den das PDF zugeschnitten werden soll."
selectControls = "Die <strong>Rechte Leiste</strong> enthält Schaltflächen, um alle aktiven PDFs schnell zu (de-)selektieren, sowie Schaltflächen zum Ändern des App-Themas oder der Sprache."
cropSettings = "Nachdem wir die Datei ausgewählt haben, die wir zuschneiden möchten, können wir das Tool Crop konfigurieren, um den Bereich auszuwählen, auf den das PDF zugeschnitten werden soll."
runButton = "Sobald das Tool konfiguriert ist, können Sie mit dieser Schaltfläche das Tool auf alle ausgewählten PDFs ausführen."
results = "Nachdem das Tool fertig ist, zeigt der Schritt <strong>Überprüfen</strong> in diesem Bereich eine Vorschau der Ergebnisse und ermöglicht es Ihnen, den Vorgang rückgängig zu machen oder die Datei herunterzuladen."
fileReplacement = "Die geänderte Datei ersetzt automatisch die Originaldatei im Arbeitsbereich, sodass Sie sie einfach mit weiteren Tools verarbeiten können."
pinButton = "Mit der Schaltfläche <strong>Anheften</strong> können Sie dafür sorgen, dass Ihre Dateien nach dem Ausführen von Tools aktiv bleiben."
wrapUp = "Alles fertig! Sie haben die Hauptbereiche der App und deren Verwendung kennengelernt. Klicken Sie jederzeit auf die Schaltfläche <strong>Hilfe</strong>, um diese Tour erneut zu sehen."
results = "Nachdem das Tool fertig ist, zeigt der Schritt <strong>Review</strong> in diesem Bereich eine Vorschau der Ergebnisse und ermöglicht es Ihnen, den Vorgang rückgängig zu machen oder die Datei herunterzuladen."
fileReplacement = "Die geänderte Datei ersetzt automatisch die Originaldatei in der Workbench, sodass Sie sie einfach mit weiteren Tools verarbeiten können."
pinButton = "Mit der Schaltfläche <strong>Pin</strong> können Sie dafür sorgen, dass Ihre Dateien nach dem Ausführen von Tools aktiv bleiben."
wrapUp = "Alles fertig! Sie haben die Hauptbereiche der App und deren Verwendung kennengelernt. Klicken Sie jederzeit auf die Schaltfläche <strong>Help</strong>, um diese Tour erneut zu sehen."
previous = "Zurück"
next = "Weiter"
finish = "Fertigstellen"
startTour = "Tour starten"
startTourDescription = "Geführte Tour zu den wichtigsten Funktionen von Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Starten Sie im Bereich <strong>Schnellzugriff</strong>, um zwischen Reader, Automate, Ihren Dateien und allen Touren zu wechseln."
leftPanel = "Die linke <strong>Tools</strong>-Leiste zeigt alles, was Sie tun können. Durchsuchen Sie Kategorien oder suchen Sie, um schnell ein Tool zu finden."
fileUpload = "Verwenden Sie die Schaltfläche <strong>Dateien</strong>, um eine PDF hochzuladen oder eine kürzlich verwendete auszuwählen. Wir laden ein Beispiel, damit Sie den Arbeitsbereich sehen können."
rightRail = "Die <strong>rechte Leiste</strong> enthält Schnellaktionen zum Auswählen von Dateien, Ändern des Designs oder der Sprache und zum Herunterladen von Ergebnissen."
topBar = "Die obere Leiste ermöglicht den Wechsel zwischen <strong>Viewer</strong>, <strong>Seiteneditor</strong> und <strong>Aktive Dateien</strong>."
pageEditorView = "Wechseln Sie zum Seiteneditor, um Seiten neu anzuordnen, zu drehen oder zu löschen."
activeFilesView = "Verwenden Sie „Aktive Dateien“, um alles Geöffnete zu sehen und auszuwählen, woran Sie arbeiten möchten."
wrapUp = "Das ist neu in V2. Öffnen Sie jederzeit das Menü <strong>Touren</strong>, um diese, die Tools-Tour oder die Admin-Tour erneut abzuspielen."
[onboarding.welcomeModal]
title = "Willkommen bei Stirling PDF!"
description = "Möchten Sie eine kurze 1MinutenTour machen, um die wichtigsten Funktionen kennenzulernen und zu erfahren, wie Sie loslegen?"
helpHint = "Sie können diese Tour jederzeit über die Schaltfläche <strong>Hilfe</strong> unten links aufrufen."
helpHint = "Sie können diese Tour jederzeit über die Schaltfläche <strong>Help</strong> unten links aufrufen."
startTour = "Tour starten"
maybeLater = "Vielleicht später"
dontShowAgain = "Nicht mehr anzeigen"
@@ -5651,14 +5251,10 @@ body = "Stirling PDF ist jetzt bereit für Teams jeder Größe. Dieses Update br
next = "Weiter →"
back = "Zurück"
skipForNow = "Für jetzt überspringen"
download = "Herunterladen →"
download = "Download →"
showMeAround = "Rundgang starten"
skipTheTour = "Rundgang überspringen"
[onboarding.tourOverview]
title = "Tour-Übersicht"
body = "Stirling PDF V2 wird mit Dutzenden Tools und einem aufgefrischten Layout ausgeliefert. Machen Sie eine kurze Tour, um zu sehen, was sich geändert hat und wo Sie die benötigten Funktionen finden."
[onboarding.serverLicense]
skip = "Für jetzt überspringen"
seePlans = "Pläne ansehen →"
@@ -5669,8 +5265,8 @@ overLimitBody = "Unsere Lizenz erlaubt bis zu <strong>{{freeTierLimit}}</strong>
freeBody = "Unsere <strong>Open-Core</strong>-Lizenz erlaubt bis zu <strong>{{freeTierLimit}}</strong> Nutzern pro Server kostenlos. Um unterbrechungsfrei zu skalieren, empfehlen wir den Stirling Server-Plan - <strong>unbegrenzte Plätze</strong> und <strong>SSO-Unterstützung</strong> für $99/Server/Monat."
[onboarding.desktopInstall]
title = "Herunterladen"
titleWithOs = "Herunterladen für {{osLabel}}"
title = "Download"
titleWithOs = "Download für {{osLabel}}"
body = "Stirling funktioniert am besten als Desktop-App. Sie können es offline nutzen, schneller auf Dokumente zugreifen und lokal auf Ihrem Computer bearbeiten."
[onboarding.planOverview]
@@ -5685,14 +5281,14 @@ message = "Die Anwendung hat kürzlich bedeutende Änderungen erfahren. Möglich
[adminOnboarding]
welcome = "Willkommen zur <strong>Admin-Tour</strong>! Entdecken wir die leistungsstarken Enterprise-Funktionen und Einstellungen für Systemadministratoren."
configButton = "Klicken Sie auf die Schaltfläche <strong>Konfiguration</strong>, um alle Systemeinstellungen und Administrationskontrollen aufzurufen."
configButton = "Klicken Sie auf die Schaltfläche <strong>Config</strong>, um alle Systemeinstellungen und Administrationskontrollen aufzurufen."
settingsOverview = "Dies ist das <strong>Einstellungsfeld</strong>. Admin-Einstellungen sind zur einfachen Navigation nach Kategorien organisiert."
teamsAndUsers = "Verwalten Sie hier <strong>Teams</strong> und einzelne Benutzer. Sie können neue Benutzer per E-Mail, teilbaren Links einladen oder selbst benutzerdefinierte Konten erstellen."
systemCustomization = "Wir bieten umfangreiche Möglichkeiten zur UI-Anpassung: <strong>Systemeinstellungen</strong> ermöglichen Änderungen am App-Namen und an Sprachen, <strong>Funktionen</strong> ermöglicht die Verwaltung von Serverzertifikaten und <strong>Endpunkte</strong> das Aktivieren oder Deaktivieren spezifischer Tools für Ihre Benutzer."
systemCustomization = "Wir bieten umfangreiche Möglichkeiten zur UI-Anpassung: <strong>System Settings</strong> ermöglichen Änderungen am App-Namen und an Sprachen, <strong>Features</strong> ermöglicht die Verwaltung von Serverzertifikaten und <strong>Endpoints</strong> das Aktivieren oder Deaktivieren spezifischer Tools für Ihre Benutzer."
databaseSection = "Für erweiterte Produktionsumgebungen gibt es Einstellungen für <strong>externe Datenbankanbindungen</strong>, damit Sie Ihre bestehende Infrastruktur integrieren können."
connectionsSection = "Der Bereich <strong>Verbindungen</strong> unterstützt verschiedene Anmeldemethoden, einschließlich benutzerdefiniertem SSO und SAML-Anbietern wie Google und GitHub, sowie E-Mail-Integrationen für Benachrichtigungen und Kommunikation."
adminTools = "Abschließend bieten wir erweiterte Administrationstools wie <strong>Audit-Protokollierung</strong> zur Nachverfolgung der Systemaktivität und <strong>Nutzungsanalysen</strong> zur Überwachung, wie Ihre Benutzer mit der Plattform interagieren."
wrapUp = "Das war die Admin-Tour! Sie haben die Enterprise-Funktionen gesehen, die Stirling PDF zu einer leistungsstarken, anpassbaren Lösung für Organisationen machen. Sie können diese Tour jederzeit über das <strong>Hilfe</strong>-Menü aufrufen."
connectionsSection = "Der Bereich <strong>Connections</strong> unterstützt verschiedene Anmeldemethoden, einschließlich benutzerdefiniertem SSO und SAML-Anbietern wie Google und GitHub, sowie E-Mail-Integrationen für Benachrichtigungen und Kommunikation."
adminTools = "Abschließend bieten wir erweiterte Administrationstools wie <strong>Auditing</strong> zur Nachverfolgung der Systemaktivität und <strong>Nutzungsanalysen</strong> zur Überwachung, wie Ihre Benutzer mit der Plattform interagieren."
wrapUp = "Das war die Admin-Tour! Sie haben die Enterprise-Funktionen gesehen, die Stirling PDF zu einer leistungsstarken, anpassbaren Lösung für Organisationen machen. Sie können diese Tour jederzeit über das <strong>Help</strong>-Menü aufrufen."
[workspace]
title = "Arbeitsbereich"
@@ -5972,28 +5568,6 @@ contactSales = "Vertrieb kontaktieren"
contactToUpgrade = "Kontaktieren Sie uns, um Ihren Plan zu upgraden oder anzupassen"
maxUsers = "Max. Benutzer"
upTo = "Bis zu"
getLicense = "Server-Lizenz erhalten"
upgradeToEnterprise = "Auf Enterprise upgraden"
selectPeriod = "Abrechnungszeitraum auswählen"
monthlyBilling = "Monatliche Abrechnung"
yearlyBilling = "Jährliche Abrechnung"
checkoutOpened = "Checkout geöffnet"
checkoutInstructions = "Schließen Sie Ihren Kauf im Stripe-Tab ab. Kehren Sie danach hierher zurück und aktualisieren Sie die Seite, um Ihre Lizenz zu aktivieren. Sie erhalten außerdem eine E-Mail mit Ihrem Lizenzschlüssel."
activateLicense = "Lizenz aktivieren"
[plan.static.licenseActivation]
checkoutOpened = "Checkout in neuem Tab geöffnet"
instructions = "Schließen Sie den Kauf im Stripe-Tab ab. Nach Abschluss der Zahlung erhalten Sie eine E-Mail mit Ihrem Lizenzschlüssel."
enterKey = "Geben Sie unten Ihren Lizenzschlüssel ein, um Ihren Plan zu aktivieren:"
keyDescription = "Fügen Sie den Lizenzschlüssel aus Ihrer E-Mail ein"
activate = "Lizenz aktivieren"
doLater = "Ich mache das später"
success = "Lizenz aktiviert!"
successMessage = "Ihre Lizenz wurde erfolgreich aktiviert. Sie können dieses Fenster nun schließen."
[plan.static.billingPortal]
title = "E-Mail-Verifizierung erforderlich"
message = "Sie müssen Ihre E-Mail-Adresse im Stripe-Abrechnungsportal verifizieren. Prüfen Sie Ihre E-Mails auf einen Login-Link."
[plan.period]
month = "Monat"
@@ -6122,7 +5696,7 @@ emailInvalid = "Bitte geben Sie eine gültige E-Mail-Adresse ein"
title = "E-Mail eingeben"
description = "Wir verwenden diese, um Ihren Lizenzschlüssel und Belege zu senden."
emailLabel = "E-Mail-Adresse"
emailPlaceholder = "ihre@email.com"
emailPlaceholder = "your@email.com"
continue = "Weiter"
modalTitle = "Loslegen {{planName}}"
@@ -6197,8 +5771,6 @@ notAvailable = "Audit-System nicht verfügbar"
notAvailableMessage = "Das Audit-System ist nicht konfiguriert oder nicht verfügbar."
disabled = "Audit-Protokollierung ist deaktiviert"
disabledMessage = "Aktivieren Sie die Audit-Protokollierung in Ihrer Anwendungskonfiguration, um Systemereignisse nachzuverfolgen."
enterpriseRequired = "Enterprise-Lizenz erforderlich"
enterpriseRequiredMessage = "Das Audit-Protokollierungssystem ist eine Enterprise-Funktion. Bitte upgraden Sie auf eine Enterprise-Lizenz, um Audit-Logs und Analysen zu nutzen."
[audit.error]
title = "Fehler beim Laden des Audit-Systems"
@@ -6373,7 +5945,6 @@ emptyUrl = "Bitte eine Server-URL eingeben"
unreachable = "Verbindung zum Server konnte nicht hergestellt werden"
testFailed = "Verbindungstest fehlgeschlagen"
configFetch = "Serverkonfiguration konnte nicht abgerufen werden. Bitte überprüfen Sie die URL und versuchen Sie es erneut."
invalidUrl = "Invalid URL format. Please enter a valid URL like https://your-server.com"
[setup.server.error.securityDisabled]
title = "Anmeldung nicht aktiviert"
@@ -6397,7 +5968,6 @@ instructions = "So aktivieren Sie die Anmeldung auf Ihrem Stirling PDF-Server:"
instructionsEnvVar = "Setzen Sie die Umgebungsvariable:"
instructionsOrYml = "Oder in der settings.yml:"
instructionsRestart = "Starten Sie anschließend Ihren Server neu, damit die Änderungen wirksam werden."
sso = "Single Sign-On"
[setup.login.username]
label = "Benutzername"
@@ -6455,8 +6025,6 @@ reset = "Änderungen zurücksetzen"
downloadJson = "JSON herunterladen"
generatePdf = "PDF generieren"
saveChanges = "Änderungen speichern"
applyChanges = "Änderungen anwenden"
downloadCopy = "Kopie herunterladen"
[pdfTextEditor.options.autoScaleText]
title = "Text automatisch in Rahmen einpassen"
@@ -6475,24 +6043,6 @@ descriptionInline = "Tipp: Halten Sie Strg (Cmd) oder Umschalt, um mehrere Textf
title = "Bearbeiteten Text auf ein einzelnes PDF-Element fixieren"
description = "Wenn aktiviert, exportiert der Editor jedes bearbeitete Textfeld als ein PDF-Textelement, um überlappende Glyphen oder gemischte Schriften zu vermeiden."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Vorschau-Einschränkungen"
[pdfTextEditor.tooltip.textFocus]
title = "Fokus auf Text und Bilder"
text = "Dieser Arbeitsbereich konzentriert sich auf das Bearbeiten von Text und das Neupositionieren eingebetteter Bilder. Komplexe Seitengrafiken, Formular-Widgets und Ebenengrafiken bleiben für den Export erhalten, sind hier jedoch nicht vollständig bearbeitbar."
[pdfTextEditor.tooltip.previewVariance]
title = "Abweichungen in der Vorschau"
text = "Einige Darstellungen (z. B. Tabellenränder, Formen oder das Erscheinungsbild von Anmerkungen) werden in der Vorschau möglicherweise nicht exakt angezeigt. Die exportierte PDF behält die ursprünglichen Zeichenbefehle nach Möglichkeit bei."
[pdfTextEditor.tooltip.alpha]
title = "Alpha-Viewer"
text = "Dieser Alpha-Viewer wird noch weiterentwickelt bestimmte Schriftarten, Farben, Transparenzeffekte und Layoutdetails können leicht abweichen. Bitte prüfen Sie die erzeugte PDF vor dem Teilen."
[pdfTextEditor.manual]
mergeTooltip = "Ausgewählte Felder zusammenführen"
merge = "Auswahl zusammenführen"
@@ -6614,58 +6164,3 @@ title = "Ergebnisse: Text hinzufügen"
[addText.error]
failed = "Beim Hinzufügen von Text zum PDF ist ein Fehler aufgetreten."
[mobileScanner]
addToBatch = "Add to Batch"
back = "Back"
batchImages = "Batch"
camera = "Camera"
cameraAccessDenied = "Camera access denied. Please enable camera access."
cameraDescription = "Scan documents using your device camera with automatic edge detection"
capture = "Capture Photo"
chooseMethod = "Choose Upload Method"
chooseMethodDescription = "Select how you want to scan and upload documents"
clearBatch = "Clear"
connected = "Connected"
connecting = "Connecting..."
edgeDetection = "Edge Detection"
fileDescription = "Upload existing photos or documents from your device"
fileUpload = "File Upload"
flash = "Flash"
flashlight = "Flashlight"
httpsRequired = "Camera access requires HTTPS or localhost. Please use HTTPS or access via localhost."
noSession = "Invalid Session"
noSessionMessage = "Please scan a valid QR code to access this page."
preview = "Preview"
processing = "Processing..."
retake = "Retake"
selectFilesPrompt = "Select files to upload"
selectImage = "Select Image"
sessionExpired = "This session has expired. Please refresh and try again."
sessionInvalid = "Session Error"
sessionNotFound = "Session not found. Please refresh and try again."
sessionValidationError = "Unable to verify session. Please try again."
settings = "Settings"
title = "Mobile Scanner"
upload = "Upload"
uploadAll = "Upload All"
uploadFailed = "Upload failed. Please try again."
uploadSuccess = "Upload Successful!"
uploadSuccessMessage = "Your images have been transferred."
uploading = "Uploading..."
validating = "Validating session..."
[mobileUpload]
connected = "Mobile device connected"
description = "Scan to upload photos. Images auto-convert to PDF."
descriptionNoConvert = "Scan to upload photos from your mobile device."
error = "Connection Error"
expiryWarning = "Session Expiring Soon"
expiryWarningMessage = "This QR code will expire in {{seconds}} seconds. A new code will be generated automatically."
filesReceived = "{{count}} file(s) received"
instructions = "Scan with your phone camera. Images convert to PDF automatically."
instructionsNoConvert = "Scan with your phone camera to upload files."
pollingError = "Error checking for files"
sessionCreateError = "Failed to create session"
sessionId = "Session ID"
title = "Upload from Mobile"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Προχωρημένα"
edit = "Προβολή & Επεξεργασία"
popular = "Δημοφιλή"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Προτιμήσεις"
@@ -439,25 +435,6 @@ latestVersion = "Νεότερη έκδοση"
checkForUpdates = "Έλεγχος για ενημερώσεις"
viewDetails = "Προβολή λεπτομερειών"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Συντομεύσεις πληκτρολογίου"
description = "Προσαρμόστε τις συντομεύσεις για γρήγορη πρόσβαση στα εργαλεία. Κάντε κλικ στο \"Αλλαγή συντόμευσης\" και πατήστε νέο συνδυασμό. Πατήστε Esc για ακύρωση."
@@ -511,16 +488,11 @@ low = "Χαμηλή"
title = "Αλλαγή διαπιστευτηρίων"
header = "Ενημέρωση στοιχείων λογαριασμού"
changePassword = "Χρησιμοποιείτε προεπιλεγμένα διαπιστευτήρια σύνδεσης. Παρακαλώ εισάγετε νέο κωδικό"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Νέο όνομα χρήστη"
oldPassword = "Τρέχων κωδικός"
newPassword = "Νέος κωδικός"
confirmNewPassword = "Επιβεβαίωση νέου κωδικού"
submit = "Υποβολή αλλαγών"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Ρυθμίσεις λογαριασμού"
@@ -736,11 +708,6 @@ tags = "υπογραφή,αυτόγραφο"
title = "Υπογραφή"
desc = "Προσθήκη υπογραφής σε PDF με σχεδίαση, κείμενο ή εικόνα"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "απλοποίηση,αφαίρεση,διαδραστικό"
title = "Ισοπέδωση"
@@ -1278,21 +1245,6 @@ cbzOptions = "Επιλογές CBZ σε PDF"
optimizeForEbook = "Βελτιστοποίηση PDF για συσκευές ανάγνωσης ebook (χρησιμοποιεί Ghostscript)"
cbzOutputOptions = "Επιλογές PDF σε CBZ"
cbzDpi = "DPI για απόδοση εικόνας"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "μετατροπή,εικόνα,jpg,φωτογραφία"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Προσθήκη συνημμένου"
remove = "Αφαίρεση συνημμένου"
embed = "Ενσωμάτωση συνημμένου"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Αποθηκευμένες"
label = "Μεταφορτώστε εικόνα υπογραφής"
placeholder = "Επιλέξτε αρχείο εικόνας"
hint = "Μεταφορτώστε εικόνα PNG ή JPG της υπογραφής σας"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Πώς να προσθέσετε υπογραφή"
@@ -2408,11 +2351,6 @@ note = "Η επιπέδωση αφαιρεί διαδραστικά στοιχε
label = "Ισοπέδωση μόνο φορμών"
desc = "Επιπέδωση μόνο πεδίων φόρμας, αφήνοντας τα υπόλοιπα διαδραστικά στοιχεία ανέπαφα"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Αποτελέσματα επιπέδωσης"
@@ -2987,7 +2925,6 @@ header = "Περικοπή PDF"
submit = "Υποβολή"
noFileSelected = "Επιλέξτε ένα αρχείο PDF για να ξεκινήσετε την περικοπή"
reset = "Επαναφορά σε πλήρες PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Επιλογή περιοχής περικοπής"
@@ -3405,19 +3342,6 @@ placeholder = "Εισάγετε αριθμό οριζόντιων διαιρέσ
label = "Κάθετες διαιρέσεις"
placeholder = "Εισάγετε αριθμό κάθετων διαιρέσεων"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "σφραγίδα,προσθήκη εικόνας,κεντράρισμα εικόνας,υδατογράφημα,PDF,ενσωμάτωση,προσαρμογή"
header = "Σφράγισμα PDF"
@@ -3779,19 +3703,6 @@ filesize = "Μέγεθος αρχείου"
[compress.grayscale]
label = "Εφαρμογή κλίμακας του γκρι για συμπίεση"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Επισκόπηση ρυθμίσεων συμπίεσης"
@@ -3809,10 +3720,6 @@ bullet2 = "Οι υψηλές τιμές μειώνουν το μέγεθος α
title = "Κλίμακα του γκρι"
text = "Επιλέξτε αυτήν την επιλογή για να μετατρέψετε όλες τις εικόνες σε ασπρόμαυρες, κάτι που μπορεί να μειώσει σημαντικά το μέγεθος αρχείου ειδικά για σαρωμένα PDF ή έγγραφα με πολλές εικόνες."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Παρουσιάστηκε σφάλμα κατά τη συμπίεση του PDF."
@@ -3825,11 +3732,6 @@ failed = "Παρουσιάστηκε σφάλμα κατά τη συμπίεση
_value = "Ρυθμίσεις συμπίεσης"
1 = "1-3 συμπίεση PDF,</br> 4-6 ελαφριά συμπίεση εικόνας,</br> 7-9 έντονη συμπίεση εικόνας Θα μειώσει δραστικά την ποιότητα εικόνας"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Αυτό το αρχείο προστατεύεται με κωδικό πρόσβασης. Παρακαλώ εισάγετε τον κωδικό:"
cancelled = "Η λειτουργία ακυρώθηκε για το PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Διαγραφή επιλεγμένων σελίδων"
closePdf = "Κλείσιμο PDF"
exportAll = "Εξαγωγή PDF"
downloadSelected = "Λήψη επιλεγμένων αρχείων"
annotations = "Annotations"
exportSelected = "Εξαγωγή επιλεγμένων σελίδων"
saveChanges = "Αποθήκευση αλλαγών"
downloadAll = "Λήψη όλων"
saveAll = "Αποθήκευση όλων"
toggleTheme = "Εναλλαγή θέματος"
toggleBookmarks = "Εναλλαγή σελιδοδεικτών"
language = "Γλώσσα"
toggleAnnotations = "Εναλλαγή ορατότητας σχολιασμών"
search = "Αναζήτηση PDF"
panMode = "Λειτουργία μετακίνησης"
rotateLeft = "Περιστροφή αριστερά"
rotateRight = "Περιστροφή δεξιά"
toggleSidebar = "Εναλλαγή πλευρικής γραμμής"
toggleBookmarks = "Εναλλαγή σελιδοδεικτών"
exportSelected = "Εξαγωγή επιλεγμένων σελίδων"
toggleAnnotations = "Εναλλαγή ορατότητας σχολιασμών"
annotationMode = "Εναλλαγή λειτουργίας σχολιασμού"
print = "Εκτύπωση PDF"
downloadAll = "Λήψη όλων"
saveAll = "Αποθήκευση όλων"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Σχεδίαση"
save = "Αποθήκευση"
saveChanges = "Αποθήκευση αλλαγών"
[search]
title = "Αναζήτηση στο PDF"
@@ -4205,20 +4038,12 @@ settings = "Ρυθμ."
adminSettings = "Ρυθμ. διαχ."
allTools = "All Tools"
reader = "Ανάγνωση"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Ξενάγηση στα εργαλεία"
toolsTourDesc = "Μάθετε τι μπορούν να κάνουν τα εργαλεία"
adminTour = "Ξενάγηση διαχειριστή"
adminTourDesc = "Εξερευνήστε τις ρυθμίσεις και τις δυνατότητες διαχειριστή"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Σφάλμα"
@@ -5244,7 +5069,6 @@ loading = "Φόρτωση..."
back = "Πίσω"
continue = "Συνέχεια"
error = "Σφάλμα"
save = "Save"
[config.overview]
title = "Ρυθμίσεις εφαρμογής"
@@ -5411,16 +5235,6 @@ finish = "Τέλος"
startTour = "Έναρξη περιήγησης"
startTourDescription = "Κάντε μια καθοδηγούμενη περιήγηση στα βασικά χαρακτηριστικά του Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Καλώς ήρθατε στο Stirling PDF!"
description = "Θέλετε να κάνετε μια γρήγορη περιήγηση 1 λεπτού για να μάθετε τα βασικά χαρακτηριστικά και πώς να ξεκινήσετε;"
@@ -5441,10 +5255,6 @@ download = "Λήψη →"
showMeAround = "Ξεναγήστε με"
skipTheTour = "Παράλειψη ξενάγησης"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Παράλειψη προς το παρόν"
seePlans = "Δείτε τα πλάνα →"
@@ -5758,28 +5568,6 @@ contactSales = "Επικοινωνία με Πωλήσεις"
contactToUpgrade = "Επικοινωνήστε μαζί μας για αναβάθμιση ή προσαρμογή του πλάνου σας"
maxUsers = "Μέγιστοι χρήστες"
upTo = "Έως"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "μήνα"
@@ -5983,8 +5771,6 @@ notAvailable = "Το σύστημα ελέγχου δεν είναι διαθέ
notAvailableMessage = "Το σύστημα ελέγχου δεν έχει ρυθμιστεί ή δεν είναι διαθέσιμο."
disabled = "Η καταγραφή ελέγχου είναι απενεργοποιημένη"
disabledMessage = "Ενεργοποιήστε την καταγραφή ελέγχου στις ρυθμίσεις της εφαρμογής για παρακολούθηση συμβάντων συστήματος."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Σφάλμα φόρτωσης συστήματος ελέγχου"
@@ -6239,8 +6025,6 @@ reset = "Επαναφορά αλλαγών"
downloadJson = "Λήψη JSON"
generatePdf = "Δημιουργία PDF"
saveChanges = "Αποθήκευση αλλαγών"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Αυτόματη προσαρμογή κειμένου στα πλαίσια"
@@ -6259,24 +6043,6 @@ descriptionInline = "Συμβουλή: Κρατήστε πατημένο το Ct
title = "Κλείδωμα επεξεργασμένου κειμένου σε ένα μόνο στοιχείο PDF"
description = "Όταν είναι ενεργό, ο επεξεργαστής εξάγει κάθε επεξεργασμένο πλαίσιο κειμένου ως ένα στοιχείο κειμένου PDF για να αποφύγει επικαλυπτόμενους γλύφους ή ανάμεικτες γραμματοσειρές."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Συγχώνευση επιλεγμένων πλαισίων"
merge = "Συγχώνευση επιλογής"
+2 -147
View File
@@ -367,7 +367,6 @@ advanced = "Advanced"
title = "Security & Authentication"
security = "Security"
connections = "Connections"
telegram = "Telegram"
[settings.licensingAnalytics]
title = "Licensing & Analytics"
@@ -442,13 +441,6 @@ currentVersion = "Current Version"
latestVersion = "Latest Version"
checkForUpdates = "Check for Updates"
viewDetails = "View Details"
serverNeedsUpdate = "Server needs to be updated by administrator"
[settings.general.versionInfo]
title = "Version Information"
description = "Desktop and server version details"
desktop = "Desktop Version"
server = "Server Version"
[settings.security]
title = "Security"
@@ -1308,18 +1300,6 @@ includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[convert.epubOptions]
epubOptions = "PDF to eBook Options"
epubOptionsDesc = "Options for converting PDF to EPUB/AZW3"
detectChapters = "Detect chapters"
detectChaptersDesc = "Detect headings that look like chapters and insert EPUB page breaks"
targetDevice = "Target device"
targetDeviceDesc = "Choose an output profile optimized for the reader device"
outputFormat = "Output format"
outputFormatDesc = "Choose the output format for the ebook"
tabletPhone = "Tablet/Phone (with images)"
kindleEink = "Kindle e-Ink (text optimized)"
[imageToPdf]
tags = "conversion,img,jpg,picture,photo"
@@ -4297,8 +4277,6 @@ fetchError = "Failed to load settings"
saveError = "Failed to save settings"
saved = "Settings saved successfully"
saveSuccess = "Settings saved successfully"
success = "Settings saved successfully"
error = "Failed to save settings"
save = "Save Changes"
discard = "Discard"
restartRequired = "Restart Required"
@@ -4565,19 +4543,6 @@ connect = "Connect"
disconnect = "Disconnect"
disconnected = "Provider disconnected successfully"
disconnectError = "Failed to disconnect provider"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatA4 = "A4 (210×297mm)"
pageFormatLetter = "Letter (8.5×11in)"
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
[admin.settings.connections.ssoAutoLogin]
label = "SSO Auto Login"
@@ -4646,109 +4611,12 @@ description = "Automatically create user accounts on first SAML2 login"
label = "Block Registration"
description = "Prevent new user registration via SAML2"
[admin.settings.telegram]
title = "Telegram Bot"
description = "Configure Telegram bot connectivity, access controls, and feedback behavior."
[admin.settings.telegram.enabled]
label = "Enable Telegram Bot"
description = "Allow users to interact with Stirling PDF through your configured Telegram bot."
[admin.settings.telegram.botUsername]
label = "Bot Username"
description = "The public username of your Telegram bot."
[admin.settings.telegram.botToken]
label = "Bot Token"
description = "API token provided by BotFather for your Telegram bot."
[admin.settings.telegram.pipelineInboxFolder]
label = "Inbox Folder"
description = "Folder under the pipeline directory where incoming Telegram files are stored."
[admin.settings.telegram.customFolderSuffix]
label = "Use Custom Folder Suffix"
description = "Append the chat ID to incoming file folders to isolate uploads per chat."
[admin.settings.telegram.accessControl]
title = "Access Control"
description = "Restrict which users or channels can interact with the bot."
[admin.settings.telegram.enableAllowUserIDs]
label = "Allow Specific User IDs"
description = "When enabled, only listed user IDs can use the bot."
[admin.settings.telegram.allowUserIDs]
label = "Allowed User IDs"
description = "Enter Telegram user IDs allowed to interact with the bot."
placeholder = "Add user ID and press enter"
[admin.settings.telegram.enableAllowChannelIDs]
label = "Allow Specific Channel IDs"
description = "When enabled, only listed channel IDs can use the bot."
[admin.settings.telegram.allowChannelIDs]
label = "Allowed Channel IDs"
description = "Enter Telegram channel IDs allowed to interact with the bot."
placeholder = "Add channel ID and press enter"
[admin.settings.telegram.processing]
title = "Processing"
description = "Control polling intervals and processing timeouts for Telegram uploads."
[admin.settings.telegram.processingTimeoutSeconds]
label = "Processing Timeout (seconds)"
description = "Maximum time to wait for a processing job before reporting an error."
[admin.settings.telegram.pollingIntervalMillis]
label = "Polling Interval (ms)"
description = "Interval between checks for new Telegram updates."
[admin.settings.telegram.feedback]
title = "Feedback Messages"
description = "Choose when the bot should send feedback to users and channels."
[admin.settings.telegram.feedback.general.enabled]
label = "Enable Feedback"
description = "Control whether the bot sends feedback messages at all."
[admin.settings.telegram.feedback.channel]
title = "Channel Feedback Rules"
noValidDocument.label = "Show \"No valid document\" (Channel)"
noValidDocument.description = "Suppress the no valid document response for channel uploads."
errorProcessing.label = "Show processing errors (Channel)"
errorProcessing.description = "Send processing error messages to channels."
errorMessage.label = "Show error messages (Channel)"
errorMessage.description = "Show detailed error messages for channels."
[admin.settings.telegram.feedback.user]
title = "User Feedback Rules"
noValidDocument.label = "Show \"No valid document\" (User)"
noValidDocument.description = "Suppress the no valid document response for user uploads."
errorProcessing.label = "Show processing errors (User)"
errorProcessing.description = "Send processing error messages to users."
errorMessage.label = "Show error messages (User)"
errorMessage.description = "Show detailed error messages for users."
[admin.settings.connections.mobileScanner]
label = "Mobile Phone Upload"
enable = "Enable QR Code Upload"
description = "Allow users to upload files from mobile devices by scanning a QR code"
note = "Note: Requires Frontend URL to be configured. "
link = "Configure in System Settings"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatA4 = "A4 (210×297mm)"
pageFormatLetter = "Letter (8.5×11in)"
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
[admin.settings.database]
title = "Database"
@@ -5122,7 +4990,6 @@ noRecentFiles = "No recent files found"
googleDriveNotAvailable = "Google Drive integration not available"
mobileUpload = "Mobile Upload"
mobileShort = "Mobile"
mobileUploadNotAvailable = "Mobile upload not enabled"
downloadSelected = "Download Selected"
saveSelected = "Save Selected"
openFiles = "Open Files"
@@ -5501,15 +5368,6 @@ impact = "Any applications or services currently using these keys will stop work
confirmPrompt = "Are you sure you want to continue?"
confirmCta = "Refresh Keys"
[config.apiKeys.alert]
apiKeyErrorTitle = "API Key Error"
failedToCreateApiKey = "Failed to create API key."
failedToRetrieveApiKey = "Failed to retrieve API key from response."
failedToFetchApiKey = "Failed to fetch API key."
apiKeyRefreshed = "API Key Refreshed"
apiKeyRefreshedBody = "Your API key has been successfully refreshed."
failedToRefreshApiKey = "Failed to refresh API key."
[AddAttachmentsRequest]
attachments = "Select Attachments"
info = "Select files to attach to your PDF. These files will be embedded and accessible through the PDF's attachment panel."
@@ -6359,7 +6217,6 @@ description = "Enter the full URL of your self-hosted Stirling PDF server"
[setup.server.error]
emptyUrl = "Please enter a server URL"
invalidUrl = "Invalid URL format. Please enter a valid URL like https://your-server.com"
unreachable = "Could not connect to server"
testFailed = "Connection test failed"
configFetch = "Failed to fetch server configuration. Please check the URL and try again."
@@ -6606,8 +6463,7 @@ failed = "An error occurred while adding text to the PDF."
[mobileUpload]
title = "Upload from Mobile"
description = "Scan to upload photos. Images auto-convert to PDF."
descriptionNoConvert = "Scan to upload photos from your mobile device."
description = "Scan this QR code with your mobile device to upload photos directly to this page."
error = "Connection Error"
pollingError = "Error checking for files"
sessionId = "Session ID"
@@ -6616,8 +6472,7 @@ expiryWarning = "Session Expiring Soon"
expiryWarningMessage = "This QR code will expire in {{seconds}} seconds. A new code will be generated automatically."
filesReceived = "{{count}} file(s) received"
connected = "Mobile device connected"
instructions = "Scan with your phone camera. Images convert to PDF automatically."
instructionsNoConvert = "Scan with your phone camera to upload files."
instructions = "Open the camera app on your phone and scan this code. Files will be transferred directly between devices."
[mobileScanner]
title = "Mobile Scanner"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avanzado"
edit = "Ver y Editar"
popular = "Populares"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferencias"
@@ -439,25 +435,6 @@ latestVersion = "Última versión"
checkForUpdates = "Buscar actualizaciones"
viewDetails = "Ver detalles"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Atajos de teclado"
description = "Personaliza los atajos de teclado para acceder rápido a las herramientas. Haz clic en \"Cambiar atajo\" y pulsa una nueva combinación de teclas. Pulsa Esc para cancelar."
@@ -511,16 +488,11 @@ low = "Baja"
title = "Cambiar Credenciales"
header = "Actualice los detalles de su cuenta"
changePassword = "Está usando las credenciales de inicio de sesión por defecto. Por favor, introduzca una contraseña nueva"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nuevo usuario"
oldPassword = "Contraseña actual"
newPassword = "Nueva contraseña"
confirmNewPassword = "Confirme la nueva contraseña"
submit = "Enviar cambios"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Configuración de la cuenta"
@@ -736,11 +708,6 @@ tags = "firma,autógrafo"
title = "Firmar"
desc = "Añadir firma a PDF mediante dibujo, texto o imagen"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplificar,eliminar,interactivo"
title = "Eliminar interactividad"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opciones de CBZ a PDF"
optimizeForEbook = "Optimizar PDF para lectores de libros electrónicos (usa Ghostscript)"
cbzOutputOptions = "Opciones de PDF a CBZ"
cbzDpi = "DPI para renderizado de imágenes"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversión,img,jpg,imagen,fotografía"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Añadir archivo adjunto"
remove = "Eliminar archivo adjunto"
embed = "Incrustar archivo adjunto"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Guardadas"
label = "Cargar imagen de firma"
placeholder = "Seleccionar archivo de imagen"
hint = "Cargue una imagen PNG o JPG de su firma"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Cómo añadir firma"
@@ -2408,11 +2351,6 @@ note = "Aplanar elimina elementos interactivos del PDF, haciéndolos no editable
label = "Aplanar solo formularios"
desc = "Solo aplanar campos de formulario, dejando intactos otros elementos interactivos"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultados de Aplanado"
@@ -2987,7 +2925,6 @@ header = "Recortar PDF"
submit = "Entregar"
noFileSelected = "Seleccione un archivo PDF para comenzar a recortar"
reset = "Restablecer a PDF completo"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Selección de Área de Recorte"
@@ -3405,19 +3342,6 @@ placeholder = "Introduzca el número de divisiones horizontales"
label = "Divisiones Verticales"
placeholder = "Introduzca el número de divisiones verticales"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Sello, Añadir imagen, centrar imagen, Marca de agua, PDF, Incrustar, Personalizar"
header = "Sellar PDF"
@@ -3779,19 +3703,6 @@ filesize = "Tamaño de archivo"
[compress.grayscale]
label = "Aplicar escala de grises para compresión"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Resumen de Configuración de Compresión"
@@ -3809,10 +3720,6 @@ bullet2 = "Los valores más altos reducen el tamaño del archivo"
title = "Escala de Grises"
text = "Seleccione esta opción para convertir todas las imágenes a blanco y negro, lo que puede reducir significativamente el tamaño del archivo, especialmente para PDFs escaneados o documentos con muchas imágenes."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Ocurrió un error al comprimir el PDF."
@@ -3825,11 +3732,6 @@ failed = "Ocurrió un error al comprimir el PDF."
_value = "Configuración de Compresión"
1 = "1-3 compresión PDF,</br> 4-6 compresión de imagen suave,</br> 7-9 compresión de imágenes intensa reducirá drásticamente la calidad de imagen"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Este archivo está protegido con contraseña. Por favor, introduzca la contraseña:"
cancelled = "Operación cancelada para el PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Eliminar Páginas Seleccionadas"
closePdf = "Cerrar PDF"
exportAll = "Exportar PDF"
downloadSelected = "Descargar Archivos Seleccionados"
annotations = "Annotations"
exportSelected = "Exportar páginas seleccionadas"
saveChanges = "Guardar cambios"
downloadAll = "Descargar Todo"
saveAll = "Guardar todo"
toggleTheme = "Alternar Tema"
toggleBookmarks = "Mostrar/ocultar marcadores"
language = "Idioma"
toggleAnnotations = "Mostrar/ocultar anotaciones"
search = "Buscar en PDF"
panMode = "Modo de Desplazamiento"
rotateLeft = "Rotar a la Izquierda"
rotateRight = "Rotar a la Derecha"
toggleSidebar = "Alternar Barra Lateral"
toggleBookmarks = "Mostrar/ocultar marcadores"
exportSelected = "Exportar páginas seleccionadas"
toggleAnnotations = "Mostrar/ocultar anotaciones"
annotationMode = "Cambiar modo de anotaciones"
print = "Imprimir PDF"
downloadAll = "Descargar Todo"
saveAll = "Guardar todo"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Dibujar"
save = "Guardar"
saveChanges = "Guardar cambios"
[search]
title = "Buscar PDF"
@@ -4205,20 +4038,12 @@ settings = "Ajustes"
adminSettings = "Ajustes admin"
allTools = "Herram."
reader = "Lector"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Recorrido por las herramientas"
toolsTourDesc = "Descubre lo que pueden hacer las herramientas"
adminTour = "Recorrido de administración"
adminTourDesc = "Explora la configuración y las funciones de administración"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Error"
@@ -5244,7 +5069,6 @@ loading = "Cargando..."
back = "Atrás"
continue = "Continuar"
error = "Error"
save = "Save"
[config.overview]
title = "Configuración de la aplicación"
@@ -5411,16 +5235,6 @@ finish = "Finalizar"
startTour = "Iniciar recorrido"
startTourDescription = "Realiza un recorrido guiado por las funciones clave de Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "¡Bienvenido a Stirling PDF!"
description = "¿Te gustaría hacer un recorrido rápido de 1 minuto para conocer las funciones clave y cómo empezar?"
@@ -5441,10 +5255,6 @@ download = "Descargar →"
showMeAround = "Muéstreme el recorrido"
skipTheTour = "Saltar el recorrido"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Omitir por ahora"
seePlans = "Ver planes →"
@@ -5758,28 +5568,6 @@ contactSales = "Contactar con ventas"
contactToUpgrade = "Contacta con nosotros para actualizar o personalizar tu plan"
maxUsers = "Máximo de usuarios"
upTo = "Hasta"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mes"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistema de auditoría no disponible"
notAvailableMessage = "El sistema de auditoría no está configurado o no está disponible."
disabled = "El registro de auditoría está desactivado"
disabledMessage = "Habilita el registro de auditoría en la configuración de tu aplicación para rastrear eventos del sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Error al cargar el sistema de auditoría"
@@ -6239,8 +6025,6 @@ reset = "Restablecer cambios"
downloadJson = "Descargar JSON"
generatePdf = "Generar PDF"
saveChanges = "Guardar cambios"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Escalar texto automáticamente para ajustar a las cajas"
@@ -6259,24 +6043,6 @@ descriptionInline = "Consejo: mantenga pulsado Ctrl (Cmd) o Shift para seleccion
title = "Bloquear el texto editado a un único elemento PDF"
description = "Cuando está activado, el editor exporta cada cuadro de texto editado como un único elemento de texto PDF para evitar solapamientos de glifos o fuentes mezcladas."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Combinar cuadros seleccionados"
merge = "Combinar selección"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Aurreratua"
edit = "Ikusi eta editatu"
popular = "Ezagunak"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Hobespenak"
@@ -439,25 +435,6 @@ latestVersion = "Azken bertsioa"
checkForUpdates = "Egiaztatu eguneratzeak"
viewDetails = "Xehetasunak ikusi"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Laster-teklak"
description = "Pertsonalizatu laster-teklak tresnetara azkar sartzeko. Egin klik \"Laster-tekla aldatu\" eta sakatu tekla-konbinazio berria. Sakatu Esc ezeztatzeko."
@@ -511,16 +488,11 @@ low = "Baxua"
title = "Aldatu kredentzialak"
header = "Eguneratu zure kontuaren xehetasunak"
changePassword = "Saioa hasteko kredentzial lehenetsiak erabiltzen ari zara. Mesedez, sartu pasahitz berria"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Erabiltzaile izen berria"
oldPassword = "Uneko pasahitza"
newPassword = "Pasahitz berria"
confirmNewPassword = "Konfirmatu pasahitz berria"
submit = "Bidali aldaketak"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Kontuaren ezarpenak"
@@ -736,11 +708,6 @@ tags = "sinadura,autografoa"
title = "Sinatu"
desc = "Gehitu sinadura PDFari marrazki, testu edo irudi bidez"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "sinplifikatu,kendu,interaktiboa"
title = "Lautu"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZtik PDFra aukerak"
optimizeForEbook = "Optimizatu PDF e-book irakurgailuetarako (Ghostscript erabiltzen du)"
cbzOutputOptions = "PDFtik CBZra aukerak"
cbzDpi = "Irudien errendatzeko DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversion,img,jpg,picture,photo,psd,photoshop"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Gehitu eranskina"
remove = "Kendu eranskina"
embed = "Txertatu eranskina"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Gordeta"
label = "Igo sinaduraren irudia"
placeholder = "Hautatu irudi-fitxategia"
hint = "Igo zure sinaduraren PNG edo JPG irudia"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Nola gehitu sinadura"
@@ -2408,11 +2351,6 @@ note = "Lautzeak PDFko elementu interaktiboak kentzen ditu, eta ezin editagarri
label = "Lautu bakarrik inprimakiak"
desc = "Lautu soilik inprimaki-eremuak, beste elementu interaktiboak ukitu gabe utzita"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Lautze-emaitzak"
@@ -2987,7 +2925,6 @@ header = "Moztu PDF"
submit = "Bidali"
noFileSelected = "Hautatu PDF fitxategi bat mozten hasteko"
reset = "Berrezarri PDF osoa"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Mozketa-arearen hautapena"
@@ -3405,19 +3342,6 @@ placeholder = "Sartu zatiketa horizontal kopurua"
label = "Zatiketa bertikalak"
placeholder = "Sartu zatiketa bertikal kopurua"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stamp, Add image, center image, Watermark, PDF, Embed, Customize"
header = "Zigilatu PDFa"
@@ -3779,19 +3703,6 @@ filesize = "Fitxategiaren tamaina"
[compress.grayscale]
label = "Aplikatu grisezko eskala konpresiorako"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Konpresio ezarpenen ikuspegi orokorra"
@@ -3809,10 +3720,6 @@ bullet2 = "Balio altuek fitxategi-tamaina murrizten dute"
title = "Gris-eskala"
text = "Aukeratu aukera hau irudi guztiak zuri-beltzera bihurtzeko; asko murriztu dezake fitxategiaren tamaina, bereziki eskaneatutako PDFetan edo irudi askoko dokumentuetan."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Errore bat gertatu da PDFa konprimatzean."
@@ -3825,11 +3732,6 @@ failed = "Errore bat gertatu da PDFa konprimatzean."
_value = "Konpresio ezarpenak"
1 = "1-3 PDF konpresioa,</br> 4-6 irudi-konpresio arina,</br> 7-9 irudi-konpresio bizia Irudien kalitatea nabarmen murriztuko du"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Fitxategi hau pasahitzarekin babestuta dago. Idatzi pasahitza:"
cancelled = "Eragiketa bertan behera utzi da PDFarentzat: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Ezabatu hautatutako orriak"
closePdf = "Itxi PDFa"
exportAll = "Esportatu PDFa"
downloadSelected = "Deskargatu hautatutako fitxategiak"
annotations = "Annotations"
exportSelected = "Esportatu hautatutako orriak"
saveChanges = "Aldaketak gorde"
downloadAll = "Deskargatu dena"
saveAll = "Gorde dena"
toggleTheme = "Gaia txandakatu"
toggleBookmarks = "Laster-markak txandakatu"
language = "Hizkuntza"
toggleAnnotations = "Oharpenen ikusgarritasuna txandakatu"
search = "Bilatu PDF"
panMode = "Pan modua"
rotateLeft = "Biratu ezkerrera"
rotateRight = "Biratu eskuinera"
toggleSidebar = "Alboko barra txandakatu"
toggleBookmarks = "Laster-markak txandakatu"
exportSelected = "Esportatu hautatutako orriak"
toggleAnnotations = "Oharpenen ikusgarritasuna txandakatu"
annotationMode = "Oharpen modua txandakatu"
print = "Inprimatu PDFa"
downloadAll = "Deskargatu dena"
saveAll = "Gorde dena"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Marraztu"
save = "Gorde"
saveChanges = "Aldaketak gorde"
[search]
title = "Bilatu PDF"
@@ -4205,20 +4038,12 @@ settings = "Aukerak"
adminSettings = "Admin aukerak"
allTools = "All Tools"
reader = "Irakurri"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Tresnen ibilaldia"
toolsTourDesc = "Ikasi tresnek zer egin dezaketen"
adminTour = "Administrazio ibilaldia"
adminTourDesc = "Arakatu admin ezarpenak eta ezaugarriak"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Errorea"
@@ -5244,7 +5069,6 @@ loading = "Kargatzen..."
back = "Atzera"
continue = "Jarraitu"
error = "Errorea"
save = "Save"
[config.overview]
title = "Aplikazioaren konfigurazioa"
@@ -5411,16 +5235,6 @@ finish = "Amaitu"
startTour = "Hasi bira"
startTourDescription = "Stirling PDFren ezaugarri nagusien gida-bira"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Ongi etorri Stirling PDFra!"
description = "1 minutuko bisita azkar bat egin nahi duzu funtsezko ezaugarriak eta nola hasi ikasteko?"
@@ -5441,10 +5255,6 @@ download = "Deskargatu →"
showMeAround = "Erakutsi ingurunea"
skipTheTour = "Utzi bisita gidatua"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Utzi oraingoz"
seePlans = "Ikusi planak →"
@@ -5758,28 +5568,6 @@ contactSales = "Jarri salmentekin harremanetan"
contactToUpgrade = "Jarri gurekin harremanetan zure plana bertsio-berritzeko edo pertsonalizatzeko"
maxUsers = "Erabiltzaile kopuru maximoa"
upTo = "Gehienez"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "hilabete"
@@ -5983,8 +5771,6 @@ notAvailable = "Auditoretza-sistema ez dago eskuragarri"
notAvailableMessage = "Auditoretza-sistema ez dago konfiguratuta edo ez dago eskuragarri."
disabled = "Auditoretza-erregistroa desgaituta dago"
disabledMessage = "Gaitu auditoretza-erregistroa zure aplikazioaren konfigurazioan sistemaren gertaerak jarraitzeko."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Errorea auditoretza-sistema kargatzean"
@@ -6239,8 +6025,6 @@ reset = "Aldaketak berrezarri"
downloadJson = "JSON deskargatu"
generatePdf = "PDF sortu"
saveChanges = "Gorde aldaketak"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Testua automatikoki eskalatu kutxetara egokitzeko"
@@ -6259,24 +6043,6 @@ descriptionInline = "Aholkua: Eutsi sakatuta Ctrl (Cmd) edo Shift testu-kutxa an
title = "Editatutako testua PDF elementu bakarrera lotu"
description = "Gaituta dagoenean, editoreak editatutako testu-kutxa bakoitza PDFko testu-elementu bakar gisa esportatzen du, glifoen gainjartzeak edo letra-tipo nahasiak saihesteko."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Hautatutako kutxak batu"
merge = "Hautapena batu"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "پیشرفته"
edit = "مشاهده و ویرایش"
popular = "محبوب"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "ترجیحات"
@@ -439,25 +435,6 @@ latestVersion = "آخرین نسخه"
checkForUpdates = "بررسی به‌روزرسانی"
viewDetails = "مشاهده جزئیات"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "میانبرهای صفحه‌کلید"
description = "می‌توانید میانبرهای صفحه‌کلید را برای دسترسی سریع به ابزارها سفارشی کنید. روی «تغییر میانبر» کلیک کنید و ترکیب کلید جدید را فشار دهید. برای لغو، Esc را بزنید."
@@ -511,16 +488,11 @@ low = "کم"
title = "تغییر مشخصات"
header = "به‌روزرسانی جزئیات حساب کاربری"
changePassword = "شما از مشخصات پیش‌فرض ورود استفاده می‌کنید. لطفاً یک رمز عبور جدید وارد کنید"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "نام کاربری جدید"
oldPassword = "رمز عبور فعلی"
newPassword = "رمز عبور جدید"
confirmNewPassword = "تأیید رمز عبور جدید"
submit = "ثبت تغییرات"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "تنظیمات حساب"
@@ -736,11 +708,6 @@ tags = "امضا,دستخط"
title = "امضا"
desc = "افزودن امضا به PDF با کشیدن، متن یا تصویر"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "ساده‌سازی,حذف,تعامل"
title = "تسطیح"
@@ -1278,21 +1245,6 @@ cbzOptions = "گزینه‌های CBZ به PDF"
optimizeForEbook = "بهینه‌سازی PDF برای کتاب‌خوان‌ها (از Ghostscript استفاده می‌کند)"
cbzOutputOptions = "گزینه‌های PDF به CBZ"
cbzDpi = "DPI برای رندر تصویر"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "تبدیل،عکس،jpg،تصویر،عکس"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "افزودن پیوست"
remove = "حذف پیوست"
embed = "جاسازی پیوست"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "ذخیره‌شده"
label = "بارگذاری تصویر امضا"
placeholder = "انتخاب فایل تصویر"
hint = "یک تصویر PNG یا JPG از امضای خود بارگذاری کنید"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "چگونه امضا اضافه کنیم"
@@ -2408,11 +2351,6 @@ note = "تخت‌سازی عناصر تعاملی را از PDF حذف می‌ک
label = "فقط فرم‌ها را یکپارچه کن"
desc = "فقط فیلدهای فرم را تخت‌سازی کن و سایر عناصر تعاملی را دست‌نخورده بگذار"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "نتایج تخت‌سازی"
@@ -2987,7 +2925,6 @@ header = "برش PDF"
submit = "ارسال"
noFileSelected = "برای شروع برش یک فایل PDF انتخاب کنید"
reset = "بازنشانی به کل PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "انتخاب ناحیه برش"
@@ -3405,19 +3342,6 @@ placeholder = "تعداد تقسیمات افقی را وارد کنید"
label = "تقسیمات عمودی"
placeholder = "تعداد تقسیمات عمودی را وارد کنید"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "مهر، افزودن تصویر، واترمارک، PDF، سفارشی‌سازی"
header = "مهر زدن به PDF"
@@ -3779,19 +3703,6 @@ filesize = "اندازه فایل"
[compress.grayscale]
label = "اعمال مقیاس خاکستری برای فشرده‌سازی"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "مرور تنظیمات فشرده‌سازی"
@@ -3809,10 +3720,6 @@ bullet2 = "مقادیر بالا اندازه فایل را کاهش می‌ده
title = "سیاه‌وسفید"
text = "با انتخاب این گزینه تمام تصاویر به سیاه‌وسفید تبدیل می‌شوند که می‌تواند به‌طور قابل‌توجهی اندازه فایل را کاهش دهد، مخصوصاً برای PDFهای اسکن‌شده یا اسناد پر از تصویر."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "هنگام فشرده‌سازی PDF خطایی رخ داد."
@@ -3825,11 +3732,6 @@ failed = "هنگام فشرده‌سازی PDF خطایی رخ داد."
_value = "تنظیمات فشرده‌سازی"
1 = "1-3 فشرده‌سازی PDF،</br> 4-6 فشرده‌سازی سبک تصویر،</br> 7-9 فشرده‌سازی شدید تصویر باعث کاهش چشمگیر کیفیت تصویر می‌شود"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "این فایل با گذرواژه محافظت شده است. لطفاً گذرواژه را وارد کنید:"
cancelled = "عملیات برای PDF لغو شد: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "حذف صفحات انتخاب‌شده"
closePdf = "بستن PDF"
exportAll = "برون‌بری PDF"
downloadSelected = "دانلود فایل‌های انتخاب‌شده"
annotations = "Annotations"
exportSelected = "برون‌بری صفحات انتخاب‌شده"
saveChanges = "ذخیره تغییرات"
downloadAll = "دانلود همه"
saveAll = "ذخیره همه"
toggleTheme = "تغییر تم"
toggleBookmarks = "نمایش/پنهان‌کردن نشانک‌ها"
language = "زبان"
toggleAnnotations = "تغییر وضعیت نمایش حاشیه‌نویسی‌ها"
search = "جستجوی PDF"
panMode = "حالت پیمایش"
rotateLeft = "چرخش به چپ"
rotateRight = "چرخش به راست"
toggleSidebar = "تغییر وضعیت نوار کناری"
toggleBookmarks = "نمایش/پنهان‌کردن نشانک‌ها"
exportSelected = "برون‌بری صفحات انتخاب‌شده"
toggleAnnotations = "تغییر وضعیت نمایش حاشیه‌نویسی‌ها"
annotationMode = "تغییر حالت حاشیه‌نویسی"
print = "چاپ PDF"
downloadAll = "دانلود همه"
saveAll = "ذخیره همه"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "رسم"
save = "ذخیره"
saveChanges = "ذخیره تغییرات"
[search]
title = "جستجوی PDF"
@@ -4205,20 +4038,12 @@ settings = "تنظیمات"
adminSettings = "تنظیمات مدیر"
allTools = "All Tools"
reader = "نمایشگر"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "تور ابزارها"
toolsTourDesc = "با قابلیت‌های ابزارها آشنا شوید"
adminTour = "تور مدیریت"
adminTourDesc = "تنظیمات و قابلیت‌های مدیریت را بررسی کنید"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "خطا"
@@ -5244,7 +5069,6 @@ loading = "در حال بارگذاری..."
back = "بازگشت"
continue = "ادامه"
error = "خطا"
save = "Save"
[config.overview]
title = "پیکربندی برنامه"
@@ -5411,16 +5235,6 @@ finish = "پایان"
startTour = "شروع تور"
startTourDescription = "یک تور راهنما از قابلیت‌های کلیدی Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "به Stirling PDF خوش آمدید!"
description = "مایلید یک تور سریع ۱ دقیقه‌ای بگیرید تا با قابلیت‌های کلیدی و نحوه شروع آشنا شوید؟"
@@ -5441,10 +5255,6 @@ download = "دانلود →"
showMeAround = "راهنمایی کن"
skipTheTour = "از تور بگذر"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "فعلاً رد کن"
seePlans = "مشاهده پلن‌ها →"
@@ -5758,28 +5568,6 @@ contactSales = "تماس با فروش"
contactToUpgrade = "برای ارتقا یا سفارشی‌سازی طرح خود با ما تماس بگیرید"
maxUsers = "حداکثر کاربران"
upTo = "تا"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "ماه"
@@ -5983,8 +5771,6 @@ notAvailable = "سیستم ممیزی در دسترس نیست"
notAvailableMessage = "سیستم ممیزی پیکربندی نشده یا در دسترس نیست."
disabled = "ثبت وقایع ممیزی غیرفعال است"
disabledMessage = "برای پیگیری رویدادهای سیستم، ثبت ممیزی را در پیکربندی برنامه خود فعال کنید."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "خطا در بارگذاری سیستم ممیزی"
@@ -6239,8 +6025,6 @@ reset = "بازنشانی تغییرات"
downloadJson = "دانلود JSON"
generatePdf = "تولید PDF"
saveChanges = "ذخیرهٔ تغییرات"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "مقیاس خودکار متن برای جا شدن در باکس‌ها"
@@ -6259,24 +6043,6 @@ descriptionInline = "نکته: برای انتخاب چندگانه باکس‌
title = "قفل‌کردن متن ویرایش‌شده به یک عنصر PDF واحد"
description = "وقتی فعال باشد، هر باکس متن ویرایش‌شده را به‌صورت یک عنصر متن PDF خروجی می‌گیرد تا از هم‌پوشانی گلیف‌ها یا فونت‌های ترکیبی جلوگیری شود."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "ادغام باکس‌های انتخاب‌شده"
merge = "ادغام انتخاب"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Mode avancé"
edit = "Voir et modifier"
popular = "Populaire"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Préférences"
@@ -439,25 +435,6 @@ latestVersion = "Dernière version"
checkForUpdates = "Rechercher des mises à jour"
viewDetails = "Voir les détails"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Raccourcis clavier"
description = "Personnalisez les raccourcis clavier pour un accès rapide aux outils. Cliquez sur \"Modifier le raccourci\" et pressez une nouvelle combinaison de touches. Appuyez sur Échap pour annuler."
@@ -511,16 +488,11 @@ low = "Faible"
title = "Modifiez vos identifiants"
header = "Mettez à jour vos identifiants de connexion"
changePassword = "Vous utilisez les identifiants de connexion par défaut. Veuillez saisir un nouveau mot de passe"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nouveau nom d'utilisateur"
oldPassword = "Mot de passe actuel"
newPassword = "Nouveau mot de passe"
confirmNewPassword = "Confirmer le nouveau mot de passe"
submit = "Soumettre les modifications"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Paramètres du compte"
@@ -736,11 +708,6 @@ tags = "signature,autographe"
title = "Signer"
desc = "Ajoutez une signature au PDF avec un dessin, du texte ou une image."
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplifier,retirer,interactif"
title = "Rendre inerte"
@@ -1278,21 +1245,6 @@ cbzOptions = "Options CBZ vers PDF"
optimizeForEbook = "Optimiser le PDF pour les liseuses (utilise Ghostscript)"
cbzOutputOptions = "Options PDF vers CBZ"
cbzDpi = "DPI pour le rendu des images"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "pdf,conversion,img,jpg,image,photo"
@@ -1409,11 +1361,6 @@ header = "Ajouter des pièces jointes"
add = "Ajouter une pièce jointe"
remove = "Supprimer la pièce jointe"
embed = "Intégrer la pièce jointe"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Ajouter des pièces jointes"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Enregistrées"
label = "Téléverser une image de signature"
placeholder = "Sélectionner un fichier image"
hint = "Téléversez une image PNG ou JPG de votre signature"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Comment ajouter une signature"
@@ -2408,11 +2351,6 @@ note = "Laplatissement supprime les éléments interactifs du PDF, les rendan
label = "Aplatir uniquement les formulaires"
desc = "Aplatir uniquement les champs de formulaire, en laissant les autres éléments interactifs intacts"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Résultats de laplatissement"
@@ -2987,7 +2925,6 @@ header = "Redimensionner"
submit = "Envoyer"
noFileSelected = "Sélectionnez un fichier PDF pour commencer le recadrage"
reset = "Réinitialiser au PDF complet"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Sélection de la zone de recadrage"
@@ -3405,19 +3342,6 @@ placeholder = "Saisir le nombre de divisions horizontales"
label = "Divisions verticales"
placeholder = "Entrer le nombre de divisions verticales"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Tampon,Ajouter,Stamp,Add image,center image,Watermark,PDF,Embed,Customize"
header = "Tampon PDF"
@@ -3779,19 +3703,6 @@ filesize = "Taille du Fichier"
[compress.grayscale]
label = "Appliquer l'échelle de gris pour la compression"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Aperçu des paramètres de compression"
@@ -3809,10 +3720,6 @@ bullet2 = "Des valeurs élevées réduisent la taille du fichier"
title = "Niveaux de gris"
text = "Sélectionnez cette option pour convertir toutes les images en noir et blanc, ce qui peut réduire significativement la taille, en particulier pour les PDF scannés ou riches en images."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Une erreur est survenue lors de la compression du PDF."
@@ -3825,11 +3732,6 @@ failed = "Une erreur est survenue lors de la compression du PDF."
_value = "Paramètres de compression"
1 = "1-3 compression PDF,</br> 4-6 compression d'image légère,</br> 7-9 compression d'image intense qui réduira considérablement la qualité de l'image"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ce fichier est protégé par un mot de passe. Veuillez saisir le mot de passe :"
cancelled = "Operation annulée pour le PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Supprimer les pages sélectionnées"
closePdf = "Fermer le PDF"
exportAll = "Exporter le PDF"
downloadSelected = "Télécharger les fichiers sélectionnés"
annotations = "Annotations"
exportSelected = "Exporter les pages sélectionnées"
saveChanges = "Enregistrer les modifications"
downloadAll = "Tout télécharger"
saveAll = "Tout enregistrer"
toggleTheme = "Changer de thème"
toggleBookmarks = "Afficher/Masquer les signets"
language = "Langue"
toggleAnnotations = "Afficher/masquer les annotations"
search = "Rechercher dans le PDF"
panMode = "Mode panoramique"
rotateLeft = "Pivoter à gauche"
rotateRight = "Pivoter à droite"
toggleSidebar = "Afficher/masquer la barre latérale"
toggleBookmarks = "Afficher/Masquer les signets"
exportSelected = "Exporter les pages sélectionnées"
toggleAnnotations = "Afficher/masquer les annotations"
annotationMode = "Basculer en mode annotation"
print = "Imprimer le PDF"
downloadAll = "Tout télécharger"
saveAll = "Tout enregistrer"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Dessiner"
save = "Enregistrer"
saveChanges = "Enregistrer les modifications"
[search]
title = "Rechercher dans le PDF"
@@ -4205,20 +4038,12 @@ settings = "Réglages"
adminSettings = "Réglages admin"
allTools = "Outils"
reader = "Lecteur"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Visite des outils"
toolsTourDesc = "Découvrez ce que les outils peuvent faire"
adminTour = "Visite administrateur"
adminTourDesc = "Découvrez les paramètres et fonctionnalités dadministration"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Erreur"
@@ -5244,7 +5069,6 @@ loading = "Chargement…"
back = "Retour"
continue = "Continuer"
error = "Erreur"
save = "Save"
[config.overview]
title = "Configuration de lapplication"
@@ -5411,16 +5235,6 @@ finish = "Terminer"
startTour = "Commencer la visite"
startTourDescription = "Suivez une visite guidée des fonctionnalités clés de Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Bienvenue dans Stirling PDF !"
description = "Souhaitez-vous suivre une visite guidée dune minute pour découvrir les fonctionnalités clés et comment démarrer ?"
@@ -5441,10 +5255,6 @@ download = "Télécharger →"
showMeAround = "Faites-moi faire le tour"
skipTheTour = "Passer la visite"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Passer pour linstant"
seePlans = "Voir les offres →"
@@ -5758,28 +5568,6 @@ contactSales = "Contacter l’équipe commerciale"
contactToUpgrade = "Contactez-nous pour mettre à niveau ou personnaliser votre forfait"
maxUsers = "Nombre maximal dutilisateurs"
upTo = "Jusqu’à"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mois"
@@ -5983,8 +5771,6 @@ notAvailable = "Système daudit non disponible"
notAvailableMessage = "Le système daudit nest pas configuré ou nest pas disponible."
disabled = "La journalisation daudit est désactivée"
disabledMessage = "Activez la journalisation daudit dans la configuration de votre application pour suivre les événements du système."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Erreur lors du chargement du système daudit"
@@ -6239,8 +6025,6 @@ reset = "Réinitialiser les modifications"
downloadJson = "Télécharger le JSON"
generatePdf = "Générer le PDF"
saveChanges = "Enregistrer les modifications"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Ajuster automatiquement le texte aux cadres"
@@ -6259,24 +6043,6 @@ descriptionInline = "Astuce : Maintenez Ctrl (Cmd) ou Shift pour sélectionner p
title = "Verrouiller le texte modifié à un seul élément PDF"
description = "Lorsqu'il est activé, l'éditeur exporte chaque boîte de texte modifiée comme un seul élément de texte PDF afin d'éviter le chevauchement de glyphes ou les polices mixtes."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Fusionner les boîtes sélectionnées"
merge = "Fusionner la sélection"
+9 -514
View File
@@ -128,9 +128,6 @@ undoQuotaError = "Ní féidir a chealú: níl dóthain spáis stórála ann"
undoStorageError = "Críochnaíodh an cealú ach níorbh fhéidir roinnt comhad a shábháil sa stóras"
undoSuccess = "Cealaíodh an oibríocht go rathúil"
unsupported = "Ní thacaítear leis"
discardRedactions = "Discard & Leave"
pendingRedactions = "You have unapplied redactions that will be lost."
pendingRedactionsTitle = "Unapplied Redactions"
[toolPanel]
placeholder = "Roghnaigh uirlis chun tosú"
@@ -343,10 +340,6 @@ advance = "Casta"
edit = "Féach ar & Cuir in Eagar"
popular = "Coitianta"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Sainroghanna"
@@ -367,7 +360,6 @@ advanced = "Ardroghanna"
title = "Slándáil agus Fíordheimhniú"
security = "Slándáil"
connections = "Naisc"
telegram = "Telegram"
[settings.licensingAnalytics]
title = "Ceadúnú agus Anailísíocht"
@@ -442,32 +434,6 @@ currentVersion = "Leagan Reatha"
latestVersion = "Leagan is Déanaí"
checkForUpdates = "Seiceáil le haghaidh Nuashonruithe"
viewDetails = "Féach Sonraí"
serverNeedsUpdate = "Server needs to be updated by administrator"
[settings.general.versionInfo]
description = "Desktop and server version details"
desktop = "Desktop Version"
server = "Server Version"
title = "Version Information"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Aicearraí Méarchláir"
@@ -522,16 +488,11 @@ low = "Íseal"
title = "Athraigh Dintiúir"
header = "Nuashonraigh Sonraí do Chuntais"
changePassword = "Tá dintiúir réamhshocraithe logáil isteach á úsáid agat. Cuir isteach pasfhocal nua le do thoil"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Ainm Úsáideora Nua"
oldPassword = "Pasfhocal reatha"
newPassword = "Focal Faire Nua"
confirmNewPassword = "Deimhnigh Pasfhocal Nua"
submit = "Cuir Athruithe isteach"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Socruithe cuntas"
@@ -553,8 +514,6 @@ property = "Maoin"
webBrowserSettings = "Socrú Brabhsálaí Gréasáin"
syncToBrowser = "Cuntas Sync -> Brabhsálaí"
syncToAccount = "Cuntas Sioncronaigh <- Brabhsálaí"
changeUsernameDescription = "Update your username. You will be logged out after updating."
newUsernamePlaceholder = "Enter your new username"
[adminUserSettings]
title = "Socruithe Rialaithe Úsáideora"
@@ -749,11 +708,6 @@ tags = "síniú,uathshíniú"
title = "Comhartha"
desc = "Cuireann síniú le PDF trí líníocht, téacs nó íomhá"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simpligh,bain,idirghníomhach"
title = "Comhcheangail"
@@ -976,7 +930,6 @@ desc = "Cuir téacs saincheaptha in áit ar bith i do PDF"
addFiles = "Cuir Comhaid Leis"
uploadFromComputer = "Uaslódáil ón ríomhaire"
openFromComputer = "Oscail ón ríomhaire"
mobileUpload = "Upload from Mobile"
[viewPdf]
tags = "amharc, léamh, anótáil, téacs, íomhá"
@@ -1292,33 +1245,6 @@ cbzOptions = "Roghanna CBZ go PDF"
optimizeForEbook = "Optamaigh PDF do léitheoirí ríomhleabhar (úsáideann Ghostscript)"
cbzOutputOptions = "Roghanna PDF go CBZ"
cbzDpi = "DPI do rindreáil íomhá"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[convert.epubOptions]
detectChapters = "Detect chapters"
detectChaptersDesc = "Detect headings that look like chapters and insert EPUB page breaks"
epubOptions = "PDF to eBook Options"
epubOptionsDesc = "Options for converting PDF to EPUB/AZW3"
kindleEink = "Kindle e-Ink (text optimized)"
outputFormat = "Output format"
outputFormatDesc = "Choose the output format for the ebook"
tabletPhone = "Tablet/Phone (with images)"
targetDevice = "Target device"
targetDeviceDesc = "Choose an output profile optimized for the reader device"
[imageToPdf]
tags = "comhshó, img, jpg, pictiúr, grianghraf"
@@ -1435,11 +1361,6 @@ header = "Add attachments"
add = "Cuir Iatán Leis"
remove = "Bain Iatán"
embed = "Leabaigh Iatán"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2385,10 +2306,6 @@ saved = "Sábháilte"
label = "Uaslódáil íomhá sínithe"
placeholder = "Roghnaigh comhad íomhá"
hint = "Uaslódáil íomhá PNG nó JPG de do shíniú"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Conas síniú a chur leis"
@@ -2434,11 +2351,6 @@ note = "Baineann maolú eilimintí idirghníomhacha ón PDF, rud a fhágann nach
label = "Flatten foirmeacha amháin"
desc = "Maolaigh réimsí foirme amháin, fág eilimintí idirghníomhacha eile slán"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Torthaí Maolaithe"
@@ -3013,7 +2925,6 @@ header = "PDF a ghearradh"
submit = "Cuir isteach"
noFileSelected = "Roghnaigh comhad PDF chun tosú ar bhearradh"
reset = "Athshocraigh go PDF iomlán"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Roghnú Limistéir Bhearrtha"
@@ -3247,7 +3158,6 @@ automaticDesc = "Ceil téacs bunaithe ar théarmaí cuardaigh"
manual = "Láimhe"
manualDesc = "Cliceáil agus tarraing chun limistéir shonracha a cheilt"
manualComingSoon = "Ceilt láimhe ag teacht go luath"
automaticDisabledTooltip = "Select files in the file manager to redact multiple files at once"
[redact.auto]
header = "Ceilt Uathoibríoch"
@@ -3315,24 +3225,6 @@ text = "Ní mheaitseálfar ach focail iomlána, ní meaitseálacha páirteacha.
title = "Tiontaigh go PDF-Image"
text = "Tiontaíonn sé an PDF go PDF bunaithe ar íomhá tar éis ceilte. Cinntíonn sé seo go mbaintear téacs taobh thiar de bhoscaí ceilte go hiomlán agus nach féidir é a ghnóthú."
[redact.tooltip.manual.apply]
bullet1 = "Mark as many areas as needed before applying"
bullet2 = "All pending redactions are applied at once"
bullet3 = "Redactions cannot be undone after applying"
text = "After marking content, click 'Apply' to permanently redact all marked areas. The pending count shows how many redactions are ready to be applied."
title = "Apply Redactions"
[redact.tooltip.manual.header]
title = "Manual Redaction Controls"
[redact.tooltip.manual.markArea]
text = "Draw rectangular areas on the PDF to mark regions for redaction. Useful for redacting images, signatures, or irregular shapes."
title = "Mark Area Tool"
[redact.tooltip.manual.markText]
text = "Select text directly on the PDF to mark it for redaction. Click and drag to highlight specific text that you want to redact."
title = "Mark Text Tool"
[redact.manual]
header = "Ceilt Láimhe"
textBasedRedaction = "Ceilt bunaithe ar théacs"
@@ -3354,15 +3246,6 @@ showLayers = "Taispeáin Sraitheanna (déchliceáil chun gach sraith a athshocr
colourPicker = "Roghnóir Datha"
findCurrentOutlineItem = "Aimsigh mír reatha na himlíne"
applyChanges = "Cuir Athruithe i bhFeidhm"
apply = "Apply"
applyWarning = "⚠️ Permanent application, cannot be undone and the data underneath will be deleted"
controlsTitle = "Manual Redaction Controls"
instructions = "Select text or draw areas on the PDF to mark content for redaction."
markArea = "Mark Area"
markText = "Mark Text"
noMarks = "No redaction marks. Use the tools above to mark content for redaction."
pendingLabel = "Pending:"
title = "Redaction Tools"
[redact.manual.pageRedactionNumbers]
title = "Leathanaigh"
@@ -3459,19 +3342,6 @@ placeholder = "Cuir isteach líon na rannán cothrománach"
label = "Rannáin Ingearach"
placeholder = "Cuir isteach líon na rannáin ingearacha"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stampa, Cuir íomhá, íomhá lár, Uisce, PDF, Leabú, Saincheap"
header = "Stampa PDF"
@@ -3833,19 +3703,6 @@ filesize = "Méid an Chomhaid"
[compress.grayscale]
label = "Cuir Scála Liath i bhFeidhm le Comhbhrú"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Forbhreathnú ar Shocruithe Comhbhrúite"
@@ -3863,10 +3720,6 @@ bullet2 = "Laghdaíonn luachanna níos airde an méid comhaid"
title = "Liathscála"
text = "Roghnaigh an rogha seo chun gach íomhá a thiontú go dubh agus bán, rud a d'fhéadfadh méid an chomhaid a laghdú go mór, go háirithe do PDFanna scanta nó do dhoiciméid lán d’íomhánna."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Tharla earráid agus an PDF á chomhbhrú."
@@ -3879,11 +3732,6 @@ failed = "Tharla earráid agus an PDF á chomhbhrú."
_value = "Socruithe Comhbhrúite"
1 = "1-3 comhbhrú PDF,</br> 4-6 comhbhrú éadrom íomhá,</br> 7-9 comhbhrú dian íomhá Laghdóidh sé cáilíocht na n-íomhánna go mór"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Tá an comhad seo cosanta ag pasfhocal. Cuir isteach an pasfhocal le do thoil:"
cancelled = "Cealaíodh an oibríocht le haghaidh PDF: {0}"
@@ -4123,98 +3971,23 @@ deleteSelected = "Scrios na Leathanaigh Roghnaithe"
closePdf = "Dún an PDF"
exportAll = "Easpórtáil an PDF"
downloadSelected = "Íoslódáil na Comhaid Roghnaithe"
annotations = "Annotations"
exportSelected = "Easpórtáil na Leathanaigh Roghnaithe"
saveChanges = "Sábháil Athruithe"
downloadAll = "Íoslódáil Uile"
saveAll = "Sábháil Uile"
toggleTheme = "Athraigh an Téama"
toggleBookmarks = "Scoránaigh Leabharmharcanna"
language = "Teanga"
toggleAnnotations = "Athraigh Infheictheacht Anótálacha"
search = "Cuardaigh an PDF"
panMode = "Mód Pánála"
rotateLeft = "Rothlaigh ar Chlé"
rotateRight = "Rothlaigh ar Dheis"
toggleSidebar = "Athraigh an Barra Taoibh"
toggleBookmarks = "Scoránaigh Leabharmharcanna"
exportSelected = "Easpórtáil na Leathanaigh Roghnaithe"
toggleAnnotations = "Athraigh Infheictheacht Anótálacha"
annotationMode = "Athraigh Mód Anótála"
print = "Priontáil PDF"
downloadAll = "Íoslódáil Uile"
saveAll = "Sábháil Uile"
applyRedactionsFirst = "Apply redactions first"
draw = "Draw"
exitRedaction = "Exit Redaction Mode"
redact = "Redact"
save = "Save"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
saveChanges = "Save Changes"
draw = "Tarraing"
save = "Sábháil"
saveChanges = "Sábháil Athruithe"
[search]
title = "Cuardaigh PDF"
@@ -4265,20 +4038,12 @@ settings = "Socruí"
adminSettings = "Socruí riar."
allTools = "All Tools"
reader = "Léamh"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Turas na nUirlisí"
toolsTourDesc = "Faigh amach cad is féidir leis na huirlisí a dhéanamh"
adminTour = "Turas an Riarthóra"
adminTourDesc = "Déan iniúchadh ar shocruithe agus gnéithe an riarthóra"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Earráid"
@@ -4304,8 +4069,6 @@ loginRequired = "Ní mór mód logála isteach a bheith cumasaithe chun socruith
restarting = "Freastalaí á Atosú"
restartingMessage = "Tá an freastalaí á atosú. Fan nóiméad le do thoil..."
restartError = "Theip ar an bhfreastalaí a atosú. Atosaigh de láimh le do thoil."
error = "Failed to save settings"
success = "Settings saved successfully"
[admin.settings.unsavedChanges]
title = "Athruithe gan sábháil"
@@ -4422,10 +4185,6 @@ description = "Conair chuig inrite WeasyPrint le haghaidh tiontaithe HTML go PDF
label = "Inrite Unoconvert"
description = "Conair chuig LibreOffice unoconvert le haghaidh tiontaithe doiciméad (fág folamh don réamhshocrú: /opt/venv/bin/unoconvert)"
[admin.settings.general.frontendUrl]
description = "Base URL for frontend (e.g., https://pdf.example.com). Used for email invite links and mobile QR code uploads. Leave empty to use backend URL."
label = "Frontend URL"
[admin.settings.security]
title = "Slándáil"
description = "Cumraigh fíordheimhniú, iompar logála isteach, agus polasaithe slándála."
@@ -4562,19 +4321,6 @@ connect = "Ceangail"
disconnect = "Dícheangail"
disconnected = "Dícheanglaíodh an soláthraí go rathúil"
disconnectError = "Theip ar an soláthraí a dhícheangal"
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
pageFormatA4 = "A4 (210×297mm)"
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatLetter = "Letter (8.5×11in)"
[admin.settings.connections.ssoAutoLogin]
label = "Logáil Isteach Uathoibríoch SSO"
@@ -4643,26 +4389,6 @@ description = "Cruthaigh cuntais úsáideora go huathoibríoch ar an gcéad log
label = "Cuir Clárú ar Chosc"
description = "Cosc ar chlárú úsáideoirí nua trí SAML2"
[admin.settings.connections.mobileScanner]
description = "Allow users to upload files from mobile devices by scanning a QR code"
enable = "Enable QR Code Upload"
imageResolutionFull = "Full (Original Size)"
imageResolutionReduced = "Reduced (Max 1200px)"
label = "Mobile Phone Upload"
link = "Configure in System Settings"
mobileScannerConvertToPdf = "Convert Images to PDF"
mobileScannerConvertToPdfDesc = "Automatically convert uploaded images to PDF format. If disabled, images will be kept as-is."
mobileScannerImageResolution = "Image Resolution"
mobileScannerImageResolutionDesc = "Resolution of uploaded images. \"Reduced\" scales images to max 1200px to reduce file size."
mobileScannerPageFormat = "Page Format"
mobileScannerPageFormatDesc = "PDF page size for converted images. \"Keep\" uses original image dimensions."
mobileScannerStretchToFit = "Stretch to Fit"
mobileScannerStretchToFitDesc = "Stretch images to fill the entire page. If disabled, images are centered with preserved aspect ratio."
note = "Note: Requires Frontend URL to be configured. "
pageFormatA4 = "A4 (210×297mm)"
pageFormatKeep = "Keep (Original Dimensions)"
pageFormatLetter = "Letter (8.5×11in)"
[admin.settings.database]
title = "Bunachar Sonraí"
description = "Cumraigh socruithe ceangail bunachair shonraí saincheaptha le haghaidh imscaradh fiontraíochta."
@@ -4844,10 +4570,6 @@ description = "Ceadaigh do riarthóirí úsáideoirí a thabhairt cuireadh trí
label = "URL an Tosaigh"
description = "BunURL don tosaigh (m.sh. https://pdf.example.com). Úsáidtear é chun naisc chuireadh a ghiniúint i ríomhphoist. Fág folamh chun URL an chúlchórais a úsáid."
[admin.settings.mail.frontendUrlNote]
link = "Configure in System Settings"
note = "Note: Requires Frontend URL to be configured. "
[admin.settings.legal]
title = "Doiciméid Dhlíthiúla"
description = "Cumraigh naisc le doiciméid agus polasaithe dlíthiúla."
@@ -4963,105 +4685,6 @@ description = "Roghnaigh críochphointí aonair le díchumasú"
label = "Grúpaí Críochphointí Díchumasaithe"
description = "Roghnaigh grúpaí críochphointí le díchumasú"
[admin.settings.badge]
clickToUpgrade = "Click to view plan details"
[admin.settings.telegram]
description = "Configure Telegram bot connectivity, access controls, and feedback behavior."
title = "Telegram Bot"
[admin.settings.telegram.accessControl]
description = "Restrict which users or channels can interact with the bot."
title = "Access Control"
[admin.settings.telegram.allowChannelIDs]
description = "Enter Telegram channel IDs allowed to interact with the bot."
label = "Allowed Channel IDs"
placeholder = "Add channel ID and press enter"
[admin.settings.telegram.allowUserIDs]
description = "Enter Telegram user IDs allowed to interact with the bot."
label = "Allowed User IDs"
placeholder = "Add user ID and press enter"
[admin.settings.telegram.botToken]
description = "API token provided by BotFather for your Telegram bot."
label = "Bot Token"
[admin.settings.telegram.botUsername]
description = "The public username of your Telegram bot."
label = "Bot Username"
[admin.settings.telegram.customFolderSuffix]
description = "Append the chat ID to incoming file folders to isolate uploads per chat."
label = "Use Custom Folder Suffix"
[admin.settings.telegram.enableAllowChannelIDs]
description = "When enabled, only listed channel IDs can use the bot."
label = "Allow Specific Channel IDs"
[admin.settings.telegram.enableAllowUserIDs]
description = "When enabled, only listed user IDs can use the bot."
label = "Allow Specific User IDs"
[admin.settings.telegram.enabled]
description = "Allow users to interact with Stirling PDF through your configured Telegram bot."
label = "Enable Telegram Bot"
[admin.settings.telegram.feedback]
description = "Choose when the bot should send feedback to users and channels."
title = "Feedback Messages"
[admin.settings.telegram.feedback.channel]
title = "Channel Feedback Rules"
[admin.settings.telegram.feedback.channel.errorMessage]
description = "Show detailed error messages for channels."
label = "Show error messages (Channel)"
[admin.settings.telegram.feedback.channel.errorProcessing]
description = "Send processing error messages to channels."
label = "Show processing errors (Channel)"
[admin.settings.telegram.feedback.channel.noValidDocument]
description = "Suppress the no valid document response for channel uploads."
label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.general.enabled]
description = "Control whether the bot sends feedback messages at all."
label = "Enable Feedback"
[admin.settings.telegram.feedback.user]
title = "User Feedback Rules"
[admin.settings.telegram.feedback.user.errorMessage]
description = "Show detailed error messages for users."
label = "Show error messages (User)"
[admin.settings.telegram.feedback.user.errorProcessing]
description = "Send processing error messages to users."
label = "Show processing errors (User)"
[admin.settings.telegram.feedback.user.noValidDocument]
description = "Suppress the no valid document response for user uploads."
label = "Show \"No valid document\" (User)"
[admin.settings.telegram.pipelineInboxFolder]
description = "Folder under the pipeline directory where incoming Telegram files are stored."
label = "Inbox Folder"
[admin.settings.telegram.pollingIntervalMillis]
description = "Interval between checks for new Telegram updates."
label = "Polling Interval (ms)"
[admin.settings.telegram.processing]
description = "Control polling intervals and processing timeouts for Telegram uploads."
title = "Processing"
[admin.settings.telegram.processingTimeoutSeconds]
description = "Maximum time to wait for a processing job before reporting an error."
label = "Processing Timeout (seconds)"
[fileUpload]
selectFile = "Roghnaigh comhad"
selectFiles = "Roghnaigh comhaid"
@@ -5161,9 +4784,6 @@ showAll = "Taispeáin Uile"
sortByDate = "Sórtáil de réir Dáta"
sortByName = "Sórtáil de réir Ainm"
sortBySize = "Sórtáil de réir Méid"
mobileShort = "Mobile"
mobileUpload = "Mobile Upload"
mobileUploadNotAvailable = "Mobile upload not enabled"
[storage]
temporaryNotice = "Stóráiltear comhaid go sealadach i do bhrabhsálaí agus dfhéadfaí iad a ghlanadh go huathoibríoch"
@@ -5449,7 +5069,6 @@ loading = "Á lódáil..."
back = "Siar"
continue = "Lean ar aghaidh"
error = "Earráid"
save = "Save"
[config.overview]
title = "Cumraíocht an Fheidhmchláir"
@@ -5512,15 +5131,6 @@ impact = "Stopfaidh aon fheidhmchláir nó seirbhísí atá ag úsáid na n-eoch
confirmPrompt = "An bhfuil tú cinnte gur mian leat leanúint ar aghaidh?"
confirmCta = "Athnuaigh Eochracha"
[config.apiKeys.alert]
apiKeyErrorTitle = "API Key Error"
apiKeyRefreshed = "API Key Refreshed"
apiKeyRefreshedBody = "Your API key has been successfully refreshed."
failedToCreateApiKey = "Failed to create API key."
failedToFetchApiKey = "Failed to fetch API key."
failedToRefreshApiKey = "Failed to refresh API key."
failedToRetrieveApiKey = "Failed to retrieve API key from response."
[AddAttachmentsRequest]
attachments = "Roghnaigh Iatáin"
info = "Roghnaigh comhaid le ceangal le do PDF. Ionsádtar na comhaid seo agus beidh siad inrochtana trí phainéal iatán an PDF."
@@ -5625,16 +5235,6 @@ finish = "Críochnaigh"
startTour = "Tosaigh an Turas"
startTourDescription = "Téigh ar thuras treoraithe de phríomhghnéithe Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Fáilte go Stirling PDF!"
description = "Ar mhaith leat turas gasta 1 nóiméad a dhéanamh chun na príomhghnéithe agus conas tosú a fhoghlaim?"
@@ -5655,10 +5255,6 @@ download = "Íoslódáil →"
showMeAround = "Taispeáin timpeall dom"
skipTheTour = "Scipeáil an turas"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Scipeáil faoi láthair"
seePlans = "Féach ar Phleananna →"
@@ -5972,28 +5568,6 @@ contactSales = "Déan Teagmháil le Díolacháin"
contactToUpgrade = "Déan teagmháil linn chun do phlean a uasghrádú nó a shaincheapadh"
maxUsers = "Uaslíon Úsáideoirí"
upTo = "Suas le"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mí"
@@ -6197,8 +5771,6 @@ notAvailable = "Níl an córas iniúchta ar fáil"
notAvailableMessage = "Níl an córas iniúchta cumraithe nó níl sé ar fáil."
disabled = "Tá logáil iniúchta díchumasaithe"
disabledMessage = "Cumasaigh logáil iniúchta i gcumraíocht dfheidhmchláir chun imeachtaí an chórais a rianú."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Earráid agus an córas iniúchta á lódáil"
@@ -6373,7 +5945,6 @@ emptyUrl = "Cuir isteach URL freastalaí le do thoil"
unreachable = "Níorbh fhéidir ceangal leis an bhfreastalaí"
testFailed = "Theip ar thástáil an cheangail"
configFetch = "Níor éirigh le cumraíocht an fhreastalaí a fháil. Seiceáil an URL agus bain triail eile as."
invalidUrl = "Invalid URL format. Please enter a valid URL like https://your-server.com"
[setup.server.error.securityDisabled]
title = "Níl an Logáil Isteach Cumasaithe"
@@ -6397,7 +5968,6 @@ instructions = "Chun logáil isteach a chumasú ar do fhreastalaí Stirling PDF:
instructionsEnvVar = "Socraigh an athróg chomhshaoil:"
instructionsOrYml = "Nó i settings.yml:"
instructionsRestart = "Ansin atosaigh do fhreastalaí chun go mbeidh na hathruithe i bhfeidhm."
sso = "Single Sign-On"
[setup.login.username]
label = "Ainm Úsáideora"
@@ -6455,8 +6025,6 @@ reset = "Athshocraigh Athruithe"
downloadJson = "Íoslódáil JSON"
generatePdf = "Gin PDF"
saveChanges = "Sábháil Athruithe"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Scálaigh téacs go huathoibríoch chun boscaí a fheistiú"
@@ -6475,24 +6043,6 @@ descriptionInline = "Leid: Coinnigh Ctrl (Cmd) nó Shift chun boscaí téacs a r
title = "Glasáil téacs curtha in eagar le heilimint PDF aonair"
description = "Nuair atá cumasaithe, easpórtálann an t-eagarthóir gach bosca téacs curtha in eagar mar eilimint téacs PDF amháin chun glifaí forluiteacha nó clónna measctha a sheachaint."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Cumaisc na boscaí roghnaithe"
merge = "Cumaisc an roghnú"
@@ -6614,58 +6164,3 @@ title = "Torthaí Cur Téacs"
[addText.error]
failed = "Tharla earráid agus téacs á chur leis an PDF."
[mobileScanner]
addToBatch = "Add to Batch"
back = "Back"
batchImages = "Batch"
camera = "Camera"
cameraAccessDenied = "Camera access denied. Please enable camera access."
cameraDescription = "Scan documents using your device camera with automatic edge detection"
capture = "Capture Photo"
chooseMethod = "Choose Upload Method"
chooseMethodDescription = "Select how you want to scan and upload documents"
clearBatch = "Clear"
connected = "Connected"
connecting = "Connecting..."
edgeDetection = "Edge Detection"
fileDescription = "Upload existing photos or documents from your device"
fileUpload = "File Upload"
flash = "Flash"
flashlight = "Flashlight"
httpsRequired = "Camera access requires HTTPS or localhost. Please use HTTPS or access via localhost."
noSession = "Invalid Session"
noSessionMessage = "Please scan a valid QR code to access this page."
preview = "Preview"
processing = "Processing..."
retake = "Retake"
selectFilesPrompt = "Select files to upload"
selectImage = "Select Image"
sessionExpired = "This session has expired. Please refresh and try again."
sessionInvalid = "Session Error"
sessionNotFound = "Session not found. Please refresh and try again."
sessionValidationError = "Unable to verify session. Please try again."
settings = "Settings"
title = "Mobile Scanner"
upload = "Upload"
uploadAll = "Upload All"
uploadFailed = "Upload failed. Please try again."
uploadSuccess = "Upload Successful!"
uploadSuccessMessage = "Your images have been transferred."
uploading = "Uploading..."
validating = "Validating session..."
[mobileUpload]
connected = "Mobile device connected"
description = "Scan to upload photos. Images auto-convert to PDF."
descriptionNoConvert = "Scan to upload photos from your mobile device."
error = "Connection Error"
expiryWarning = "Session Expiring Soon"
expiryWarningMessage = "This QR code will expire in {{seconds}} seconds. A new code will be generated automatically."
filesReceived = "{{count}} file(s) received"
instructions = "Scan with your phone camera. Images convert to PDF automatically."
instructionsNoConvert = "Scan with your phone camera to upload files."
pollingError = "Error checking for files"
sessionCreateError = "Failed to create session"
sessionId = "Session ID"
title = "Upload from Mobile"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "उन्नत"
edit = "देखें और संपादित करें"
popular = "लोकप्रिय"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "प्राथमिकताएँ"
@@ -439,25 +435,6 @@ latestVersion = "नवीनतम संस्करण"
checkForUpdates = "अपडेट्स जाँचें"
viewDetails = "विवरण देखें"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "कीबोर्ड शॉर्टकट्स"
description = "त्वरित टूल एक्सेस के लिए कीबोर्ड शॉर्टकट्स कस्टमाइज़ करें। \"Change shortcut\" पर क्लिक करें और नया की कॉम्बिनेशन दबाएँ। रद्द करने के लिए Esc दबाएँ।"
@@ -511,16 +488,11 @@ low = "कम"
title = "क्रेडेंशियल्स बदलें"
header = "अपना खाता विवरण अपडेट करें"
changePassword = "आप डिफ़ॉल्ट लॉगिन क्रेडेंशियल्स का उपयोग कर रहे हैं। कृपया एक नया पासवर्ड दर्ज करें"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "नया उपयोगकर्ता नाम"
oldPassword = "वर्तमान पासवर्ड"
newPassword = "नया पासवर्ड"
confirmNewPassword = "नए पासवर्ड की पुष्टि करें"
submit = "परिवर्तन जमा करें"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "खाता सेटिंग्स"
@@ -736,11 +708,6 @@ tags = "हस्ताक्षर,ऑटोग्राफ"
title = "हस्ताक्षर करें"
desc = "चित्र बनाकर, टेक्स्ट या छवि द्वारा PDF में हस्ताक्षर जोड़ें"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "सरल बनाएं,हटाएँ,इंटरैक्टिव"
title = "समतल करें"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ से PDF विकल्प"
optimizeForEbook = "ईबुक रीडर्स के लिए PDF ऑप्टिमाइज़ करें (Ghostscript का उपयोग करता है)"
cbzOutputOptions = "PDF से CBZ विकल्प"
cbzDpi = "इमेज रेंडरिंग के लिए DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "रूपांतरण,img,jpg,चित्र,फोटो"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "अटैचमेंट जोड़ें"
remove = "अटैचमेंट हटाएँ"
embed = "अटैचमेंट एम्बेड करें"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "सहेजा गया"
label = "हस्ताक्षर की इमेज अपलोड करें"
placeholder = "इमेज फ़ाइल चुनें"
hint = "अपने हस्ताक्षर की PNG या JPG इमेज अपलोड करें"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "हस्ताक्षर कैसे जोड़ें"
@@ -2408,11 +2351,6 @@ note = "फ्लैटन करने से PDF के इंटरैक्
label = "केवल फ़ॉर्म समतल करें"
desc = "केवल फॉर्म फ़ील्ड फ्लैटन करें, अन्य इंटरैक्टिव तत्व यथावत रखें"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "फ्लैटन परिणाम"
@@ -2987,7 +2925,6 @@ header = "PDF क्रॉप करें"
submit = "जमा करें"
noFileSelected = "क्रॉप शुरू करने के लिए एक PDF फ़ाइल चुनें"
reset = "पूर्ण PDF पर रीसेट करें"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "क्रॉप क्षेत्र चयन"
@@ -3405,19 +3342,6 @@ placeholder = "क्षैतिज विभाजनों की संख
label = "ऊर्ध्वाधर विभाजन"
placeholder = "ऊर्ध्वाधर विभाजनों की संख्या दर्ज करें"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "स्टैम्प, छवि जोड़ें, केंद्र छवि, वॉटरमार्क, PDF, एम्बेड, अनुकूलित"
header = "PDF स्टैम्प करें"
@@ -3779,19 +3703,6 @@ filesize = "फ़ाइल आकार"
[compress.grayscale]
label = "संपीड़न के लिए ग्रेस्केल लागू करें"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "संपीड़न सेटिंग्स अवलोकन"
@@ -3809,10 +3720,6 @@ bullet2 = "अधिक मान फ़ाइल आकार घटाते
title = "श्वेत-श्याम"
text = "सभी छवियों को काले-सफेद में बदलने के लिए इस विकल्प को चुनें, जो विशेषकर स्कैन किए गए PDFs या चित्र-प्रधान दस्तावेज़ों के लिए फ़ाइल आकार को काफी घटा सकता है।"
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF संपीड़ित करते समय त्रुटि हुई।"
@@ -3825,11 +3732,6 @@ failed = "PDF संपीड़ित करते समय त्रुटि
_value = "संपीड़न सेटिंग्स"
1 = "1-3 PDF संपीड़न,</br> 4-6 हल्का छवि संपीड़न,</br> 7-9 तीव्र छवि संपीड़न छवि गुणवत्ता को काफी घटाएगा"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "यह फ़ाइल पासवर्ड से सुरक्षित है। कृपया पासवर्ड दर्ज करें:"
cancelled = "PDF के लिए कार्रवाई रद्द की गई: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "चयनित पृष्ठ हटाएँ"
closePdf = "PDF बंद करें"
exportAll = "PDF निर्यात करें"
downloadSelected = "चयनित फ़ाइलें डाउनलोड करें"
annotations = "Annotations"
exportSelected = "चयनित पृष्ठ निर्यात करें"
saveChanges = "परिवर्तनों को सहेजें"
downloadAll = "सभी डाउनलोड करें"
saveAll = "सभी सहेजें"
toggleTheme = "थीम टॉगल करें"
toggleBookmarks = "बुकमार्क्स टॉगल करें"
language = "भाषा"
toggleAnnotations = "एनोटेशन दृश्यता टॉगल करें"
search = "PDF खोजें"
panMode = "पैन मोड"
rotateLeft = "बाएँ घुमाएँ"
rotateRight = "दाएँ घुमाएँ"
toggleSidebar = "साइडबार टॉगल करें"
toggleBookmarks = "बुकमार्क्स टॉगल करें"
exportSelected = "चयनित पृष्ठ निर्यात करें"
toggleAnnotations = "एनोटेशन दृश्यता टॉगल करें"
annotationMode = "एनोटेशन मोड टॉगल करें"
print = "PDF प्रिंट करें"
downloadAll = "सभी डाउनलोड करें"
saveAll = "सभी सहेजें"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "ड्रॉ"
save = "सहेजें"
saveChanges = "परिवर्तनों को सहेजें"
[search]
title = "PDF खोजें"
@@ -4205,20 +4038,12 @@ settings = "सेटिंग्स"
adminSettings = "एडमिन सेटिंग्स"
allTools = "All Tools"
reader = "रीडर"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "टूल्स टूर"
toolsTourDesc = "जानें कि टूल क्या कर सकते हैं"
adminTour = "एडमिन टूर"
adminTourDesc = "एडमिन सेटिंग्स और फ़ीचर्स का अन्वेषण करें"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "त्रुटि"
@@ -5244,7 +5069,6 @@ loading = "लोड हो रहा है..."
back = "वापस"
continue = "जारी रखें"
error = "त्रुटि"
save = "Save"
[config.overview]
title = "एप्लिकेशन कॉन्फ़िगरेशन"
@@ -5411,16 +5235,6 @@ finish = "समाप्त करें"
startTour = "टूर शुरू करें"
startTourDescription = "Stirling PDF की प्रमुख विशेषताओं का मार्गदर्शित टूर लें"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDF में आपका स्वागत है!"
description = "क्या आप 1-मिनट का त्वरित टूर लेना चाहेंगे ताकि मुख्य फीचर्स और शुरुआत करने का तरीका जान सकें?"
@@ -5441,10 +5255,6 @@ download = "डाउनलोड →"
showMeAround = "मुझे दिखाएँ"
skipTheTour = "टूर छोड़ें"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "अभी छोड़ें"
seePlans = "प्लान देखें →"
@@ -5758,28 +5568,6 @@ contactSales = "सेल्स से संपर्क करें"
contactToUpgrade = "अपने प्लान को अपग्रेड या कस्टमाइज़ करने के लिए हमसे संपर्क करें"
maxUsers = "अधिकतम उपयोगकर्ता"
upTo = "तक"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "माह"
@@ -5983,8 +5771,6 @@ notAvailable = "ऑडिट सिस्टम उपलब्ध नहीं"
notAvailableMessage = "ऑडिट सिस्टम कॉन्फ़िगर नहीं है या उपलब्ध नहीं है।"
disabled = "ऑडिट लॉगिंग अक्षम है"
disabledMessage = "सिस्टम ईवेंट ट्रैक करने के लिए अपनी एप्लिकेशन कॉन्फ़िगरेशन में ऑडिट लॉगिंग सक्षम करें।"
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "ऑडिट सिस्टम लोड करने में त्रुटि"
@@ -6239,8 +6025,6 @@ reset = "परिवर्तन रीसेट करें"
downloadJson = "JSON डाउनलोड करें"
generatePdf = "PDF जनरेट करें"
saveChanges = "परिवर्तन सहेजें"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "टेक्स्ट को बॉक्स में फिट करने हेतु ऑटो-स्केल"
@@ -6259,24 +6043,6 @@ descriptionInline = "टिप: मल्टी-सेलेक्ट करन
title = "संपादित टेक्स्ट को एक ही PDF एलिमेंट में लॉक करें"
description = "सक्रिय होने पर, ओवरलैपिंग glyphs या मिश्रित फ़ॉन्ट्स से बचने के लिए, एडिटर संपादित हर टेक्स्ट बॉक्स को एक PDF टेक्स्ट एलिमेंट के रूप में एक्सपोर्ट करता है."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "चयनित बॉक्सों को मर्ज करें"
merge = "चयन मर्ज करें"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Napredno"
edit = "Pregled & Uređivanje"
popular = "Popularno"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferencije"
@@ -439,25 +435,6 @@ latestVersion = "Najnovija verzija"
checkForUpdates = "Provjeri ažuriranja"
viewDetails = "Prikaži detalje"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Prečaci tipkovnice"
description = "Prilagodite prečace tipkovnice za brz pristup alatima. Kliknite \"Promijeni prečac\" i pritisnite novu kombinaciju tipki. Pritisnite Esc za odustajanje."
@@ -511,16 +488,11 @@ low = "Nizak"
title = "Promijeni pristupne podatke"
header = "Ažurirajte korisničke podatke"
changePassword = "Koristite zadanu lozinku za prijavu. Unesite novu lozinku"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Novo korisničko ime"
oldPassword = "Trenutna zaporka"
newPassword = "Nova zaporka"
confirmNewPassword = "Potvrdite novu lozinku"
submit = "Potvrdi"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Postavke računa"
@@ -736,11 +708,6 @@ tags = "potpis,autogram"
title = "Potpisati"
desc = "Dodaje potpis u PDF crtežom, tekstom ili slikom"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "pojednostavi,ukloni,interaktivno"
title = "Ravnanje (Flatten)"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opcije CBZ u PDF"
optimizeForEbook = "Optimiziraj PDF za e-čitače (koristi Ghostscript)"
cbzOutputOptions = "Opcije PDF u CBZ"
cbzDpi = "DPI za renderiranje slike"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konverzija,pretvaranje,img,jpg,slika,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Dodaj privitak"
remove = "Ukloni privitak"
embed = "Ugradi privitak"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Spremljeno"
label = "Učitaj sliku potpisa"
placeholder = "Odaberite slikovnu datoteku"
hint = "Učitajte PNG ili JPG sliku svojega potpisa"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Kako dodati potpis"
@@ -2408,11 +2351,6 @@ note = "Spljoštavanje uklanja interaktivne elemente iz PDF-a, čineći ih neure
label = "Izravnati samo obrasce"
desc = "Spljošti samo polja obrazaca, ostavljajući druge interaktivne elemente netaknute"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Rezultati spljoštavanja"
@@ -2987,7 +2925,6 @@ header = "Izreži sliku"
submit = "Potvrdi"
noFileSelected = "Odaberite PDF datoteku za početak izrezivanja"
reset = "Vrati na cijeli PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Odabir područja izrezivanja"
@@ -3405,19 +3342,6 @@ placeholder = "Unesite broj vodoravnih podjela"
label = "Okomite podjele"
placeholder = "Unesite broj okomitih podjela"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Pečat, dodavanje slike, središnja slika, vodeni žig, PDF, ugradnja, prilagodba"
header = "Pečat PDF"
@@ -3779,19 +3703,6 @@ filesize = "Veličina datoteke"
[compress.grayscale]
label = "Primijeni sivinu za kompresiju"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Pregled postavki kompresije"
@@ -3809,10 +3720,6 @@ bullet2 = "Više vrijednosti smanjuju veličinu datoteke"
title = "Sivi tonovi"
text = "Odaberite ovu opciju kako biste sve slike pretvorili u crno-bijele, što može znatno smanjiti veličinu datoteke, osobito za skenirane PDF-ove ili dokumente s mnogo slika."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Došlo je do pogreške pri komprimiranju PDF-a."
@@ -3825,11 +3732,6 @@ failed = "Došlo je do pogreške pri komprimiranju PDF-a."
_value = "Postavke kompresije"
1 = "1-3 PDF kompresija,</br> 4-6 blaga kompresija slika,</br> 7-9 jaka kompresija slika značajno će smanjiti kvalitetu slike"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ova je datoteka zaštićena lozinkom. Unesite lozinku:"
cancelled = "Operacija otkazana za PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Izbriši odabrane stranice"
closePdf = "Zatvori PDF"
exportAll = "Izvezi PDF"
downloadSelected = "Preuzmi odabrane datoteke"
annotations = "Annotations"
exportSelected = "Izvezi odabrane stranice"
saveChanges = "Spremi promjene"
downloadAll = "Preuzmi sve"
saveAll = "Spremi sve"
toggleTheme = "Prebaci temu"
toggleBookmarks = "Prebaci knjižne oznake"
language = "Jezik"
toggleAnnotations = "Prebaci vidljivost bilješki"
search = "Pretraži PDF"
panMode = "Način pomicanja"
rotateLeft = "Rotiraj ulijevo"
rotateRight = "Rotiraj udesno"
toggleSidebar = "Prebaci bočnu traku"
toggleBookmarks = "Prebaci knjižne oznake"
exportSelected = "Izvezi odabrane stranice"
toggleAnnotations = "Prebaci vidljivost bilješki"
annotationMode = "Prebaci način bilješki"
print = "Ispis PDF-a"
downloadAll = "Preuzmi sve"
saveAll = "Spremi sve"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Crtaj"
save = "Spremi"
saveChanges = "Spremi promjene"
[search]
title = "Pretraži PDF"
@@ -4205,20 +4038,12 @@ settings = "Postavke"
adminSettings = "Admin postavke"
allTools = "All Tools"
reader = "Čitač"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Vodič kroz alate"
toolsTourDesc = "Saznajte što alati mogu"
adminTour = "Vodič za administratore"
adminTourDesc = "Istražite administratorske postavke i značajke"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Pogreška"
@@ -5244,7 +5069,6 @@ loading = "Učitavanje..."
back = "Natrag"
continue = "Nastavi"
error = "Pogreška"
save = "Save"
[config.overview]
title = "Konfiguracija aplikacije"
@@ -5411,16 +5235,6 @@ finish = "Završi"
startTour = "Započni obilazak"
startTourDescription = "Krenite u vođeni obilazak ključnih značajki alata Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Dobrodošli u Stirling PDF!"
description = "Želite li brzu 1-minutnu turu kako biste naučili ključne značajke i kako započeti?"
@@ -5441,10 +5255,6 @@ download = "Preuzmi →"
showMeAround = "Provedi me"
skipTheTour = "Preskoči obilazak"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Preskoči zasad"
seePlans = "Pogledaj planove →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontaktirajte prodaju"
contactToUpgrade = "Kontaktirajte nas za nadogradnju ili prilagodbu vašeg plana"
maxUsers = "Maks. korisnika"
upTo = "Do"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mjesec"
@@ -5983,8 +5771,6 @@ notAvailable = "Sustav revizije nije dostupan"
notAvailableMessage = "Sustav revizije nije konfiguriran ili nije dostupan."
disabled = "Revizijsko zapisivanje je onemogućeno"
disabledMessage = "Omogućite revizijsko zapisivanje u konfiguraciji aplikacije kako biste pratili sustavne događaje."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Pogreška pri učitavanju sustava revizije"
@@ -6239,8 +6025,6 @@ reset = "Poništi promjene"
downloadJson = "Preuzmi JSON"
generatePdf = "Generiraj PDF"
saveChanges = "Spremi promjene"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Automatski skaliraj tekst kako bi stao u okvire"
@@ -6259,24 +6043,6 @@ descriptionInline = "Savjet: Držite Ctrl (Cmd) ili Shift za višestruki odabir
title = "Zaključaj uređeni tekst u jedan PDF element"
description = "Kad je omogućeno, uređivač izvozi svaki uređeni tekstualni okvir kao jedan PDF tekstni element kako bi se izbjeglo preklapanje glifova ili miješanje fontova."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Spoji odabrane okvire"
merge = "Spoji odabir"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Haladó"
edit = "Megtekintés és szerkesztés"
popular = "Népszerű"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Beállítások"
@@ -439,25 +435,6 @@ latestVersion = "Legújabb verzió"
checkForUpdates = "Frissítések keresése"
viewDetails = "Részletek megtekintése"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Billentyűparancsok"
description = "Testreszabhatja a billentyűparancsokat az eszközök gyors eléréséhez. Kattintson a \"Billentyűparancs módosítása\" gombra, és nyomjon meg egy új billentyűkombinációt. A megszakításhoz nyomja meg az Esc billentyűt."
@@ -511,16 +488,11 @@ low = "Alacsony"
title = "Hitelesítési adatok módosítása"
header = "Fiókadatok frissítése"
changePassword = "Az alapértelmezett bejelentkezési adatokat használja. Kérjük, adjon meg új jelszót"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Új felhasználónév"
oldPassword = "Jelenlegi jelszó"
newPassword = "Új jelszó"
confirmNewPassword = "Új jelszó megerősítése"
submit = "Változtatások mentése"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Fiókbeállítások"
@@ -736,11 +708,6 @@ tags = "aláírás,szignó"
title = "Aláírás"
desc = "Aláírás hozzáadása PDF-hez rajzolással, szöveggel vagy képpel"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "egyszerűsít,eltávolít,interaktív"
title = "Lapítás"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ to PDF beállítások"
optimizeForEbook = "PDF optimalizálása e-könyv olvasókhoz (Ghostscript használatával)"
cbzOutputOptions = "PDF to CBZ beállítások"
cbzDpi = "DPI a képrendereléshez"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konverzió,kép,jpg,fotó,fénykép"
@@ -1409,11 +1361,6 @@ header = "Mellékletek hozzáadása"
add = "Melléklet hozzáadása"
remove = "Melléklet eltávolítása"
embed = "Melléklet beágyazása"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Csatolmányok hozzáadása a PDF-hez"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Mentett"
label = "Aláíráskép feltöltése"
placeholder = "Képfájl kiválasztása"
hint = "Töltse fel az aláírását tartalmazó PNG vagy JPG képet"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Hogyan adjon hozzá aláírást"
@@ -2408,11 +2351,6 @@ note = "A lapítás eltávolítja az interaktív elemeket a PDF-ből, így azok
label = "Csak űrlapok lapítása"
desc = "Csak az űrlapmezők lapítása, a többi interaktív elem változatlanul marad"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Lapítás eredménye"
@@ -2987,7 +2925,6 @@ header = "PDF vágása"
submit = "Küldés"
noFileSelected = "Válasszon egy PDF-fájlt a vágás megkezdéséhez"
reset = "Visszaállítás teljes PDF-re"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Vágási terület kiválasztása"
@@ -3405,19 +3342,6 @@ placeholder = "Adja meg a vízszintes felosztások számát"
label = "Függőleges felosztások"
placeholder = "Adja meg a függőleges felosztások számát"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Pecsét,Kép hozzáadása,középre igazítás,Vízjel,PDF,Beágyazás,Testreszabás"
header = "PDF pecsételése"
@@ -3779,19 +3703,6 @@ filesize = "Fájlméret"
[compress.grayscale]
label = "Szürkeárnyalatok alkalmazása tömörítéshez"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Tömörítési beállítások áttekintése"
@@ -3809,10 +3720,6 @@ bullet2 = "Magasabb értékek csökkentik a fájlméretet"
title = "Szürkeárnyalatos"
text = "Válassza ezt az opciót az összes kép fekete-fehérre konvertálásához, ami jelentősen csökkentheti a fájlméretet, különösen beszkennelt PDF-eknél vagy képekkel teli dokumentumoknál."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Hiba történt a PDF tömörítése közben."
@@ -3825,11 +3732,6 @@ failed = "Hiba történt a PDF tömörítése közben."
_value = "Tömörítési beállítások"
1 = "1-3 PDF tömörítés,</br> 4-6 enyhe kép tömörítés,</br> 7-9 intenzív kép tömörítés Jelentősen csökkenti a kép minőségét"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ez a fájl jelszóval védett. Kérjük, adja meg a jelszót:"
cancelled = "Művelet megszakítva a PDF-nél: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Kijelölt oldalak törlése"
closePdf = "PDF bezárása"
exportAll = "PDF exportálása"
downloadSelected = "Kijelölt fájlok letöltése"
annotations = "Annotations"
exportSelected = "Kijelölt oldalak exportálása"
saveChanges = "Változtatások mentése"
downloadAll = "Összes letöltése"
saveAll = "Összes mentése"
toggleTheme = "Téma váltása"
toggleBookmarks = "Könyvjelzők megjelenítése/elrejtése"
language = "Nyelv"
toggleAnnotations = "Jegyzetek láthatóságának váltása"
search = "PDF keresése"
panMode = "Pásztázó mód"
rotateLeft = "Forgatás balra"
rotateRight = "Forgatás jobbra"
toggleSidebar = "Oldalsáv ki/be"
toggleBookmarks = "Könyvjelzők megjelenítése/elrejtése"
exportSelected = "Kijelölt oldalak exportálása"
toggleAnnotations = "Jegyzetek láthatóságának váltása"
annotationMode = "Jegyzetelési mód váltása"
print = "PDF nyomtatása"
downloadAll = "Összes letöltése"
saveAll = "Összes mentése"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Rajzolás"
save = "Mentés"
saveChanges = "Változtatások mentése"
[search]
title = "PDF keresése"
@@ -4205,20 +4038,12 @@ settings = "Beáll."
adminSettings = "Admin beáll."
allTools = "All Tools"
reader = "Olvasó"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Eszköztúra"
toolsTourDesc = "Ismerje meg, mire képesek az eszközök"
adminTour = "Admin túra"
adminTourDesc = "Fedezze fel az admin beállításokat és funkciókat"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Hiba"
@@ -5244,7 +5069,6 @@ loading = "Betöltés..."
back = "Vissza"
continue = "Folytatás"
error = "Hiba"
save = "Save"
[config.overview]
title = "Alkalmazás konfigurációja"
@@ -5411,16 +5235,6 @@ finish = "Befejezés"
startTour = "Túra indítása"
startTourDescription = "Vezetett túra a Stirling PDF fő funkcióiról"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Üdvözli a Stirling PDF!"
description = "Szeretne egy gyors, 1 perces túrát, hogy megismerje a fő funkciókat és a kezdést?"
@@ -5441,10 +5255,6 @@ download = "Letöltés →"
showMeAround = "Körbevezetés"
skipTheTour = "Körbevezetés kihagyása"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Kihagyás most"
seePlans = "Csomagok megtekintése →"
@@ -5758,28 +5568,6 @@ contactSales = "Kapcsolat az értékesítéssel"
contactToUpgrade = "Lépjen kapcsolatba velünk a csomag frissítéséhez vagy testreszabásához"
maxUsers = "Max. felhasználók"
upTo = "Legfeljebb"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "hónap"
@@ -5983,8 +5771,6 @@ notAvailable = "Audit rendszer nem érhető el"
notAvailableMessage = "Az audit rendszer nincs konfigurálva vagy nem elérhető."
disabled = "Az audit naplózás le van tiltva"
disabledMessage = "Engedélyezze az audit naplózást az alkalmazás konfigurációjában a rendszeresemények követéséhez."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Hiba az audit rendszer betöltésekor"
@@ -6239,8 +6025,6 @@ reset = "Módosítások visszaállítása"
downloadJson = "JSON letöltése"
generatePdf = "PDF generálása"
saveChanges = "Változtatások mentése"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Szöveg automatikus méretezése a dobozokhoz"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tipp: Tartsa lenyomva a Ctrl (Cmd) vagy a Shift billentyűt
title = "Szerkesztett szöveg rögzítése egyetlen PDF-elemhez"
description = "Bekapcsolva a szerkesztő minden szerkesztett szövegdobozt egy PDF szövegelemként exportál, elkerülve az átfedő glifákat vagy kevert betűtípusokat."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Kijelölt dobozok egyesítése"
merge = "Kijelölés egyesítése"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Langkah Lanjut"
edit = "Melihat & Mengedit"
popular = "Populer"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferensi"
@@ -439,25 +435,6 @@ latestVersion = "Versi Terbaru"
checkForUpdates = "Periksa Pembaruan"
viewDetails = "Lihat Detail"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Pintasan Keyboard"
description = "Sesuaikan pintasan keyboard untuk akses cepat ke alat. Klik \"Change shortcut\" dan tekan kombinasi tombol baru. Tekan Esc untuk membatalkan."
@@ -511,16 +488,11 @@ low = "Rendah"
title = "Ubah Kredensial"
header = "Perbarui Detail Akun Anda"
changePassword = "Anda menggunakan kredensial login default. Silakan masukkan kata sandi baru"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nama Pengguna Baru"
oldPassword = "Kata Sandi Saat Ini"
newPassword = "Kata Sandi Baru"
confirmNewPassword = "Konfirmasi Kata Sandi Baru"
submit = "Kirim Perubahan"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Pengaturan Akun"
@@ -736,11 +708,6 @@ tags = "tanda tangan,autograf"
title = "Tanda Tangan"
desc = "Menambahkan tanda tangan ke PDF dengan gambar, teks, atau gambar"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "sederhanakan,hapus,interaktif"
title = "Meratakan"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opsi CBZ ke PDF"
optimizeForEbook = "Optimalkan PDF untuk pembaca ebook (menggunakan Ghostscript)"
cbzOutputOptions = "Opsi PDF ke CBZ"
cbzDpi = "DPI untuk perenderan gambar"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konversi,img,jpg,gambar,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Tambahkan Lampiran"
remove = "Hapus Lampiran"
embed = "Sematkan Lampiran"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Tersimpan"
label = "Unggah gambar tanda tangan"
placeholder = "Pilih berkas gambar"
hint = "Unggah gambar PNG atau JPG dari tanda tangan Anda"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Cara menambahkan tanda tangan"
@@ -2408,11 +2351,6 @@ note = "Perataan menghapus elemen interaktif dari PDF, membuatnya tidak dapat di
label = "Ratakan hanya formulir"
desc = "Hanya meratakan bidang formulir, membiarkan elemen interaktif lainnya tetap utuh"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Hasil Perataan"
@@ -2987,7 +2925,6 @@ header = "Pangkas PDF"
submit = "Kirim"
noFileSelected = "Pilih file PDF untuk mulai memotong"
reset = "Atur ulang ke PDF penuh"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Pilihan Area Pangkas"
@@ -3405,19 +3342,6 @@ placeholder = "Input angka untuk pembagian horizontal"
label = "Pembagian Vertikal"
placeholder = "Input angka untuk pembagian vertikal"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Tanda tangan, tambahkan gambar, posisikan gambar di tengah, air tinta, PDF, embedding, customisasi"
header = "Stampel PDF"
@@ -3779,19 +3703,6 @@ filesize = "Ukuran Berkas"
[compress.grayscale]
label = "Terapkan Skala Abu-Abu untuk Kompresi"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Ringkasan Pengaturan Kompresi"
@@ -3809,10 +3720,6 @@ bullet2 = "Nilai lebih tinggi mengurangi ukuran file"
title = "Skala abu-abu"
text = "Pilih opsi ini untuk mengonversi semua gambar menjadi hitam putih, yang dapat secara signifikan mengurangi ukuran file terutama untuk PDF hasil pemindaian atau dokumen yang banyak gambar."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Terjadi kesalahan saat mengompresi PDF."
@@ -3825,11 +3732,6 @@ failed = "Terjadi kesalahan saat mengompresi PDF."
_value = "Pengaturan Kompresi"
1 = "1-3 kompresi PDF,</br> 4-6 kompresi gambar ringan,</br> 7-9 kompresi gambar intens akan sangat mengurangi kualitas gambar"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "File ini dilindungi kata sandi. Silakan masukkan kata sandi:"
cancelled = "Operasi dibatalkan untuk PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Hapus Halaman Terpilih"
closePdf = "Tutup PDF"
exportAll = "Ekspor PDF"
downloadSelected = "Unduh File Terpilih"
annotations = "Annotations"
exportSelected = "Ekspor Halaman Terpilih"
saveChanges = "Simpan Perubahan"
downloadAll = "Unduh Semua"
saveAll = "Simpan Semua"
toggleTheme = "Alihkan Tema"
toggleBookmarks = "Tampilkan/Sembunyikan Bookmark"
language = "Bahasa"
toggleAnnotations = "Alihkan Visibilitas Anotasi"
search = "Cari PDF"
panMode = "Mode Geser"
rotateLeft = "Putar Kiri"
rotateRight = "Putar Kanan"
toggleSidebar = "Alihkan Sidebar"
toggleBookmarks = "Tampilkan/Sembunyikan Bookmark"
exportSelected = "Ekspor Halaman Terpilih"
toggleAnnotations = "Alihkan Visibilitas Anotasi"
annotationMode = "Alihkan Mode Anotasi"
print = "Cetak PDF"
downloadAll = "Unduh Semua"
saveAll = "Simpan Semua"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Gambar"
save = "Simpan"
saveChanges = "Simpan Perubahan"
[search]
title = "Cari PDF"
@@ -4205,20 +4038,12 @@ settings = "Setelan"
adminSettings = "Setelan Admin"
allTools = "All Tools"
reader = "Pembaca"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Tur Alat"
toolsTourDesc = "Pelajari apa yang bisa dilakukan alat"
adminTour = "Tur Admin"
adminTourDesc = "Jelajahi pengaturan & fitur admin"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Kesalahan"
@@ -5244,7 +5069,6 @@ loading = "Memuat..."
back = "Kembali"
continue = "Lanjut"
error = "Kesalahan"
save = "Save"
[config.overview]
title = "Konfigurasi Aplikasi"
@@ -5411,16 +5235,6 @@ finish = "Selesai"
startTour = "Mulai Tur"
startTourDescription = "Ikuti tur terpandu tentang fitur utama Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Selamat datang di Stirling PDF!"
description = "Ingin mengikuti tur singkat 1 menit untuk mempelajari fitur utama dan cara memulai?"
@@ -5441,10 +5255,6 @@ download = "Unduh →"
showMeAround = "Tunjukkan saya"
skipTheTour = "Lewati tur"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Lewati dulu"
seePlans = "Lihat Paket →"
@@ -5758,28 +5568,6 @@ contactSales = "Hubungi Penjualan"
contactToUpgrade = "Hubungi kami untuk meningkatkan atau menyesuaikan paket Anda"
maxUsers = "Pengguna Maks"
upTo = "Hingga"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "bulan"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistem audit tidak tersedia"
notAvailableMessage = "Sistem audit belum dikonfigurasi atau tidak tersedia."
disabled = "Pencatatan audit dinonaktifkan"
disabledMessage = "Aktifkan pencatatan audit di konfigurasi aplikasi Anda untuk melacak peristiwa sistem."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Kesalahan saat memuat sistem audit"
@@ -6239,8 +6025,6 @@ reset = "Reset Perubahan"
downloadJson = "Unduh JSON"
generatePdf = "Buat PDF"
saveChanges = "Simpan Perubahan"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Sesuaikan teks otomatis ke kotak"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tips: Tahan Ctrl (Cmd) atau Shift untuk memilih beberapa ko
title = "Kunci teks yang diedit ke satu elemen PDF"
description = "Saat diaktifkan, editor mengekspor setiap kotak teks yang diedit sebagai satu elemen teks PDF untuk menghindari glif yang saling tumpang tindih atau font campuran."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Gabungkan kotak yang dipilih"
merge = "Gabungkan pilihan"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avanzate"
edit = "Visualizza & Modifica"
popular = "Popolare"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferenze"
@@ -439,25 +435,6 @@ latestVersion = "Ultima versione"
checkForUpdates = "Controlla aggiornamenti"
viewDetails = "Vedi dettagli"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Scorciatoie da tastiera"
description = "Personalizza le scorciatoie da tastiera per l'accesso rapido agli strumenti. Clicca \"Cambia scorciatoia\" e premi una nuova combinazione di tasti. Premi Esc per annullare."
@@ -511,16 +488,11 @@ low = "Bassa"
title = "Cambia credenziali"
header = "Aggiorna i dettagli del tuo account"
changePassword = "Stai utilizzando le credenziali di accesso predefinite. Inserisci una nuova password"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nuovo nome utente"
oldPassword = "Password attuale"
newPassword = "Nuova Password"
confirmNewPassword = "Conferma nuova Password"
submit = "Invia modifiche"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Impostazioni Account"
@@ -736,11 +708,6 @@ tags = "firma,autografo"
title = "Firma"
desc = "Aggiungi una firma al PDF da disegno, testo o immagine."
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "semplifica,rimuovi,interattivo"
title = "Appiattisci"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opzioni CBZ in PDF"
optimizeForEbook = "Ottimizza il PDF per i lettori ebook (usa Ghostscript)"
cbzOutputOptions = "Opzioni PDF in CBZ"
cbzDpi = "DPI per il rendering delle immagini"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversione,img,jpg,immagine,foto"
@@ -1409,11 +1361,6 @@ header = "Aggiungi allegati"
add = "Aggiungi allegato"
remove = "Rimuovi allegato"
embed = "Incorpora allegato"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Aggiungi allegati"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Salvate"
label = "Carica immagine firma"
placeholder = "Seleziona file immagine"
hint = "Carica un'immagine PNG o JPG della tua firma"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Come aggiungere la firma"
@@ -2408,11 +2351,6 @@ note = "L'appiattimento rimuove gli elementi interattivi dal PDF, rendendoli non
label = "Appiattisci solo i moduli"
desc = "Appiattisci solo i campi modulo, lasciando intatti gli altri elementi interattivi"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Risultati di appiattimento"
@@ -2987,7 +2925,6 @@ header = "Ritaglia PDF"
submit = "Invia"
noFileSelected = "Seleziona un file PDF per iniziare il ritaglio"
reset = "Reimposta allintero PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Selezione area di ritaglio"
@@ -3405,19 +3342,6 @@ placeholder = "Inserire il numero di divisioni orizzontali"
label = "Divisioni verticali"
placeholder = "Inserire il numero di divisioni verticali"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Timbro,Aggiungi immagine,Centra immagine,Filigrana,PDF,Incorpora,Personalizza"
header = "Timbro PDF"
@@ -3779,19 +3703,6 @@ filesize = "Dimensione"
[compress.grayscale]
label = "Applica scala di grigio per la compressione"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Panoramica impostazioni di compressione"
@@ -3809,10 +3720,6 @@ bullet2 = "Valori più alti riducono la dimensione del file"
title = "Scala di grigi"
text = "Seleziona questa opzione per convertire tutte le immagini in bianco e nero, il che può ridurre significativamente la dimensione, specialmente per PDF scansionati o ricchi di immagini."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Si è verificato un errore durante la compressione del PDF."
@@ -3825,11 +3732,6 @@ failed = "Si è verificato un errore durante la compressione del PDF."
_value = "Impostazioni di compressione"
1 = "1-3 Compressione PDF,</br> 4-6 Compressione immagine leggera,</br> 7-9 Compressione immagine intensa Ridurrà drasticamente la qualità dell'immagine"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Questo file è protetto da password. Inserisci la password:"
cancelled = "Operazione annullata per il PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Elimina pagine selezionate"
closePdf = "Chiudi PDF"
exportAll = "Esporta PDF"
downloadSelected = "Scarica file selezionati"
annotations = "Annotations"
exportSelected = "Esporta pagine selezionate"
saveChanges = "Salva modifiche"
downloadAll = "Scarica tutto"
saveAll = "Salva tutto"
toggleTheme = "Cambia tema"
toggleBookmarks = "Mostra/Nascondi segnalibri"
language = "Lingua"
toggleAnnotations = "Attiva/disattiva visibilità annotazioni"
search = "Cerca nel PDF"
panMode = "Modalità mano"
rotateLeft = "Ruota a sinistra"
rotateRight = "Ruota a destra"
toggleSidebar = "Mostra/Nascondi barra laterale"
toggleBookmarks = "Mostra/Nascondi segnalibri"
exportSelected = "Esporta pagine selezionate"
toggleAnnotations = "Attiva/disattiva visibilità annotazioni"
annotationMode = "Attiva/disattiva modalità annotazione"
print = "Stampa PDF"
downloadAll = "Scarica tutto"
saveAll = "Salva tutto"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Disegna"
save = "Salva"
saveChanges = "Salva modifiche"
[search]
title = "Cerca nel PDF"
@@ -4205,20 +4038,12 @@ settings = "Opzioni"
adminSettings = "Opzioni Admin"
allTools = "Funzioni"
reader = "Lettore"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Tour strumenti"
toolsTourDesc = "Scopri cosa possono fare gli strumenti"
adminTour = "Tour amministratore"
adminTourDesc = "Esplora impostazioni e funzionalità di amministrazione"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Errore"
@@ -5244,7 +5069,6 @@ loading = "Caricamento..."
back = "Indietro"
continue = "Continua"
error = "Errore"
save = "Save"
[config.overview]
title = "Configurazione applicazione"
@@ -5411,16 +5235,6 @@ finish = "Fine"
startTour = "Avvia tour"
startTourDescription = "Fai un tour guidato delle funzioni chiave di Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Benvenuto in Stirling PDF!"
description = "Vuoi fare un tour rapido di 1 minuto per imparare le funzioni chiave e come iniziare?"
@@ -5441,10 +5255,6 @@ download = "Scarica →"
showMeAround = "Fammi fare un tour"
skipTheTour = "Salta il tour"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Salta per ora"
seePlans = "Vedi piani →"
@@ -5758,28 +5568,6 @@ contactSales = "Contatta il reparto vendite"
contactToUpgrade = "Contattaci per aggiornare o personalizzare il tuo piano"
maxUsers = "Utenti massimi"
upTo = "Fino a"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mese"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistema di audit non disponibile"
notAvailableMessage = "Il sistema di audit non è configurato o non è disponibile."
disabled = "La registrazione dell'audit è disattivata"
disabledMessage = "Abilita la registrazione dell'audit nella configurazione dell'applicazione per tracciare gli eventi di sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Errore nel caricamento del sistema di audit"
@@ -6239,8 +6025,6 @@ reset = "Reimposta modifiche"
downloadJson = "Scarica JSON"
generatePdf = "Genera PDF"
saveChanges = "Salva modifiche"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Ridimensiona automaticamente il testo alle caselle"
@@ -6259,24 +6043,6 @@ descriptionInline = "Suggerimento: Tieni premuto Ctrl (Cmd) o Shift per selezion
title = "Blocca il testo modificato in un singolo elemento PDF"
description = "Se attivato, l'editor esporta ogni casella di testo modificata come un unico elemento di testo PDF per evitare glifi sovrapposti o font misti."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Unisci caselle selezionate"
merge = "Unisci selezione"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "アドバンスド"
edit = "閲覧と編集"
popular = "人気"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "環境設定"
@@ -439,25 +435,6 @@ latestVersion = "最新バージョン"
checkForUpdates = "更新を確認"
viewDetails = "詳細を表示"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "キーボードショートカット"
description = "ツールにすばやくアクセスできるようキーボードショートカットをカスタマイズします。「Change shortcut」をクリックし、新しいキーの組み合わせを押してください。Escでキャンセルします。"
@@ -511,16 +488,11 @@ low = "低"
title = "資格情報の変更"
header = "アカウントの詳細を更新する"
changePassword = "デフォルトのログイン認証情報を使用しています。新しいパスワードを入力してください"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "新しいユーザー名"
oldPassword = "現在のパスワード"
newPassword = "新しいパスワード"
confirmNewPassword = "新しいパスワードの確認"
submit = "変更を送信"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "アカウント設定"
@@ -736,11 +708,6 @@ tags = "署名,サイン"
title = "署名"
desc = "手書き、テキストまたは画像によってPDFに署名を追加します。"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "平坦化,削除,インタラクティブ除去"
title = "平坦化"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ から PDF へのオプション"
optimizeForEbook = "PDF を eBook リーダー向けに最適化(Ghostscript 使用)"
cbzOutputOptions = "PDF から CBZ へのオプション"
cbzDpi = "画像レンダリングの DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversion,img,jpg,picture,photo,psd,photoshop"
@@ -1409,11 +1361,6 @@ header = "添付ファイルの追加"
add = "添付を追加"
remove = "添付を削除"
embed = "添付を埋め込む"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "添付ファイルの追加"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "保存済み"
label = "署名画像をアップロード"
placeholder = "画像ファイルを選択"
hint = "署名の PNG または JPG 画像をアップロードしてください"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "署名の追加方法"
@@ -2408,11 +2351,6 @@ note = "フラット化すると PDF からインタラクティブ要素が削
label = "フォームのみフラット化"
desc = "フォームフィールドのみをフラット化し、その他のインタラクティブ要素は維持します"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "フラット化の結果"
@@ -2987,7 +2925,6 @@ header = "PDFのトリミング"
submit = "送信"
noFileSelected = "トリミングを開始する PDF ファイルを選択してください"
reset = "PDF 全体にリセット"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "切り抜き範囲の選択"
@@ -3405,19 +3342,6 @@ placeholder = "水平方向の分割数を選択"
label = "垂直方向"
placeholder = "垂直方向の分割数を選択"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "スタンプ, 画像を追加, 画像を中央に配置, 透かし, PDF, 埋め込み, カスタマイズ"
header = "PDFにスタンプを押す"
@@ -3779,19 +3703,6 @@ filesize = "ファイルサイズ"
[compress.grayscale]
label = "圧縮にグレースケールを適用する"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "圧縮設定の概要"
@@ -3809,10 +3720,6 @@ bullet2 = "値が大きいほどファイルサイズを削減"
title = "グレースケール"
text = "このオプションを選ぶと、すべての画像を白黒に変換します。特にスキャン PDF や画像の多い文書で大幅なサイズ削減が見込めます。"
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF の圧縮中にエラーが発生しました。"
@@ -3825,11 +3732,6 @@ failed = "PDF の圧縮中にエラーが発生しました。"
_value = "圧縮設定"
1 = "1-3 PDF圧縮、</br> 4-6 弱い画像圧縮、</br> 7-9 強い画像圧縮により画質が大幅に低下します"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "このファイルはパスワードで保護されています。パスワードを入力してください:"
cancelled = "PDFの操作がキャンセルされました: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "選択したページを削除"
closePdf = "PDF を閉じる"
exportAll = "PDF を書き出し"
downloadSelected = "選択したファイルをダウンロード"
annotations = "Annotations"
exportSelected = "選択したページを書き出し"
saveChanges = "変更を保存"
downloadAll = "すべてをダウンロード"
saveAll = "すべて保存"
toggleTheme = "テーマを切り替え"
toggleBookmarks = "ブックマークを切り替え"
language = "言語"
toggleAnnotations = "注釈の表示を切り替え"
search = "PDF を検索"
panMode = "パンモード"
rotateLeft = "左に回転"
rotateRight = "右に回転"
toggleSidebar = "サイドバーを切り替え"
toggleBookmarks = "ブックマークを切り替え"
exportSelected = "選択したページを書き出し"
toggleAnnotations = "注釈の表示を切り替え"
annotationMode = "注釈モードを切り替え"
print = "PDFを印刷"
downloadAll = "すべてをダウンロード"
saveAll = "すべて保存"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "描画"
save = "保存"
saveChanges = "変更を保存"
[search]
title = "PDF を検索"
@@ -4205,20 +4038,12 @@ settings = "設定"
adminSettings = "管理者設定"
allTools = "All Tools"
reader = "リーダー"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "ツールツアー"
toolsTourDesc = "ツールでできることを学ぶ"
adminTour = "管理ツアー"
adminTourDesc = "管理設定と機能を探索"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "エラー"
@@ -5244,7 +5069,6 @@ loading = "読み込み中..."
back = "戻る"
continue = "続行"
error = "エラー"
save = "Save"
[config.overview]
title = "アプリケーション構成"
@@ -5411,16 +5235,6 @@ finish = "完了"
startTour = "ツアーを開始"
startTourDescription = "Stirling PDF の主な機能をガイド付きで紹介します"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDF へようこそ!"
description = "主な機能と始め方を 1 分のクイックツアーで確認しますか?"
@@ -5441,10 +5255,6 @@ download = "ダウンロード →"
showMeAround = "ツアーを見る"
skipTheTour = "ツアーをスキップ"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "今はスキップ"
seePlans = "プランを見る →"
@@ -5758,28 +5568,6 @@ contactSales = "営業に問い合わせ"
contactToUpgrade = "プランのアップグレードやカスタマイズはお問い合わせください"
maxUsers = "最大ユーザー数"
upTo = "最大"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "月"
@@ -5983,8 +5771,6 @@ notAvailable = "監査システムは利用できません"
notAvailableMessage = "監査システムが未設定または利用できません。"
disabled = "監査ログは無効です"
disabledMessage = "アプリケーション設定で監査ログを有効にして、システムイベントを記録してください。"
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "監査システムの読み込みエラー"
@@ -6239,8 +6025,6 @@ reset = "変更をリセット"
downloadJson = "JSON をダウンロード"
generatePdf = "PDF を生成"
saveChanges = "変更を保存"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "ボックスに収まるようテキストを自動スケール"
@@ -6259,24 +6043,6 @@ descriptionInline = "ヒント: CtrlCmd)または Shift を押しながら
title = "編集したテキストを1つのPDF要素に固定"
description = "有効にすると、編集した各テキストボックスを1つのPDFテキスト要素としてエクスポートし、グリフの重なりやフォント混在を避けます。"
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "選択ボックスを結合"
merge = "選択を結合"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "고급"
edit = "보기 & 편집"
popular = "인기"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "환경설정"
@@ -439,25 +435,6 @@ latestVersion = "최신 버전"
checkForUpdates = "업데이트 확인"
viewDetails = "자세히 보기"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "키보드 단축키"
description = "빠르게 도구에 접근할 수 있도록 키보드 단축키를 사용자 지정하세요. \"단축키 변경\"을 클릭하고 새 키 조합을 누르세요. 취소하려면 Esc를 누르세요."
@@ -511,16 +488,11 @@ low = "낮음"
title = "자격 증명 변경"
header = "계정 정보 업데이트"
changePassword = "기본 로그인 자격 증명을 사용 중입니다. 새 비밀번호를 입력하세요"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "새 사용자 이름"
oldPassword = "현재 비밀번호"
newPassword = "새 비밀번호"
confirmNewPassword = "새 비밀번호 확인"
submit = "변경 사항 제출"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "계정 설정"
@@ -736,11 +708,6 @@ tags = "서명,사인"
title = "서명"
desc = "그리기, 텍스트 또는 이미지로 PDF에 서명 추가"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "단순화,제거,대화형"
title = "평면화"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ → PDF 옵션"
optimizeForEbook = "전자책 리더기에 맞게 PDF 최적화(Ghostscript 사용)"
cbzOutputOptions = "PDF → CBZ 옵션"
cbzDpi = "이미지 렌더링용 DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "변환,이미지,jpg,사진"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "첨부 파일 추가"
remove = "첨부 파일 제거"
embed = "첨부 파일 내장"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "저장됨"
label = "서명 이미지 업로드"
placeholder = "이미지 파일 선택"
hint = "서명 PNG 또는 JPG 이미지를 업로드하세요"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "서명 추가 방법"
@@ -2408,11 +2351,6 @@ note = "평탄화는 PDF의 대화형 요소를 제거하여 편집할 수 없
label = "양식만 평면화"
desc = "양식 필드만 평탄화하고 다른 대화형 요소는 그대로 둡니다"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "평탄화 결과"
@@ -2987,7 +2925,6 @@ header = "PDF 자르기"
submit = "제출"
noFileSelected = "자르기를 시작하려면 PDF 파일을 선택하세요"
reset = "전체 PDF로 재설정"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "자르기 영역 선택"
@@ -3405,19 +3342,6 @@ placeholder = "수평 분할 수 입력"
label = "수직 분할"
placeholder = "수직 분할 수 입력"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "스탬프,이미지 추가,중앙 이미지,워터마크,PDF,삽입,사용자 지정"
header = "PDF 스탬프"
@@ -3779,19 +3703,6 @@ filesize = "파일 크기"
[compress.grayscale]
label = "압축을 위해 그레이스케일 적용"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "압축 설정 개요"
@@ -3809,10 +3720,6 @@ bullet2 = "높은 값은 파일 크기 감소"
title = "그레이스케일"
text = "이 옵션을 선택하면 모든 이미지를 흑백으로 변환합니다. 특히 스캔한 PDF나 이미지가 많은 문서의 파일 크기를 크게 줄일 수 있습니다."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF를 압축하는 중 오류가 발생했습니다."
@@ -3825,11 +3732,6 @@ failed = "PDF를 압축하는 중 오류가 발생했습니다."
_value = "압축 설정"
1 = "1-3 PDF 압축,</br> 4-6 약한 이미지 압축,</br> 7-9 강한 이미지 압축은 이미지 품질을 크게 낮춥니다"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "이 파일은 비밀번호로 보호되어 있습니다. 비밀번호를 입력하세요:"
cancelled = "PDF 작업이 취소되었습니다: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "선택한 페이지 삭제"
closePdf = "PDF 닫기"
exportAll = "PDF 내보내기"
downloadSelected = "선택한 파일 다운로드"
annotations = "Annotations"
exportSelected = "선택한 페이지 내보내기"
saveChanges = "변경 내용 저장"
downloadAll = "전체 다운로드"
saveAll = "모두 저장"
toggleTheme = "테마 전환"
toggleBookmarks = "북마크 표시/숨기기"
language = "언어"
toggleAnnotations = "주석 가시성 전환"
search = "PDF 검색"
panMode = "이동 모드"
rotateLeft = "왼쪽으로 회전"
rotateRight = "오른쪽으로 회전"
toggleSidebar = "사이드바 전환"
toggleBookmarks = "북마크 표시/숨기기"
exportSelected = "선택한 페이지 내보내기"
toggleAnnotations = "주석 가시성 전환"
annotationMode = "주석 모드 전환"
print = "PDF 인쇄"
downloadAll = "전체 다운로드"
saveAll = "모두 저장"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "그리기"
save = "저장"
saveChanges = "변경 내용 저장"
[search]
title = "PDF 검색"
@@ -4205,20 +4038,12 @@ settings = "설정"
adminSettings = "관리자 설정"
allTools = "All Tools"
reader = "리더"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "도구 둘러보기"
toolsTourDesc = "도구로 할 수 있는 일을 알아보세요"
adminTour = "관리자 둘러보기"
adminTourDesc = "관리자 설정 및 기능을 살펴보세요"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "오류"
@@ -5244,7 +5069,6 @@ loading = "불러오는 중..."
back = "뒤로"
continue = "계속"
error = "오류"
save = "Save"
[config.overview]
title = "애플리케이션 구성"
@@ -5411,16 +5235,6 @@ finish = "완료"
startTour = "투어 시작"
startTourDescription = "Stirling PDF의 주요 기능을 둘러보는 가이드 투어"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDF에 오신 것을 환영합니다!"
description = "주요 기능과 시작 방법을 1분 만에 알아보는 간단한 투어를 진행할까요?"
@@ -5441,10 +5255,6 @@ download = "다운로드 →"
showMeAround = "둘러보기"
skipTheTour = "투어 건너뛰기"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "나중에 건너뛰기"
seePlans = "요금제 보기 →"
@@ -5758,28 +5568,6 @@ contactSales = "영업팀 문의"
contactToUpgrade = "요금제 업그레이드 또는 맞춤 설정은 문의해 주세요"
maxUsers = "최대 사용자 수"
upTo = "최대"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "월"
@@ -5983,8 +5771,6 @@ notAvailable = "감사 시스템을 사용할 수 없습니다"
notAvailableMessage = "감사 시스템이 구성되어 있지 않거나 사용할 수 없습니다."
disabled = "감사 로깅이 비활성화되었습니다"
disabledMessage = "시스템 이벤트를 추적하려면 애플리케이션 구성에서 감사 로깅을 활성화하세요."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "감사 시스템을 불러오는 중 오류"
@@ -6239,8 +6025,6 @@ reset = "변경 사항 초기화"
downloadJson = "JSON 다운로드"
generatePdf = "PDF 생성"
saveChanges = "변경 사항 저장"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "텍스트 자동 크기 조정"
@@ -6259,24 +6043,6 @@ descriptionInline = "팁: Ctrl(Cmd) 또는 Shift를 눌러 텍스트 상자를
title = "편집된 텍스트를 단일 PDF 요소로 고정"
description = "활성화하면 겹치는 글리프나 혼합 폰트를 피하기 위해 편집된 각 텍스트 상자를 하나의 PDF 텍스트 요소로 내보냅니다."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "선택 항목 병합"
merge = "선택 병합"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "വിപുലമായത്"
edit = "കാണുക & തിരുത്തുക"
popular = "ജനപ്രിയം"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "അഭിരുചികൾ"
@@ -439,25 +435,6 @@ latestVersion = "പുതിയ പതിപ്പ്"
checkForUpdates = "അപ്‌ഡേറ്റുകൾ പരിശോധിക്കുക"
viewDetails = "വിശദാംശങ്ങൾ കാണുക"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "കീബോർഡ് ഷോർട്ട്‌കട്ടുകൾ"
description = "ടൂൾസ് വേഗത്തിൽ ആക്‌സസ് ചെയ്യാൻ കീബോർഡ് ഷോർട്ട്‌കട്ടുകൾ ഇഷ്ടാനുസൃതമാക്കുക. \"Change shortcut\" ക്ലിക്ക് ചെയ്ത് ഒരു പുതിയ കീ കോംബിനേഷൻ അമർത്തുക. റദ്ദാക്കാൻ Esc അമർത്തുക."
@@ -511,16 +488,11 @@ low = "താഴ്ന്നത്"
title = "വിവരങ്ങൾ മാറ്റുക"
header = "നിങ്ങളുടെ അക്കൗണ്ട് വിവരങ്ങൾ അപ്‌ഡേറ്റ് ചെയ്യുക"
changePassword = "നിങ്ങൾ സ്ഥിര ലോഗിൻ വിവരങ്ങളാണ് ഉപയോഗിക്കുന്നത്. ദയവായി ഒരു പുതിയ പാസ്‌വേഡ് നൽകുക"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "പുതിയ ഉപയോക്തൃനാമം"
oldPassword = "നിലവിലെ പാസ്‌വേഡ്"
newPassword = "പുതിയ പാസ്‌വേഡ്"
confirmNewPassword = "പുതിയ പാസ്‌വേഡ് സ്ഥിരീകരിക്കുക"
submit = "മാറ്റങ്ങൾ സമർപ്പിക്കുക"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "അക്കൗണ്ട് ക്രമീകരണങ്ങൾ"
@@ -736,11 +708,6 @@ tags = "ഒപ്പ്,ഓട്ടോഗ്രാഫ്"
title = "ഒപ്പിടുക"
desc = "വരച്ചോ, ടെക്സ്റ്റ് ഉപയോഗിച്ചോ, ചിത്രം ഉപയോഗിച്ചോ PDF-ൽ ഒപ്പ് ചേർക്കുന്നു"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "ലളിതമാക്കുക,നീക്കം ചെയ്യുക,ഇന്ററാക്ടീവ്"
title = "പരത്തുക"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ ടു PDF ഓപ്ഷനുകൾ"
optimizeForEbook = "ഇബുക്ക് റീഡറുകൾക്കായി PDF ഓപ്റ്റിമൈസ് ചെയ്യുക (Ghostscript ഉപയോഗിക്കുന്നു)"
cbzOutputOptions = "PDF ടു CBZ ഓപ്ഷനുകൾ"
cbzDpi = "ഇമേജ് റെൻഡറിംഗിനുള്ള DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "പരിവർത്തനം,img,jpg,ചിത്രം,ഫോട്ടോ"
@@ -1409,11 +1361,6 @@ header = "അറ്റാച്ച്മെന്റുകൾ ചേർക്ക
add = "അറ്റാച്ച്മെന്റ് ചേർക്കുക"
remove = "അറ്റാച്ച്മെന്റ് നീക്കം ചെയ്യുക"
embed = "അറ്റാച്ച്മെന്റ് എംബെഡ് ചെയ്യുക"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "അറ്റാച്ച്മെന്റുകൾ ചേർക്കുക"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "സേവ് ചെയ്തത്"
label = "ഒപ്പിന്റെ ചിത്രം അപ്‌ലോഡ് ചെയ്യുക"
placeholder = "ഇമേജ് ഫയൽ തിരഞ്ഞെടുക്കുക"
hint = "നിങ്ങളുടെ ഒപ്പിന്റെ PNG അല്ലെങ്കിൽ JPG ചിത്രം അപ്‌ലോഡ് ചെയ്യുക"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "ഒപ്പ് എങ്ങനെ ചേർക്കാം"
@@ -2408,11 +2351,6 @@ note = "ഫ്ലാറ്റൻ ചെയ്യുന്നത് PDF-ിൽ
label = "ഫോമുകൾ മാത്രം ഫ്ലാറ്റൻ ചെയ്യുക"
desc = "ഫോം ഫീൽഡുകൾ മാത്രം ഫ്ലാറ്റൻ ചെയ്ത്, മറ്റു ഇന്ററാക്ടീവ് ഘടകങ്ങൾ അവികൃതമായി വിടുക"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "ഫ്ലാറ്റൻ ഫലങ്ങൾ"
@@ -2987,7 +2925,6 @@ header = "PDF ക്രോപ്പ് ചെയ്യുക"
submit = "സമർപ്പിക്കുക"
noFileSelected = "ക്രോപ്പ് ആരംഭിക്കാൻ ഒരു PDF ഫയൽ തിരഞ്ഞെടുക്കുക"
reset = "പൂർണ്ണ PDF ലേക്ക് റീസെറ്റ് ചെയ്യുക"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "ക്രോപ്പ് ഏരിയ തിരഞ്ഞെടുപ്പ്"
@@ -3405,19 +3342,6 @@ placeholder = "തിരശ്ചീന വിഭജനങ്ങളുടെ എ
label = "ലംബ വിഭജനങ്ങൾ"
placeholder = "ലംബ വിഭജനങ്ങളുടെ എണ്ണം നൽകുക"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "സ്റ്റാമ്പ്, ചിത്രം ചേർക്കുക, ചിത്രം മധ്യത്തിലാക്കുക, വാട്ടർമാർക്ക്, PDF, ഉൾപ്പെടുത്തുക, ഇഷ്ടാനുസൃതമാക്കുക"
header = "PDF സ്റ്റാമ്പ് ചെയ്യുക"
@@ -3779,19 +3703,6 @@ filesize = "ഫയൽ വലിപ്പം"
[compress.grayscale]
label = "കംപ്രഷനായി ഗ്രേസ്‌കെയിൽ പ്രയോഗിക്കുക"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "കംപ്രസ് സെറ്റിങ്ങുകളുടെ അവലോകനം"
@@ -3809,10 +3720,6 @@ bullet2 = "ഉയർന്ന മൂല്യങ്ങൾ ഫയൽ വലിപ
title = "ഗ്രേസ്കെയിൽ"
text = "എല്ലാ ഇമേജുകളും ബ്ലാക്ക്-ആൻഡ്-വൈറ്റാക്കി മാറ്റാൻ ഈ ഓപ്ഷൻ തിരഞ്ഞെടുക്കുക; പ്രത്യേകിച്ച് സ്കാൻ ചെയ്ത PDFകൾക്കും ഇമേജ് കൂടുതലുള്ള ഡോക്യുമെന്റുകൾക്കും ഫയൽ വലിപ്പം ഗണ്യമായി കുറയ്ക്കാം."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF കംപ്രസ് ചെയ്യുന്നതിനിടെ പിശക് സംഭവിച്ചു."
@@ -3825,11 +3732,6 @@ failed = "PDF കംപ്രസ് ചെയ്യുന്നതിനിട
_value = "കംപ്രഷൻ ക്രമീകരണങ്ങൾ"
1 = "1-3 PDF കംപ്രഷൻ,</br> 4-6 ലൈറ്റ് ഇമേജ് കംപ്രഷൻ,</br> 7-9 തീവ്രമായ ഇമേജ് കംപ്രഷൻ ചിത്രത്തിന്റെ ഗുണനിലവാരം ഗണ്യമായി കുറയ്ക്കും"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "ഈ ഫയൽ പാസ്‌വേഡ് ഉപയോഗിച്ച് സംരക്ഷിച്ചിരിക്കുന്നു. ദയവായി പാസ്‌വേഡ് നൽകുക:"
cancelled = "PDF-നായുള്ള പ്രവർത്തനം റദ്ദാക്കി: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "തിരഞ്ഞെടുത്ത പേജുകൾ ഇല
closePdf = "PDF അടയ്ക്കുക"
exportAll = "PDF എക്സ്പോർട്ട് ചെയ്യുക"
downloadSelected = "തിരഞ്ഞെടുത്ത ഫയലുകൾ ഡൗൺലോഡ് ചെയ്യുക"
annotations = "Annotations"
exportSelected = "തിരഞ്ഞെടുത്ത പേജുകൾ എക്സ്പോർട്ട് ചെയ്യുക"
saveChanges = "മാറ്റങ്ങൾ സംരക്ഷിക്കുക"
downloadAll = "എല്ലാം ഡൗൺലോഡ് ചെയ്യുക"
saveAll = "എല്ലാം സേവ് ചെയ്യുക"
toggleTheme = "തീം മാറ്റുക"
toggleBookmarks = "ബുക്ക്‌മാർക്കുകൾ ടോഗിൾ ചെയ്യുക"
language = "ഭാഷ"
toggleAnnotations = "അനോട്ടേഷൻ ദൃശ്യമാനം മാറ്റുക"
search = "PDF തിരയുക"
panMode = "പാൻ മോഡ്"
rotateLeft = "ഇടത്തേക്ക് തിരിക്കുക"
rotateRight = "വലത്തേക്ക് തിരിക്കുക"
toggleSidebar = "സൈഡ്ബാർ മാറ്റുക"
toggleBookmarks = "ബുക്ക്‌മാർക്കുകൾ ടോഗിൾ ചെയ്യുക"
exportSelected = "തിരഞ്ഞെടുത്ത പേജുകൾ എക്സ്പോർട്ട് ചെയ്യുക"
toggleAnnotations = "അനോട്ടേഷൻ ദൃശ്യമാനം മാറ്റുക"
annotationMode = "അനോട്ടേഷൻ മോഡ് മാറ്റുക"
print = "PDF അച്ചടിക്കുക"
downloadAll = "എല്ലാം ഡൗൺലോഡ് ചെയ്യുക"
saveAll = "എല്ലാം സേവ് ചെയ്യുക"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "വരയ്ക്കുക"
save = "സംരക്ഷിക്കുക"
saveChanges = "മാറ്റങ്ങൾ സംരക്ഷിക്കുക"
[search]
title = "PDF തിരയുക"
@@ -4205,20 +4038,12 @@ settings = "സെറ്റിങ്ങുകൾ"
adminSettings = "അഡ്മിൻ സെറ്റിങ്ങുകൾ"
allTools = "All Tools"
reader = "റീഡർ"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "ടൂളുകളുടെ പരിചയം"
toolsTourDesc = "ഉപകരണങ്ങൾ എന്ത് ചെയ്യുമെന്നു പഠിക്കുക"
adminTour = "അഡ്മിൻ പരിചയം"
adminTourDesc = "അഡ്മിൻ സജ്ജീകരണങ്ങളും സവിശേഷതകളും അന്വേഷിക്കുക"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "പിശക്"
@@ -5244,7 +5069,6 @@ loading = "ലോഡുചെയ്യുന്നു..."
back = "തിരികെ"
continue = "തുടരുക"
error = "പിശക്"
save = "Save"
[config.overview]
title = "ആപ്ലിക്കേഷൻ ക്രമീകരണം"
@@ -5411,16 +5235,6 @@ finish = "പൂർത്തിയാക്കുക"
startTour = "ടൂർ ആരംഭിക്കുക"
startTourDescription = "Stirling PDF 的 പ്രധാന സവിശേഷതകളുടെ മാർഗ്ഗനിർദ്ദേശ ടൂർ"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDFലേക്ക് സ്വാഗതം!"
description = "പ്രധാന സവിശേഷതകളും തുടങ്ങുന്നത് എങ്ങനെയെന്നതും അറിയാൻ 1 മിനിട്ടിലെ ഒരു ദ്രുത ടൂർ വേണമോ?"
@@ -5441,10 +5255,6 @@ download = "ഡൗൺലോഡ് →"
showMeAround = "ടൂർ കാണിക്കുക"
skipTheTour = "ടൂർ ഒഴിവാക്കുക"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "ഇപ്പോൾ ഒഴിവാക്കുക"
seePlans = "പ്ലാനുകൾ കാണുക →"
@@ -5758,28 +5568,6 @@ contactSales = "വിൽപ്പന ടീമിനെ ബന്ധപ്പ
contactToUpgrade = "നിങ്ങളുടെ പ്ലാൻ അപ്‌ഗ്രേഡ് ചെയ്യുകയോ ഇഷ്ടാനുസൃതമാക്കുകയോ ചെയ്യാൻ ഞങ്ങളെ ബന്ധപ്പെടുക"
maxUsers = "പരമാവധി ഉപയോക്താക്കൾ"
upTo = "വരെ"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "മാസം"
@@ -5983,8 +5771,6 @@ notAvailable = "ഓഡിറ്റ് സിസ്റ്റം ലഭ്യമ
notAvailableMessage = "ഓഡിറ്റ് സിസ്റ്റം കോൺഫിഗർ ചെയ്തിട്ടില്ല അല്ലെങ്കിൽ ലഭ്യമല്ല."
disabled = "ഓഡിറ്റ് ലോഗിംഗ് പ്രവർത്തനരഹിതമാണ്"
disabledMessage = "സിസ്റ്റം ഇവന്റുകൾ ട്രാക്ക് ചെയ്യാൻ നിങ്ങളുടെ ആപ്ലിക്കേഷൻ ക്രമീകരണത്തിൽ ഓഡിറ്റ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "ഓഡിറ്റ് സിസ്റ്റം ലോഡ് ചെയ്യുന്നതിൽ പിശക്"
@@ -6239,8 +6025,6 @@ reset = "മാറ്റങ്ങൾ റീസെറ്റ് ചെയ്യു
downloadJson = "JSON ഡൗൺലോഡ് ചെയ്യുക"
generatePdf = "PDF സൃഷ്ടിക്കുക"
saveChanges = "മാറ്റങ്ങൾ സംരക്ഷിക്കുക"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "ബോക്‌സിൽ ഒതുങ്ങാൻ ടെക്സ്റ്റ് സ്വയം സ്കെയിൽ ചെയ്യുക"
@@ -6259,24 +6043,6 @@ descriptionInline = "ടിപ്പ്: ടെക്സ്റ്റ് ബോ
title = "തിരുത്തിയ ടെക്സ്റ്റ് ഒരു സിംഗിൾ PDF ഘടകത്തിൽ ലോക്ക് ചെയ്യുക"
description = "ഇത് ഓണാക്കിയാൽ, ഓവർലാപ്പിംഗ് ഗ്ലിഫ്‌സ് അല്ലെങ്കിൽ മിശ്ര ഫോണ്ടുകൾ ഒഴിവാക്കാൻ തിരുത്തിയ ഓരോ ടെക്സ്റ്റ് ബോക്‌സും ഒറ്റ PDF ടെക്സ്റ്റ് ഘടകമായി എക്സ്പോർട്ട് ചെയ്യും."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "തിരഞ്ഞെടുത്ത ബോക്‌സുകൾ ലയിപ്പിക്കുക"
merge = "ലയിപ്പിക്കുക"
+10 -154
View File
@@ -736,11 +736,6 @@ tags = "handtekening,ondertekenen"
title = "Ondertekenen"
desc = "Voegt handtekening toe aan PDF via tekenen, tekst of afbeelding"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "vereenvoudigen,verwijderen,interactief"
title = "Afvlakken"
@@ -1278,21 +1273,6 @@ cbzOptions = "CBZ-naar-PDF-opties"
optimizeForEbook = "PDF optimaliseren voor e-readers (gebruikt Ghostscript)"
cbzOutputOptions = "PDF-naar-CBZ-opties"
cbzDpi = "DPI voor weergave van afbeeldingen"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversie,img,jpg,foto"
@@ -1409,11 +1389,6 @@ header = "Add attachments"
add = "Bijlage toevoegen"
remove = "Bijlage verwijderen"
embed = "Bijlage insluiten"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2334,6 @@ saved = "Opgeslagen"
label = "Handtekeningafbeelding uploaden"
placeholder = "Afbeeldingsbestand selecteren"
hint = "Upload een PNG- of JPG-afbeelding van uw handtekening"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Hoe een handtekening toevoegen"
@@ -2408,11 +2379,6 @@ note = "Afvlakken verwijdert interactieve elementen uit de PDF, waardoor deze ni
label = "Alleen formulieren afvlakken"
desc = "Alleen formuliervelden afvlakken; andere interactieve elementen blijven intact"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultaten afvlakken"
@@ -2987,7 +2953,6 @@ header = "PDF bijsnijden"
submit = "Indienen"
noFileSelected = "Selecteer een PDF-bestand om te beginnen met bijsnijden"
reset = "Resetten naar volledige PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Selectie bijsnijgebied"
@@ -3405,19 +3370,6 @@ placeholder = "Voer het aantal horizontale secties in"
label = "Verticale secties"
placeholder = "Voer het aantal verticale secties in"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stempel, Afbeelding toevoegen, afbeelding centreren, watermerk, PDF, Insluiten, Aanpassen"
header = "Stempel PDF"
@@ -3779,9 +3731,6 @@ filesize = "Bestandsgrootte"
[compress.grayscale]
label = "Grijstinten toepassen voor compressie"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Afbeeldingen omzetten in lijntekening"
description = "Gebruikt ImageMagick om pagina's te reduceren tot hoogcontrast zwart-wit voor maximale verkleining van de bestandsgrootte."
@@ -3825,11 +3774,6 @@ failed = "Er is een fout opgetreden bij het comprimeren van de PDF."
_value = "Compressie-instellingen"
1 = "1-3 PDF-compressie,</br> 4-6 lichte afbeeldingscompressie,</br> 7-9 intense afbeeldingscompressie Zal de beeldkwaliteit sterk verminderen"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Dit bestand is met een wachtwoord beveiligd. Voer het wachtwoord in:"
cancelled = "Bewerking geannuleerd voor PDF: {0}"
@@ -4069,92 +4013,23 @@ deleteSelected = "Geselecteerde pagina's verwijderen"
closePdf = "PDF sluiten"
exportAll = "PDF exporteren"
downloadSelected = "Geselecteerde bestanden downloaden"
annotations = "Annotations"
exportSelected = "Geselecteerde pagina's exporteren"
saveChanges = "Wijzigingen opslaan"
downloadAll = "Alles downloaden"
saveAll = "Alles opslaan"
toggleTheme = "Thema wisselen"
toggleBookmarks = "Bladwijzers tonen/verbergen"
language = "Taal"
toggleAnnotations = "Annotaties tonen/verbergen"
search = "PDF doorzoeken"
panMode = "Pan-modus"
rotateLeft = "Linksom draaien"
rotateRight = "Rechtsom draaien"
toggleSidebar = "Zijbalk tonen/verbergen"
toggleBookmarks = "Bladwijzers tonen/verbergen"
exportSelected = "Geselecteerde pagina's exporteren"
toggleAnnotations = "Annotaties tonen/verbergen"
annotationMode = "Annotatiemodus schakelen"
print = "PDF afdrukken"
downloadAll = "Alles downloaden"
saveAll = "Alles opslaan"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Tekenen"
save = "Opslaan"
saveChanges = "Wijzigingen opslaan"
[search]
title = "PDF doorzoeken"
@@ -4811,6 +4686,7 @@ title = "Actieve licentie"
file = "Bron: licentiebestand ({{path}})"
key = "Bron: licentiesleutel"
type = "Type: {{type}}"
noInput = "Geef een licentiesleutel op of upload een certificaatbestand"
success = "Succes"
@@ -6239,8 +6115,6 @@ reset = "Wijzigingen resetten"
downloadJson = "JSON downloaden"
generatePdf = "PDF genereren"
saveChanges = "Wijzigingen opslaan"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Tekst automatisch schalen zodat deze in vakken past"
@@ -6259,24 +6133,6 @@ descriptionInline = "Tip: Houd Ctrl (Cmd) of Shift ingedrukt om meerdere tekstva
title = "Bewerkte tekst vastzetten op één PDFelement"
description = "Wanneer ingeschakeld, exporteert de editor elk bewerkt tekstvak als één PDF-tekstelement om overlappende glyphen of gemengde lettertypen te voorkomen."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Geselecteerde vakken samenvoegen"
merge = "Selectie samenvoegen"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avansert"
edit = "Vis & Rediger"
popular = "Populært"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferanser"
@@ -439,25 +435,6 @@ latestVersion = "Siste versjon"
checkForUpdates = "Søk etter oppdateringer"
viewDetails = "Vis detaljer"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Tastatursnarveier"
description = "Tilpass tastatursnarveier for rask tilgang til verktøy. Klikk \"Endre snarvei\" og trykk en ny tastekombinasjon. Trykk Esc for å avbryte."
@@ -511,16 +488,11 @@ low = "Lav"
title = "Endre Legitimasjon"
header = "Oppdater Konto Detaljer"
changePassword = "Du bruker standard påloggingsdetaljer. Vennligst skriv inn et nytt passord"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nytt Brukernavn"
oldPassword = "Nåværende Passord"
newPassword = "Nytt Passord"
confirmNewPassword = "Bekreft Nytt Passord"
submit = "Send Endringer"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Kontoinnstillinger"
@@ -736,11 +708,6 @@ tags = "signatur,autograf"
title = "Signer"
desc = "Legger til signatur i PDF ved tegning, tekst eller bilde"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "forenkle,fjern,interaktiv"
title = "Gjøre flat"
@@ -1278,21 +1245,6 @@ cbzOptions = "Alternativer for CBZ til PDF"
optimizeForEbook = "Optimaliser PDF for e-boklesere (bruker Ghostscript)"
cbzOutputOptions = "Alternativer for PDF til CBZ"
cbzDpi = "DPI for bildegjengivelse"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konvertering,bilde,jpg,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Legg til vedlegg"
remove = "Fjern vedlegg"
embed = "Bygg inn vedlegg"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Lagret"
label = "Last opp signaturbilde"
placeholder = "Velg bildefil"
hint = "Last opp et PNG- eller JPG-bilde av signaturen din"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Slik legger du til signatur"
@@ -2408,11 +2351,6 @@ note = "Utflating fjerner interaktive elementer fra PDF-en og gjør dem ikke-red
label = "Utjevning av kun skjemaer"
desc = "Flat bare ut skjemafelter, og la andre interaktive elementer være intakte"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultater for utflating"
@@ -2987,7 +2925,6 @@ header = "Beskjær PDF"
submit = "Send inn"
noFileSelected = "Velg en PDF-fil for å begynne beskjæring"
reset = "Tilbakestill til full PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Valg av beskjæringsområde"
@@ -3405,19 +3342,6 @@ placeholder = "Skriv inn antall horisontale delinger"
label = "Vertikale delinger"
placeholder = "Skriv inn antall vertikale delinger"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "stempel,legg til bilde,senter bilde,vannmerke,PDF,embed,tilpass"
header = "Stemple PDF"
@@ -3779,19 +3703,6 @@ filesize = "Filstørrelse"
[compress.grayscale]
label = "Bruk gråskala for komprimering"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Oversikt over komprimeringsinnstillinger"
@@ -3809,10 +3720,6 @@ bullet2 = "Høyere verdier reduserer filstørrelsen"
title = "Gråtoner"
text = "Velg dette alternativet for å konvertere alle bilder til svart-hvitt, noe som kan redusere filstørrelsen betydelig, spesielt for skannede PDF-er eller dokumenter med mange bilder."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Det oppstod en feil under komprimering av PDF-en."
@@ -3825,11 +3732,6 @@ failed = "Det oppstod en feil under komprimering av PDF-en."
_value = "Komprimeringsinnstillinger"
1 = "1-3 PDF-komprimering,</br> 4-6 lett bildekomprimering,</br> 7-9 intens bildekomprimering vil redusere bildekvaliteten kraftig"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Denne filen er passordbeskyttet. Skriv inn passordet:"
cancelled = "Operasjon avbrutt for PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Slett valgte sider"
closePdf = "Lukk PDF"
exportAll = "Eksporter PDF"
downloadSelected = "Last ned valgte filer"
annotations = "Annotations"
exportSelected = "Eksporter valgte sider"
saveChanges = "Lagre endringer"
downloadAll = "Last ned alle"
saveAll = "Lagre alle"
toggleTheme = "Bytt tema"
toggleBookmarks = "Veksle bokmerker"
language = "Språk"
toggleAnnotations = "Vis/skjul merknader"
search = "Søk i PDF"
panMode = "Panoreringsmodus"
rotateLeft = "Roter til venstre"
rotateRight = "Roter til høyre"
toggleSidebar = "Vis/skjul sidepanel"
toggleBookmarks = "Veksle bokmerker"
exportSelected = "Eksporter valgte sider"
toggleAnnotations = "Vis/skjul merknader"
annotationMode = "Veksle merknadsmodus"
print = "Skriv ut PDF"
downloadAll = "Last ned alle"
saveAll = "Lagre alle"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Tegn"
save = "Lagre"
saveChanges = "Lagre endringer"
[search]
title = "Søk i PDF"
@@ -4205,20 +4038,12 @@ settings = "Innst."
adminSettings = "Admin Innst."
allTools = "All Tools"
reader = "Leser"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Omvisning i verktøyene"
toolsTourDesc = "Lær hva verktøyene kan gjøre"
adminTour = "Admin-omvisning"
adminTourDesc = "Utforsk admin-innstillinger og funksjoner"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Feil"
@@ -5244,7 +5069,6 @@ loading = "Laster..."
back = "Tilbake"
continue = "Fortsett"
error = "Feil"
save = "Save"
[config.overview]
title = "Programkonfigurasjon"
@@ -5411,16 +5235,6 @@ finish = "Fullfør"
startTour = "Start omvisning"
startTourDescription = "Ta en guidet tur gjennom Stirling PDF sine nøkkelfunksjoner"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Velkommen til Stirling PDF!"
description = "Vil du ta en rask 1-minutts omvisning for å lære nøkkelfunksjonene og hvordan du kommer i gang?"
@@ -5441,10 +5255,6 @@ download = "Last ned →"
showMeAround = "Vis meg rundt"
skipTheTour = "Hopp over omvisningen"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Hopp over nå"
seePlans = "Se planer →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontakt salg"
contactToUpgrade = "Kontakt oss for å oppgradere eller tilpasse planen din"
maxUsers = "Maks brukere"
upTo = "Opptil"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "måned"
@@ -5983,8 +5771,6 @@ notAvailable = "Revisjonssystemet er ikke tilgjengelig"
notAvailableMessage = "Revisjonssystemet er ikke konfigurert eller ikke tilgjengelig."
disabled = "Revisjonslogging er deaktivert"
disabledMessage = "Aktiver revisjonslogging i programkonfigurasjonen for å spore systemhendelser."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Feil ved innlasting av revisjonssystemet"
@@ -6239,8 +6025,6 @@ reset = "Tilbakestill endringer"
downloadJson = "Last ned JSON"
generatePdf = "Generer PDF"
saveChanges = "Lagre endringer"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Autoskalere tekst til å passe i bokser"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tips: Hold Ctrl (Cmd) eller Shift for å multivelge tekstbo
title = "Lås redigert tekst til ett PDF-element"
description = "Når aktivert, eksporterer editoren hver redigerte tekstboks som ett PDF-tekstelement for å unngå overlappende glyfer eller blandede skrifttyper."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Slå sammen valgte bokser"
merge = "Slå sammen utvalg"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Zaawansowane"
edit = "Podgląd i edycja"
popular = "Popularne"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferencje"
@@ -439,25 +435,6 @@ latestVersion = "Najnowsza wersja"
checkForUpdates = "Sprawdź aktualizacje"
viewDetails = "Pokaż szczegóły"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Skróty klawiaturowe"
description = "Dostosuj skróty klawiaturowe, aby szybko uzyskiwać dostęp do narzędzi. Kliknij \"Zmień skrót\" i naciśnij nową kombinację klawiszy. Naciśnij Esc, aby anulować."
@@ -511,16 +488,11 @@ low = "Niski"
title = "Zmień dane logowania"
header = "Zmień dane konta"
changePassword = "Musisz zmienić domyślne dane logowania"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nowa nazwa użytkownika"
oldPassword = "Obecne hasło"
newPassword = "Nowe hasło"
confirmNewPassword = "Potwierdź obecne hasło"
submit = "Zapisz zmiany"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Ustawienia konta"
@@ -736,11 +708,6 @@ tags = "podpis,autograf"
title = "Podpis"
desc = "Dodaje podpis do dokumentu PDF za pomocą rysunku, tekstu lub obrazu"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "spłaszcz,usuń,interaktywne"
title = "Spłaszcz"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opcje CBZ do PDF"
optimizeForEbook = "Optymalizuj PDF dla czytników e-booków (używa Ghostscript)"
cbzOutputOptions = "Opcje PDF do CBZ"
cbzDpi = "DPI renderowania obrazu"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konwersja,img,jpg,obraz,zdjęcie"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Dodaj załącznik"
remove = "Usuń załącznik"
embed = "Osadź załącznik"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Zapisane"
label = "Prześlij obraz podpisu"
placeholder = "Wybierz plik obrazu"
hint = "Prześlij obraz podpisu w formacie PNG lub JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Jak dodać podpis"
@@ -2408,11 +2351,6 @@ note = "Spłaszczanie usuwa elementy interaktywne z PDF, czyniąc je nieedytowal
label = "Spłaszcz tylko formularze"
desc = "Spłaszczaj tylko pola formularzy, pozostawiając inne elementy interaktywne bez zmian"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Wyniki spłaszczania"
@@ -2987,7 +2925,6 @@ header = "Przytnij dokument PDF"
submit = "Wyślij"
noFileSelected = "Wybierz plik PDF, aby rozpocząć przycinanie"
reset = "Resetuj do pełnego PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Wybór obszaru przycięcia"
@@ -3405,19 +3342,6 @@ placeholder = "Podaj ilość podziałów pionowych"
label = "Podział poziomy"
placeholder = "Podaj ilość podziałów poziomych"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stempel, dodawanie obrazu, wyśrodkowanie obrazu, znak wodny, PDF, osadzanie, dostosowywanie"
header = "Pieczęć PDF"
@@ -3779,19 +3703,6 @@ filesize = "Rozmiar pliku"
[compress.grayscale]
label = "Zastosuj skalę szarości do kompresji"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Przegląd ustawień kompresji"
@@ -3809,10 +3720,6 @@ bullet2 = "Wyższe wartości zmniejszają rozmiar pliku"
title = "Skala szarości"
text = "Zaznacz tę opcję, aby przekonwertować wszystkie obrazy na czarnobiałe, co może znacząco zmniejszyć rozmiar pliku, zwłaszcza dla skanów PDF lub dokumentów z wieloma obrazami."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Wystąpił błąd podczas kompresowania PDF."
@@ -3825,11 +3732,6 @@ failed = "Wystąpił błąd podczas kompresowania PDF."
_value = "Ustawienia kompresji"
1 = "1-3 kompresja PDF,</br> 4-6 lekka kompresja obrazów,</br> 7-9 intensywna kompresja obrazów </br> Znacznie obniży jakość obrazu"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ten plik jest chroniony hasłem. Wprowadź hasło:"
cancelled = "Operacja anulowana dla PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Usuń wybrane strony"
closePdf = "Zamknij PDF"
exportAll = "Eksportuj PDF"
downloadSelected = "Pobierz wybrane pliki"
annotations = "Annotations"
exportSelected = "Eksportuj wybrane strony"
saveChanges = "Zapisz zmiany"
downloadAll = "Pobierz wszystko"
saveAll = "Zapisz wszystko"
toggleTheme = "Przełącz motyw"
toggleBookmarks = "Przełącz zakładki"
language = "Język"
toggleAnnotations = "Przełącz widoczność adnotacji"
search = "Szukaj w PDF"
panMode = "Tryb przesuwania"
rotateLeft = "Obróć w lewo"
rotateRight = "Obróć w prawo"
toggleSidebar = "Przełącz panel boczny"
toggleBookmarks = "Przełącz zakładki"
exportSelected = "Eksportuj wybrane strony"
toggleAnnotations = "Przełącz widoczność adnotacji"
annotationMode = "Przełącz tryb adnotacji"
print = "Drukuj PDF"
downloadAll = "Pobierz wszystko"
saveAll = "Zapisz wszystko"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Rysuj"
save = "Zapisz"
saveChanges = "Zapisz zmiany"
[search]
title = "Szukaj w PDF"
@@ -4205,20 +4038,12 @@ settings = "Ustaw."
adminSettings = "Ustaw. admina"
allTools = "All Tools"
reader = "Czytnik"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Przegląd narzędzi"
toolsTourDesc = "Dowiedz się, co potrafią narzędzia"
adminTour = "Przewodnik administratora"
adminTourDesc = "Poznaj ustawienia i funkcje administratora"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Błąd"
@@ -5244,7 +5069,6 @@ loading = "Wczytywanie..."
back = "Wstecz"
continue = "Kontynuuj"
error = "Błąd"
save = "Save"
[config.overview]
title = "Konfiguracja aplikacji"
@@ -5411,16 +5235,6 @@ finish = "Zakończ"
startTour = "Rozpocznij przewodnik"
startTourDescription = "Przewodnik po kluczowych funkcjach Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Witamy w Stirling PDF!"
description = "Chcesz odbyć krótką, minutową wycieczkę, aby poznać kluczowe funkcje i jak zacząć?"
@@ -5441,10 +5255,6 @@ download = "Pobierz →"
showMeAround = "Pokaż, co nowego"
skipTheTour = "Pomiń przewodnik"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Pomiń na razie"
seePlans = "Zobacz plany →"
@@ -5758,28 +5568,6 @@ contactSales = "Skontaktuj się ze sprzedażą"
contactToUpgrade = "Skontaktuj się z nami, aby uaktualnić lub dostosować plan"
maxUsers = "Maks. liczba użytkowników"
upTo = "Do"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "miesiąc"
@@ -5983,8 +5771,6 @@ notAvailable = "System audytu niedostępny"
notAvailableMessage = "System audytu nie jest skonfigurowany lub jest niedostępny."
disabled = "Rejestrowanie audytu jest wyłączone"
disabledMessage = "Włącz rejestrowanie audytu w konfiguracji aplikacji, aby śledzić zdarzenia systemowe."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Błąd podczas ładowania systemu audytu"
@@ -6239,8 +6025,6 @@ reset = "Resetuj zmiany"
downloadJson = "Pobierz JSON"
generatePdf = "Generuj PDF"
saveChanges = "Zapisz zmiany"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Automatycznie skaluj tekst do pól"
@@ -6259,24 +6043,6 @@ descriptionInline = "Wskazówka: Przytrzymaj Ctrl (Cmd) lub Shift, aby zaznaczy
title = "Zablokuj edytowany tekst do pojedynczego elementu PDF"
description = "Po włączeniu edytor eksportuje każde edytowane pole tekstowe jako jeden element tekstowy PDF, aby uniknąć nakładających się glifów lub mieszanych czcionek."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Scal zaznaczone pola"
merge = "Scal zaznaczenie"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avançado"
edit = "Visualizar & Editar"
popular = "Populares"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferências"
@@ -439,25 +435,6 @@ latestVersion = "Última versão"
checkForUpdates = "Verificar atualizações"
viewDetails = "Ver detalhes"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Atalhos de teclado"
description = "Personalize atalhos de teclado para acesso rápido às ferramentas. Clique em \"Alterar atalho\" e pressione uma nova combinação de teclas. Pressione Esc para cancelar."
@@ -511,16 +488,11 @@ low = "Baixa"
title = "Alterar Credenciais"
header = "Atualizar Detalhes da Conta"
changePassword = "Você está usando as credenciais padrões. Por favor, insira uma nova senha"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Novo Usuário"
oldPassword = "Senha Atual"
newPassword = "Senha Nova"
confirmNewPassword = "Confirme a Nova Senha"
submit = "Enviar Alterações"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Configurações da Conta"
@@ -736,11 +708,6 @@ tags = "assinatura,autógrafo"
title = "Assinar"
desc = "Adicionar assinatura ao PDF por desenho, texto ou imagem."
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplificar,remover,interativo"
title = "Achatar"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opções de CBZ para PDF"
optimizeForEbook = "Otimizar PDF para leitores de e-book (usa Ghostscript)"
cbzOutputOptions = "Opções de PDF para CBZ"
cbzDpi = "DPI para renderização de imagem"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversão,img,jpg,imagem,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Adicionar anexo"
remove = "Remover anexo"
embed = "Incorporar anexo"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Salvas"
label = "Enviar imagem da assinatura"
placeholder = "Selecionar arquivo de imagem"
hint = "Envie uma imagem PNG ou JPG da sua assinatura"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Como adicionar assinatura"
@@ -2408,11 +2351,6 @@ note = "Achatar remove elementos interativos do PDF, tornando-os não editáveis
label = "Achatar apenas formulários"
desc = "Achatar apenas campos de formulário, mantendo outros elementos interativos"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultados do achatamento"
@@ -2987,7 +2925,6 @@ header = "Recortar"
submit = "Enviar"
noFileSelected = "Selecione um arquivo PDF para iniciar o corte"
reset = "Redefinir para o PDF completo"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Seleção da área de corte"
@@ -3405,19 +3342,6 @@ placeholder = "Insira o número de divisões horizontais"
label = "Divisões Verticais:"
placeholder = "Insira o número de divisões verticais"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Carimbo,Adicionar imagem,centralizar imagem,Marca d'água,PDF,Incorporar,Personalizar"
header = "Adicionar Carimbo ao PDF"
@@ -3779,19 +3703,6 @@ filesize = "Tamanho do Arquivo"
[compress.grayscale]
label = "Aplicar escala de cinza para compressão"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Visão geral das configurações de compressão"
@@ -3809,10 +3720,6 @@ bullet2 = "Valores maiores reduzem o tamanho do arquivo"
title = "Tons de cinza"
text = "Selecione esta opção para converter todas as imagens para preto e branco, o que pode reduzir significativamente o tamanho do arquivo, especialmente para PDFs digitalizados ou documentos com muitas imagens."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Ocorreu um erro ao comprimir o PDF."
@@ -3825,11 +3732,6 @@ failed = "Ocorreu um erro ao comprimir o PDF."
_value = "Configurações de Compressão:"
1 = "1-3: Compressão do PDF,</br> 4-6: Compressão leve de Imagem,</br> 7-9: Compressão alta de Imagem. Redução considerável de qualidade da imagem."
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Este arquivo está protegido por senha. Insira a senha:"
cancelled = "Operação cancelada para PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Excluir páginas selecionadas"
closePdf = "Fechar PDF"
exportAll = "Exportar PDF"
downloadSelected = "Baixar arquivos selecionados"
annotations = "Annotations"
exportSelected = "Exportar páginas selecionadas"
saveChanges = "Salvar alterações"
downloadAll = "Baixar tudo"
saveAll = "Salvar tudo"
toggleTheme = "Alternar tema"
toggleBookmarks = "Alternar marcadores"
language = "Idioma"
toggleAnnotations = "Alternar visibilidade das anotações"
search = "Pesquisar PDF"
panMode = "Modo de panorâmica"
rotateLeft = "Girar à esquerda"
rotateRight = "Girar à direita"
toggleSidebar = "Alternar barra lateral"
toggleBookmarks = "Alternar marcadores"
exportSelected = "Exportar páginas selecionadas"
toggleAnnotations = "Alternar visibilidade das anotações"
annotationMode = "Alternar modo de anotação"
print = "Imprimir PDF"
downloadAll = "Baixar tudo"
saveAll = "Salvar tudo"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Desenhar"
save = "Salvar"
saveChanges = "Salvar alterações"
[search]
title = "Pesquisar PDF"
@@ -4205,20 +4038,12 @@ settings = "Ajustes"
adminSettings = "Ajustes admin"
allTools = "Ferram."
reader = "Leitor"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Tour das ferramentas"
toolsTourDesc = "Saiba o que as ferramentas podem fazer"
adminTour = "Tour do administrador"
adminTourDesc = "Explore configurações e recursos de administrador"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Erro"
@@ -5244,7 +5069,6 @@ loading = "Carregando..."
back = "Voltar"
continue = "Continuar"
error = "Erro"
save = "Save"
[config.overview]
title = "Configuração do aplicativo"
@@ -5411,16 +5235,6 @@ finish = "Concluir"
startTour = "Iniciar tour"
startTourDescription = "Faça um tour guiado pelos principais recursos do Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Bem-vindo ao Stirling PDF!"
description = "Gostaria de fazer um tour rápido de 1 minuto para aprender os recursos principais e como começar?"
@@ -5441,10 +5255,6 @@ download = "Baixar →"
showMeAround = "Me mostre por aí"
skipTheTour = "Pular o tour"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Pular por enquanto"
seePlans = "Ver planos →"
@@ -5758,28 +5568,6 @@ contactSales = "Falar com Vendas"
contactToUpgrade = "Entre em contato para fazer upgrade ou personalizar seu plano"
maxUsers = "Máximo de usuários"
upTo = "Até"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mês"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistema de auditoria não disponível"
notAvailableMessage = "O sistema de auditoria não está configurado ou não está disponível."
disabled = "O registro de auditoria está desativado"
disabledMessage = "Habilite o registro de auditoria na configuração do seu aplicativo para rastrear eventos do sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Erro ao carregar o sistema de auditoria"
@@ -6239,8 +6025,6 @@ reset = "Reverter alterações"
downloadJson = "Baixar JSON"
generatePdf = "Gerar PDF"
saveChanges = "Salvar alterações"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Dimensionar texto automaticamente para caber nas caixas"
@@ -6259,24 +6043,6 @@ descriptionInline = "Dica: Segure Ctrl (Cmd) ou Shift para selecionar várias ca
title = "Fixar texto editado em um único elemento PDF"
description = "Quando ativado, o editor exporta cada caixa de texto editada como um único elemento de texto PDF para evitar sobreposição de glifos ou fontes misturadas."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Mesclar caixas selecionadas"
merge = "Mesclar seleção"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avançado"
edit = "Ver & Editar"
popular = "Popular"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferências"
@@ -439,25 +435,6 @@ latestVersion = "Última versão"
checkForUpdates = "Procurar atualizações"
viewDetails = "Ver detalhes"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Atalhos de teclado"
description = "Personalize os atalhos de teclado para acesso rápido às ferramentas. Clique \"Alterar atalho\" e prima uma nova combinação de teclas. Prima Esc para cancelar."
@@ -511,16 +488,11 @@ low = "Baixa"
title = "Alterar Credenciais"
header = "Atualizar os Detalhes da sua Conta"
changePassword = "Está a usar credenciais de login padrão. Por favor insira uma nova palavra-passe"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Novo Nome de Utilizador"
oldPassword = "Palavra-passe Atual"
newPassword = "Nova Palavra-passe"
confirmNewPassword = "Confirmar Nova Palavra-passe"
submit = "Submeter Alterações"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Definições de Conta"
@@ -736,11 +708,6 @@ tags = "assinatura,autógrafo"
title = "Assinar"
desc = "Adiciona assinatura ao PDF por desenho, texto ou imagem"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplificar,remover,interativo"
title = "Achatar"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opções de CBZ para PDF"
optimizeForEbook = "Otimizar PDF para leitores de e-books (usa Ghostscript)"
cbzOutputOptions = "Opções de PDF para CBZ"
cbzDpi = "DPI para renderização de imagem"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversão,img,jpg,imagem,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Adicionar anexo"
remove = "Remover anexo"
embed = "Incorporar anexo"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Guardadas"
label = "Carregar imagem da assinatura"
placeholder = "Selecione ficheiro de imagem"
hint = "Carregue uma imagem PNG ou JPG da sua assinatura"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Como adicionar a assinatura"
@@ -2408,11 +2351,6 @@ note = "O aplanamento remove elementos interativos do PDF, tornandoos não ed
label = "Achatar apenas formulários"
desc = "Apenas aplanar campos de formulário, deixando outros elementos interativos intactos"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultados do Aplanamento"
@@ -2987,7 +2925,6 @@ header = "Recortar PDF"
submit = "Submeter"
noFileSelected = "Selecione um ficheiro PDF para começar a recortar"
reset = "Repor para PDF completo"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Seleção da área de recorte"
@@ -3405,19 +3342,6 @@ placeholder = "Introduza número de divisões horizontais"
label = "Divisões Verticais"
placeholder = "Introduza número de divisões verticais"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Carimbo, Adicionar imagem, imagem central, Marca de água, PDF, Incorporar, Personalizar"
header = "Carimbar PDF"
@@ -3779,19 +3703,6 @@ filesize = "Tamanho do Ficheiro"
[compress.grayscale]
label = "Aplicar escala de cinzentos para compressão"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Visão geral das definições de compressão"
@@ -3809,10 +3720,6 @@ bullet2 = "Valores mais altos reduzem o tamanho do ficheiro"
title = "Tons de cinzento"
text = "Selecione esta opção para converter todas as imagens para preto e branco, o que pode reduzir significativamente o tamanho do ficheiro, especialmente para PDFs digitalizados ou documentos com muitas imagens."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Ocorreu um erro ao comprimir o PDF."
@@ -3825,11 +3732,6 @@ failed = "Ocorreu um erro ao comprimir o PDF."
_value = "Definições de compressão"
1 = "1-3 compressão de PDF,</br> 4-6 compressão leve de imagem,</br> 7-9 compressão intensa de imagem irá reduzir drasticamente a qualidade da imagem"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Este ficheiro está protegido por palavra-passe. Por favor introduza a palavra-passe:"
cancelled = "Operação cancelada para PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Eliminar páginas selecionadas"
closePdf = "Fechar PDF"
exportAll = "Exportar PDF"
downloadSelected = "Transferir ficheiros selecionados"
annotations = "Annotations"
exportSelected = "Exportar páginas selecionadas"
saveChanges = "Guardar alterações"
downloadAll = "Transferir tudo"
saveAll = "Guardar tudo"
toggleTheme = "Alternar tema"
toggleBookmarks = "Alternar marcadores"
language = "Idioma"
toggleAnnotations = "Alternar visibilidade das anotações"
search = "Pesquisar PDF"
panMode = "Modo de deslocamento"
rotateLeft = "Rodar à esquerda"
rotateRight = "Rodar à direita"
toggleSidebar = "Alternar barra lateral"
toggleBookmarks = "Alternar marcadores"
exportSelected = "Exportar páginas selecionadas"
toggleAnnotations = "Alternar visibilidade das anotações"
annotationMode = "Alternar modo de anotação"
print = "Imprimir PDF"
downloadAll = "Transferir tudo"
saveAll = "Guardar tudo"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Desenhar"
save = "Guardar"
saveChanges = "Guardar alterações"
[search]
title = "Pesquisar PDF"
@@ -4205,20 +4038,12 @@ settings = "Ajustes"
adminSettings = "Ajustes admin"
allTools = "All Tools"
reader = "Leitor"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Visita guiada às ferramentas"
toolsTourDesc = "Saiba o que as ferramentas podem fazer"
adminTour = "Visita guiada de administração"
adminTourDesc = "Explore definições e funcionalidades de administração"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Erro"
@@ -5244,7 +5069,6 @@ loading = "A carregar..."
back = "Voltar"
continue = "Continuar"
error = "Erro"
save = "Save"
[config.overview]
title = "Configuração da aplicação"
@@ -5411,16 +5235,6 @@ finish = "Concluir"
startTour = "Iniciar visita"
startTourDescription = "Faça uma visita guiada às principais funcionalidades do Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Bem-vindo ao Stirling PDF!"
description = "Gostaria de fazer uma visita guiada de 1 minuto para conhecer as principais funcionalidades e como começar?"
@@ -5441,10 +5255,6 @@ download = "Transferir →"
showMeAround = "Mostre-me"
skipTheTour = "Saltar a visita guiada"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Saltar por agora"
seePlans = "Ver planos →"
@@ -5758,28 +5568,6 @@ contactSales = "Contactar Vendas"
contactToUpgrade = "Contacte-nos para atualizar ou personalizar o seu plano"
maxUsers = "Máximo de utilizadores"
upTo = "Até"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mês"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistema de auditoria não disponível"
notAvailableMessage = "O sistema de auditoria não está configurado ou não está disponível."
disabled = "Registo de auditoria desativado"
disabledMessage = "Ative o registo de auditoria na configuração da sua aplicação para rastrear eventos do sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Erro ao carregar o sistema de auditoria"
@@ -6239,8 +6025,6 @@ reset = "Repor alterações"
downloadJson = "Transferir JSON"
generatePdf = "Gerar PDF"
saveChanges = "Guardar alterações"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Dimensionar texto automaticamente para caber nas caixas"
@@ -6259,24 +6043,6 @@ descriptionInline = "Dica: Mantenha Ctrl (Cmd) ou Shift premido para selecionar
title = "Fixar texto editado a um único elemento PDF"
description = "Quando ativado, o editor exporta cada caixa de texto editada como um único elemento de texto PDF para evitar sobreposição de glifos ou mistura de fontes."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Unir caixas selecionadas"
merge = "Unir seleção"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avansat"
edit = "Vizualizează & Editează"
popular = "Populare"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferințe"
@@ -439,25 +435,6 @@ latestVersion = "Ultima versiune"
checkForUpdates = "Caută actualizări"
viewDetails = "Vezi detalii"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Scurtături de tastatură"
description = "Personalizați scurtăturile de tastatură pentru acces rapid la instrumente. Faceți clic pe \"Schimbă scurtătura\" și apăsați o nouă combinație de taste. Apăsați Esc pentru a anula."
@@ -511,16 +488,11 @@ low = "Scăzută"
title = "Schimbă Credențialele"
header = "Actualizează Detaliile Contului Tău"
changePassword = "Utilizezi credențiale de conectare implicite. Te rugăm să introduci o nouă parolă"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nume de Utilizator Nou"
oldPassword = "Parola Curentă"
newPassword = "Parolă Nouă"
confirmNewPassword = "Confirmă Parola Nouă"
submit = "Trimite Modificările"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Setări Cont"
@@ -736,11 +708,6 @@ tags = "semnătură,autograf"
title = "Semnează"
desc = "Adaugă o semnătură la documentul PDF prin desenare, text sau imagine."
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "simplifică,elimină,interactiv"
title = "Nivelare"
@@ -1278,21 +1245,6 @@ cbzOptions = "Opțiuni CBZ la PDF"
optimizeForEbook = "Optimizați PDF pentru e-readere (folosește Ghostscript)"
cbzOutputOptions = "Opțiuni PDF la CBZ"
cbzDpi = "DPI pentru randarea imaginilor"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "conversie,img,jpg,poză,fotografie"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Adaugă atașament"
remove = "Elimină atașament"
embed = "Încorporează atașament"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Salvate"
label = "Încarcă imaginea semnăturii"
placeholder = "Selectați fișierul imagine"
hint = "Încărcați o imagine PNG sau JPG a semnăturii dvs."
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Cum să adăugați semnătura"
@@ -2408,11 +2351,6 @@ note = "Aplatizarea elimină elementele interactive din PDF, făcându-le needit
label = "Nivelează doar formularele"
desc = "Aplatizează doar câmpurile de formular, lăsând celelalte elemente interactive intacte"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Rezultatele aplatizării"
@@ -2987,7 +2925,6 @@ header = "Decupează PDF"
submit = "Trimite"
noFileSelected = "Selectați un fișier PDF pentru a începe decuparea"
reset = "Resetează la PDF complet"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Selecție zonă de decupare"
@@ -3405,19 +3342,6 @@ placeholder = "Introdu numărul de diviziuni orizontale"
label = "Diviziuni Verticale"
placeholder = "Introdu numărul de diviziuni verticale"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Ștampilă, Adaugă imagine, centrează imagine, Filigran, PDF, Încorporează, Personalizează"
header = "Ștampilează PDF"
@@ -3779,19 +3703,6 @@ filesize = "Dimensiune Fișier"
[compress.grayscale]
label = "Aplicare scală de gri pentru compresie"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Prezentare generală a setărilor de comprimare"
@@ -3809,10 +3720,6 @@ bullet2 = "Valorile mai mari reduc dimensiunea fișierului"
title = "Nuanțe de gri"
text = "Selectați această opțiune pentru a converti toate imaginile în alb-negru, ceea ce poate reduce semnificativ dimensiunea fișierului, în special pentru PDF-uri scanate sau documente bogate în imagini."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "A apărut o eroare la comprimarea PDF-ului."
@@ -3825,11 +3732,6 @@ failed = "A apărut o eroare la comprimarea PDF-ului."
_value = "Setări de comprimare"
1 = "1-3 comprimare PDF,</br> 4-6 comprimare ușoară a imaginilor,</br> 7-9 comprimare intensă a imaginilor Va reduce semnificativ calitatea imaginilor"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Acest fișier este protejat cu parolă. Introduceți parola:"
cancelled = "Operațiune anulată pentru PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Ștergeți paginile selectate"
closePdf = "Închide PDF"
exportAll = "Exportați PDF"
downloadSelected = "Descărcați fișierele selectate"
annotations = "Annotations"
exportSelected = "Exportați paginile selectate"
saveChanges = "Salvați modificările"
downloadAll = "Descărcați tot"
saveAll = "Salvează tot"
toggleTheme = "Comutați tema"
toggleBookmarks = "Comută semnele de carte"
language = "Limbă"
toggleAnnotations = "Comutați vizibilitatea adnotărilor"
search = "Căutați în PDF"
panMode = "Mod panoramare"
rotateLeft = "Rotiți la stânga"
rotateRight = "Rotiți la dreapta"
toggleSidebar = "Comutați bara laterală"
toggleBookmarks = "Comută semnele de carte"
exportSelected = "Exportați paginile selectate"
toggleAnnotations = "Comutați vizibilitatea adnotărilor"
annotationMode = "Comutați modul de adnotare"
print = "Imprimați PDF"
downloadAll = "Descărcați tot"
saveAll = "Salvează tot"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Desenați"
save = "Salvați"
saveChanges = "Salvați modificările"
[search]
title = "Căutați în PDF"
@@ -4205,20 +4038,12 @@ settings = "Setări"
adminSettings = "Setări admin"
allTools = "All Tools"
reader = "Cititor"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Turul instrumentelor"
toolsTourDesc = "Aflați ce pot face instrumentele"
adminTour = "Turul de administrare"
adminTourDesc = "Explorați setările și funcțiile de administrare"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Eroare"
@@ -5244,7 +5069,6 @@ loading = "Se încarcă..."
back = "Înapoi"
continue = "Continuă"
error = "Eroare"
save = "Save"
[config.overview]
title = "Configurarea aplicației"
@@ -5411,16 +5235,6 @@ finish = "Finalizați"
startTour = "Porniți turul"
startTourDescription = "Faceți un tur ghidat al funcțiilor esențiale Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Bun venit la Stirling PDF!"
description = "Doriți să faceți un tur rapid de 1 minut pentru a afla funcțiile esențiale și cum să începeți?"
@@ -5441,10 +5255,6 @@ download = "Descarcă →"
showMeAround = "Arată-mi"
skipTheTour = "Sari peste tur"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Sari peste deocamdată"
seePlans = "Vezi planuri →"
@@ -5758,28 +5568,6 @@ contactSales = "Contactați vânzări"
contactToUpgrade = "Contactați-ne pentru a face upgrade sau a personaliza planul"
maxUsers = "Număr maxim de utilizatori"
upTo = "Până la"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "lună"
@@ -5983,8 +5771,6 @@ notAvailable = "Sistem de audit indisponibil"
notAvailableMessage = "Sistemul de audit nu este configurat sau nu este disponibil."
disabled = "Jurnalizarea de audit este dezactivată"
disabledMessage = "Activați jurnalizarea de audit în configurația aplicației pentru a urmări evenimentele sistemului."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Eroare la încărcarea sistemului de audit"
@@ -6239,8 +6025,6 @@ reset = "Resetați modificările"
downloadJson = "Descărcați JSON"
generatePdf = "Generați PDF"
saveChanges = "Salvează modificările"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Scalare automată a textului pentru a se potrivi în casete"
@@ -6259,24 +6043,6 @@ descriptionInline = "Sfat: Țineți apăsat Ctrl (Cmd) sau Shift pentru a select
title = "Blocați textul editat într-un singur element PDF"
description = "Când este activată, editorul exportă fiecare casetă de text editată ca un singur element de text PDF pentru a evita suprapunerea glifelor sau amestecul de fonturi."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Unește casetele selectate"
merge = "Unește selecția"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Расширенные"
edit = "Просмотр и редактирование"
popular = "Популярное"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Настройки"
@@ -439,25 +435,6 @@ latestVersion = "Последняя версия"
checkForUpdates = "Проверить обновления"
viewDetails = "Подробнее"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Горячие клавиши"
description = "Настройте горячие клавиши для быстрого доступа к инструментам. Нажмите «Изменить сочетание» и введите новую комбинацию клавиш. Нажмите Esc, чтобы отменить."
@@ -511,16 +488,11 @@ low = "Низкий"
title = "Изменить учетные данные"
header = "Обновить данные вашей учетной записи"
changePassword = "Вы используете стандартные учетные данные для входа. Пожалуйста, введите новый пароль"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Новое имя пользователя"
oldPassword = "Текущий пароль"
newPassword = "Новый пароль"
confirmNewPassword = "Подтвердите новый пароль"
submit = "Отправить изменения"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Настройки аккаунта"
@@ -736,11 +708,6 @@ tags = "подпись,автограф"
title = "Подпись"
desc = "Добавляет подпись в PDF рисованием, текстом или изображением"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "упростить,удалить,интерактив"
title = "Сведение"
@@ -1278,21 +1245,6 @@ cbzOptions = "Параметры CBZ → PDF"
optimizeForEbook = "Оптимизировать PDF для ридеров (использует Ghostscript)"
cbzOutputOptions = "Параметры PDF → CBZ"
cbzDpi = "DPI для отрисовки изображений"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "конвертация,изображение,jpg,картинка,фото"
@@ -1409,11 +1361,6 @@ header = "Добавлять вложения"
add = "Добавить вложение"
remove = "Удалить вложение"
embed = "Встроить вложение"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Добавлять вложения"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Сохранённое"
label = "Загрузить изображение подписи"
placeholder = "Выберите файл изображения"
hint = "Загрузите PNG или JPG с вашей подписью"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Как добавить подпись"
@@ -2408,11 +2351,6 @@ note = "Уплощение удаляет интерактивные элеме
label = "Сплющивать только формы"
desc = "Уплощать только поля форм, оставляя прочие интерактивные элементы"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Результаты уплощения"
@@ -2987,7 +2925,6 @@ header = "Обрезка PDF"
submit = "Отправить"
noFileSelected = "Выберите PDF-файл, чтобы начать обрезку"
reset = "Сбросить к полному PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Выбор области обрезки"
@@ -3405,19 +3342,6 @@ placeholder = "Введите количество горизонтальных
label = "Вертикальные разделы"
placeholder = "Введите количество вертикальных разделов"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Штамп,Добавить изображение,центрировать изображение,Водяной знак,PDF,Встраивание,Настройка"
header = "Штамп PDF"
@@ -3779,19 +3703,6 @@ filesize = "Размер файла"
[compress.grayscale]
label = "Применить шкалу серого для сжатия"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Обзор настроек сжатия"
@@ -3809,10 +3720,6 @@ bullet2 = "Высокие значения уменьшают размер фа
title = "Оттенки серого"
text = "Выберите эту опцию, чтобы преобразовать все изображения в чёрно-белые. Это может существенно уменьшить размер файла, особенно для отсканированных PDF или документов с большим количеством изображений."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Произошла ошибка при сжатии PDF."
@@ -3825,11 +3732,6 @@ failed = "Произошла ошибка при сжатии PDF."
_value = "Настройки сжатия"
1 = "1-3 сжатие PDF,</br> 4-6 лёгкое сжатие изображений,</br> 7-9 интенсивное сжатие изображений (значительно снижает качество изображений)"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Этот файл защищен паролем. Пожалуйста, введите пароль:"
cancelled = "Операция отменена для PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Удалить выбранные страницы"
closePdf = "Закрыть PDF"
exportAll = "Экспортировать PDF"
downloadSelected = "Скачать выбранные файлы"
annotations = "Annotations"
exportSelected = "Экспортировать выбранные страницы"
saveChanges = "Сохранить изменения"
downloadAll = "Скачать все"
saveAll = "Сохранить всё"
toggleTheme = "Переключить тему"
toggleBookmarks = "Показать/скрыть закладки"
language = "Язык"
toggleAnnotations = "Показать/скрыть аннотации"
search = "Поиск по PDF"
panMode = "Режим панорамирования"
rotateLeft = "Повернуть влево"
rotateRight = "Повернуть вправо"
toggleSidebar = "Показать/скрыть боковую панель"
toggleBookmarks = "Показать/скрыть закладки"
exportSelected = "Экспортировать выбранные страницы"
toggleAnnotations = "Показать/скрыть аннотации"
annotationMode = "Переключить режим аннотаций"
print = "Печать PDF"
downloadAll = "Скачать все"
saveAll = "Сохранить всё"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Рисовать"
save = "Сохранить"
saveChanges = "Сохранить изменения"
[search]
title = "Поиск по PDF"
@@ -4205,20 +4038,12 @@ settings = "Опции"
adminSettings = "Админ. настр."
allTools = "Инстр."
reader = "Читалка"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Обзор инструментов"
toolsTourDesc = "Узнайте, что умеют инструменты"
adminTour = "Обзор администрирования"
adminTourDesc = "Изучите настройки и функции администрирования"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Ошибка"
@@ -5244,7 +5069,6 @@ loading = "Загрузка..."
back = "Назад"
continue = "Продолжить"
error = "Ошибка"
save = "Save"
[config.overview]
title = "Конфигурация приложения"
@@ -5411,16 +5235,6 @@ finish = "Готово"
startTour = "Начать тур"
startTourDescription = "Пройдите ознакомительный тур по ключевым функциям Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Добро пожаловать в Stirling PDF!"
description = "Хотите пройти короткий 1‑минутный тур по ключевым функциям и началу работы?"
@@ -5441,10 +5255,6 @@ download = "Скачать →"
showMeAround = "Показать обзор"
skipTheTour = "Пропустить тур"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Пока пропустить"
seePlans = "Посмотреть тарифы →"
@@ -5758,28 +5568,6 @@ contactSales = "Связаться с отделом продаж"
contactToUpgrade = "Свяжитесь с нами, чтобы обновить или настроить ваш план"
maxUsers = "Максимум пользователей"
upTo = "До"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "месяц"
@@ -5983,8 +5771,6 @@ notAvailable = "Система аудита недоступна"
notAvailableMessage = "Система аудита не настроена или недоступна."
disabled = "Журнал аудита отключен"
disabledMessage = "Включите журнал аудита в конфигурации приложения, чтобы отслеживать события системы."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Ошибка загрузки системы аудита"
@@ -6239,8 +6025,6 @@ reset = "Сбросить изменения"
downloadJson = "Скачать JSON"
generatePdf = "Сформировать PDF"
saveChanges = "Сохранить изменения"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Автоматически подгонять текст по рамке"
@@ -6259,24 +6043,6 @@ descriptionInline = "Совет: удерживайте Ctrl (Cmd) или Shift
title = "Фиксировать отредактированный текст в одном элементе PDF"
description = "При включении редактор экспортирует каждый отредактированный блок как один элемент текста PDF, чтобы избежать наложений глифов или смешения шрифтов."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Объединить выбранные блоки"
merge = "Объединить выделение"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Pokročilé"
edit = "Zobraziť a upraviť"
popular = "Populárne"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Predvoľby"
@@ -439,25 +435,6 @@ latestVersion = "Najnovšia verzia"
checkForUpdates = "Skontrolovať aktualizácie"
viewDetails = "Zobraziť podrobnosti"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Klávesové skratky"
description = "Prispôsobte klávesové skratky pre rýchly prístup k nástrojom. Kliknite na \"Zmeniť skratku\" a stlačte novú kombináciu klávesov. Stlačením Esc zrušíte."
@@ -511,16 +488,11 @@ low = "Nízka"
title = "Zmeniť údaje"
header = "Aktualizujte údaje svojho účtu"
changePassword = "Používate predvolené prihlasovacie údaje. Prosím, zadajte nové heslo"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nové používateľské meno"
oldPassword = "Aktuálne heslo"
newPassword = "Nové heslo"
confirmNewPassword = "Potvrďte nové heslo"
submit = "Odoslať zmeny"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Nastavenia účtu"
@@ -736,11 +708,6 @@ tags = "podpis,podpísať"
title = "Podpísať"
desc = "Pridáva podpis do PDF kreslením, textom alebo obrázkom"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "zjednodušiť,odstrániť,interaktívne"
title = "Zploštiť"
@@ -1278,21 +1245,6 @@ cbzOptions = "Možnosti CBZ na PDF"
optimizeForEbook = "Optimalizovať PDF pre čítačky ekníh (používa Ghostscript)"
cbzOutputOptions = "Možnosti PDF na CBZ"
cbzDpi = "DPI pre vykresľovanie obrázkov"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konverzia,img,jpg,obrázok,fotografia"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Pridať prílohu"
remove = "Odstrániť prílohu"
embed = "Vložiť prílohu"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Uložené"
label = "Nahrať obrázok podpisu"
placeholder = "Vyberte súbor obrázka"
hint = "Nahrajte obrázok vášho podpisu vo formáte PNG alebo JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Ako pridať podpis"
@@ -2408,11 +2351,6 @@ note = "Sploštenie odstráni interaktívne prvky z PDF, čím ich spraví needi
label = "Zploštiť iba formuláre"
desc = "Sploštiť len polia formulára, ostatné interaktívne prvky ponechať"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Výsledky sploštenia"
@@ -2987,7 +2925,6 @@ header = "Orezať PDF"
submit = "Odoslať"
noFileSelected = "Vyberte súbor PDF a začnite orezávať"
reset = "Obnoviť na celé PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Výber oblasti orezania"
@@ -3405,19 +3342,6 @@ placeholder = "Zadajte počet horizontálnych delení"
label = "Vertikálne delenia"
placeholder = "Zadajte počet vertikálnych delení"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "pečiatka, pridať obrázok, stred obrázka, vodotlač, PDF, vložiť, prispôsobiť"
header = "Pečiatka PDF"
@@ -3779,19 +3703,6 @@ filesize = "Veľkosť súboru"
[compress.grayscale]
label = "Použiť odtiene šedej na kompresiu"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Prehľad nastavení kompresie"
@@ -3809,10 +3720,6 @@ bullet2 = "Vyššie hodnoty znižujú veľkosť súboru"
title = "Odtiene sivej"
text = "Vyberte túto možnosť na prevod všetkých obrázkov na čiernobiele, čo môže výrazne zmenšiť veľkosť súboru, najmä pri skenovaných PDF alebo dokumentoch s množstvom obrázkov."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Pri komprimovaní PDF došlo k chybe."
@@ -3825,11 +3732,6 @@ failed = "Pri komprimovaní PDF došlo k chybe."
_value = "Nastavenia kompresie"
1 = "13 kompresia PDF,</br> 46 mierna kompresia obrázkov,</br> 79 silná kompresia obrázkov výrazne zníži kvalitu obrázkov"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Tento súbor je chránený heslom. Zadajte heslo:"
cancelled = "Operácia zrušená pre PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Odstrániť vybrané strany"
closePdf = "Zavrieť PDF"
exportAll = "Exportovať PDF"
downloadSelected = "Stiahnuť vybrané súbory"
annotations = "Annotations"
exportSelected = "Exportovať vybrané strany"
saveChanges = "Uložiť zmeny"
downloadAll = "Stiahnuť všetko"
saveAll = "Uložiť všetko"
toggleTheme = "Prepnúť tému"
toggleBookmarks = "Prepnúť záložky"
language = "Jazyk"
toggleAnnotations = "Prepnúť zobrazenie anotácií"
search = "Hľadať v PDF"
panMode = "Režim posunu"
rotateLeft = "Otočiť doľava"
rotateRight = "Otočiť doprava"
toggleSidebar = "Prepnúť bočný panel"
toggleBookmarks = "Prepnúť záložky"
exportSelected = "Exportovať vybrané strany"
toggleAnnotations = "Prepnúť zobrazenie anotácií"
annotationMode = "Prepnúť režim anotácií"
print = "Vytlačiť PDF"
downloadAll = "Stiahnuť všetko"
saveAll = "Uložiť všetko"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Kresliť"
save = "Uložiť"
saveChanges = "Uložiť zmeny"
[search]
title = "Hľadať v PDF"
@@ -4205,20 +4038,12 @@ settings = "Nast."
adminSettings = "Admin nast."
allTools = "All Tools"
reader = "Čítačka"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Prehliadka nástrojov"
toolsTourDesc = "Zistite, čo nástroje dokážu"
adminTour = "Prehliadka administrácie"
adminTourDesc = "Preskúmajte administrátorské nastavenia a funkcie"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Chyba"
@@ -5244,7 +5069,6 @@ loading = "Načítava sa..."
back = "Späť"
continue = "Pokračovať"
error = "Chyba"
save = "Save"
[config.overview]
title = "Konfigurácia aplikácie"
@@ -5411,16 +5235,6 @@ finish = "Dokončiť"
startTour = "Spustiť prehliadku"
startTourDescription = "Prejdite si sprievodcu kľúčovými funkciami Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Vitajte v Stirling PDF!"
description = "Chceli by ste si prejsť rýchlu 1minútovú prehliadku kľúčových funkcií a ako začať?"
@@ -5441,10 +5255,6 @@ download = "Stiahnuť →"
showMeAround = "Ukážte mi to"
skipTheTour = "Preskočiť prehliadku"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Preskočiť zatiaľ"
seePlans = "Zobraziť plány →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontaktovať obchod"
contactToUpgrade = "Kontaktujte nás na inovovanie alebo prispôsobenie vášho plánu"
maxUsers = "Max. počet používateľov"
upTo = "Až do"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mesiac"
@@ -5983,8 +5771,6 @@ notAvailable = "Auditný systém nie je k dispozícii"
notAvailableMessage = "Auditný systém nie je nakonfigurovaný alebo nie je k dispozícii."
disabled = "Auditné protokolovanie je vypnuté"
disabledMessage = "Povolením auditného protokolovania v konfigurácii aplikácie môžete sledovať udalosti systému."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Chyba pri načítaní auditného systému"
@@ -6239,8 +6025,6 @@ reset = "Resetovať zmeny"
downloadJson = "Stiahnuť JSON"
generatePdf = "Vygenerovať PDF"
saveChanges = "Uložiť zmeny"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Automaticky prispôsobiť text do boxov"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tip: Podržte Ctrl (Cmd) alebo Shift na viacnásobný výbe
title = "Uzamknúť upravovaný text na jeden PDF prvok"
description = "Keď je zapnuté, editor exportuje každý upravený textový box ako jeden PDF textový prvok, aby sa predišlo prekrývaniu glyfov alebo miešaniu písiem."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Zlúčiť vybrané boxy"
merge = "Zlúčiť výber"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Napredno"
edit = "Ogled in urejanje"
popular = "Priljubljeno"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Nastavitve"
@@ -439,25 +435,6 @@ latestVersion = "Najnovejša različica"
checkForUpdates = "Preveri posodobitve"
viewDetails = "Poglej podrobnosti"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Bližnjice na tipkovnici"
description = "Prilagodite bližnjice na tipkovnici za hiter dostop do orodij. Kliknite \"Spremeni bližnjico\" in pritisnite novo kombinacijo tipk. Pritisnite Esc za preklic."
@@ -511,16 +488,11 @@ low = "Nizka"
title = "Spremeni poverilnice"
header = "Posodobite podrobnosti svojega računa"
changePassword = "Uporabljate privzete poverilnice za prijavo. Prosim vnesite novo geslo"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Novo uporabniško ime"
oldPassword = "Trenutno geslo"
newPassword = "Novo geslo"
confirmNewPassword = "Potrdi novo geslo"
submit = "Pošlji spremembe"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Nastavitve računa"
@@ -736,11 +708,6 @@ tags = "podpis,avtogram"
title = "Podpiši"
desc = "Doda podpis v PDF z risbo, besedilom ali sliko"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "poenostavi,odstrani,interaktivno"
title = "Zravnaj"
@@ -1278,21 +1245,6 @@ cbzOptions = "Možnosti CBZ v PDF"
optimizeForEbook = "Optimiziraj PDF za e-bralnike (uporablja Ghostscript)"
cbzOutputOptions = "Možnosti PDF v CBZ"
cbzDpi = "DPI za upodabljanje slik"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "pretvorba,img,jpg,slika,fotografija"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Dodaj prilogo"
remove = "Odstrani prilogo"
embed = "Vdelaj prilogo"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Shranjeno"
label = "Naložite sliko podpisa"
placeholder = "Izberite slikovno datoteko"
hint = "Naložite sliko podpisa v PNG ali JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Kako dodati podpis"
@@ -2408,11 +2351,6 @@ note = "Sploščanje odstrani interaktivne elemente iz PDF in jih naredi neurelj
label = "Splošči samo obrazce"
desc = "Splošči samo polja obrazcev in pusti druge interaktivne elemente nedotaknjene"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Rezultati sploščenja"
@@ -2987,7 +2925,6 @@ header = "Obreži PDF"
submit = "Pošlji"
noFileSelected = "Izberite datoteko PDF za začetek obrezovanja"
reset = "Ponastavi na celoten PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Izbira območja obrezovanja"
@@ -3405,19 +3342,6 @@ placeholder = "Vnesite število vodoravnih delitev"
label = "Navpične delitve"
placeholder = "Vnesite število navpičnih delitev"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Žig, Dodaj sliko, sredinska slika, Vodni žig, PDF, Vdelaj, Prilagodi, Prilagodi"
header = "Ožigosajte PDF"
@@ -3779,19 +3703,6 @@ filesize = "Velikost datoteke"
[compress.grayscale]
label = "Uporabi sivinsko lestvico za stiskanje"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Pregled nastavitev stiskanja"
@@ -3809,10 +3720,6 @@ bullet2 = "Višje vrednosti zmanjšajo velikost datoteke"
title = "Sivine"
text = "Izberite to možnost za pretvorbo vseh slik v črno-belo, kar lahko bistveno zmanjša velikost datoteke, zlasti pri skeniranih PDF-jih ali dokumentih s številnimi slikami."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Pri stiskanju PDF-ja je prišlo do napake."
@@ -3825,11 +3732,6 @@ failed = "Pri stiskanju PDF-ja je prišlo do napake."
_value = "Nastavitve stiskanja"
1 = "1-3 stiskanje PDF,</br> 4-6 enostavno stiskanje slik,</br> 7-9 intenzivno stiskanje slik Bo dramatično zmanjšalo kakovost slike"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ta datoteka je zaščitena z geslom. Prosim vnesite geslo:"
cancelled = "Operacija preklicana za PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Izbriši izbrane strani"
closePdf = "Zapri PDF"
exportAll = "Izvozi PDF"
downloadSelected = "Prenesi izbrane datoteke"
annotations = "Annotations"
exportSelected = "Izvozi izbrane strani"
saveChanges = "Shrani spremembe"
downloadAll = "Prenesi vse"
saveAll = "Shrani vse"
toggleTheme = "Preklopi temo"
toggleBookmarks = "Preklopi zaznamke"
language = "Jezik"
toggleAnnotations = "Preklopi vidnost opomb"
search = "Išči v PDF"
panMode = "Način premikanja"
rotateLeft = "Zavrti levo"
rotateRight = "Zavrti desno"
toggleSidebar = "Preklopi stransko vrstico"
toggleBookmarks = "Preklopi zaznamke"
exportSelected = "Izvozi izbrane strani"
toggleAnnotations = "Preklopi vidnost opomb"
annotationMode = "Preklopi način opomb"
print = "Natisni PDF"
downloadAll = "Prenesi vse"
saveAll = "Shrani vse"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Riši"
save = "Shrani"
saveChanges = "Shrani spremembe"
[search]
title = "Iskanje v PDF"
@@ -4205,20 +4038,12 @@ settings = "Možnosti"
adminSettings = "Skrbnik"
allTools = "All Tools"
reader = "Bralnik"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Ogled orodij"
toolsTourDesc = "Spoznajte, kaj zmorejo orodja"
adminTour = "Ogled za skrbnike"
adminTourDesc = "Raziščite skrbniške nastavitve in funkcije"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Napaka"
@@ -5244,7 +5069,6 @@ loading = "Nalaganje..."
back = "Nazaj"
continue = "Nadaljuj"
error = "Napaka"
save = "Save"
[config.overview]
title = "Konfiguracija aplikacije"
@@ -5411,16 +5235,6 @@ finish = "Dokončaj"
startTour = "Začni vodnik"
startTourDescription = "Opravite voden ogled ključnih funkcij Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Dobrodošli v Stirling PDF!"
description = "Bi želeli opraviti kratek 1-minutni vodnik, da spoznate ključne funkcije in kako začeti?"
@@ -5441,10 +5255,6 @@ download = "Prenesi →"
showMeAround = "Predstavi okolje"
skipTheTour = "Preskoči ogled"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Preskoči za zdaj"
seePlans = "Poglej načrte →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontaktirajte prodajo"
contactToUpgrade = "Kontaktirajte nas za nadgradnjo ali prilagoditev vašega paketa"
maxUsers = "Največ uporabnikov"
upTo = "Do"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mesec"
@@ -5983,8 +5771,6 @@ notAvailable = "Revizijski sistem ni na voljo"
notAvailableMessage = "Revizijski sistem ni konfiguriran ali ni na voljo."
disabled = "Revizijsko beleženje je onemogočeno"
disabledMessage = "Omogočite revizijsko beleženje v konfiguraciji vaše aplikacije za sledenje sistemskim dogodkom."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Napaka pri nalaganju revizijskega sistema"
@@ -6239,8 +6025,6 @@ reset = "Ponastavi spremembe"
downloadJson = "Prenesi JSON"
generatePdf = "Ustvari PDF"
saveChanges = "Shrani spremembe"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Samodejno prilagodi besedilo okvirjem"
@@ -6259,24 +6043,6 @@ descriptionInline = "Namig: Držite Ctrl (Cmd) ali Shift za večkratni izbor bes
title = "Zakleni urejeno besedilo na en sam element PDF"
description = "Ko je omogočeno, urejevalnik izvozi vsak urejen besedilni okvir kot en element besedila PDF, da se izogne prekrivanju znakov ali mešanim pisavam."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Združi izbrane okvirje"
merge = "Združi izbor"
@@ -340,10 +340,6 @@ advance = "Napredno"
edit = "Pregled i uređivanje"
popular = "Popularno"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferencije"
@@ -439,25 +435,6 @@ latestVersion = "Najnovija verzija"
checkForUpdates = "Proveri ažuriranja"
viewDetails = "Prikaži detalje"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Prečice na tastaturi"
description = "Prilagodite prečice na tastaturi za brz pristup alatima. Kliknite \"Promeni prečicu\" i pritisnite novu kombinaciju tastera. Pritisnite Esc za otkazivanje."
@@ -511,16 +488,11 @@ low = "Nizak"
title = "Promeni pristupne podatke"
header = "Ažurirajte detalje svog naloga"
changePassword = "Koristiš podrazumevane pristupne podatke. Molim te unesi novu lozinku"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Novo korisničko ime"
oldPassword = "Trenutna lozinka"
newPassword = "Nova lozinka"
confirmNewPassword = "Potvrdite novu lozinku"
submit = "Potvrdi promene"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Podešavanja naloga"
@@ -736,11 +708,6 @@ tags = "potpis,autogram"
title = "Potpis"
desc = "Dodaje potpis u PDF crtežom, tekstom ili slikom"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "pojednostavi,ukloni,interaktivno"
title = "Ravnanje"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ u PDF opcije"
optimizeForEbook = "Optimizuj PDF za čitače eknjiga (koristi Ghostscript)"
cbzOutputOptions = "PDF u CBZ opcije"
cbzDpi = "DPI za renderovanje slike"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konverzija,img,jpg,slika,foto"
@@ -1409,11 +1361,6 @@ header = "Dodaj priloge"
add = "Dodaj prilog"
remove = "Ukloni prilog"
embed = "Ugradi prilog"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Dodaj priloge"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Sačuvano"
label = "Otpremite sliku potpisa"
placeholder = "Izaberite slikovnu datoteku"
hint = "Otpremite PNG ili JPG sliku svog potpisa"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Kako dodati potpis"
@@ -2408,11 +2351,6 @@ note = "Ravnanje uklanja interaktivne elemente iz PDF-a, čineći ih neizmenjivi
label = "Izravnaj samo forme"
desc = "Ravnaj samo polja formulara, ostavljajući druge interaktivne elemente netaknutim"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Rezultati ravnanja"
@@ -2987,7 +2925,6 @@ header = "Skraćivanje PDF-a"
submit = "Potvrdi"
noFileSelected = "Izaberite PDF fajl da biste započeli isecanje"
reset = "Vrati na ceo PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Izbor oblasti za isecanje"
@@ -3405,19 +3342,6 @@ placeholder = "Unesite broj horizontalnih podele"
label = "Vertikalne podele"
placeholder = "Unesite broj vertikalnih podele"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stamp, Add image, center image, Watermark, PDF, Embed, Customize"
header = "Pečatiraj PDF"
@@ -3779,19 +3703,6 @@ filesize = "Veličina datoteke"
[compress.grayscale]
label = "Primeni sivinu za kompresiju"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Pregled podešavanja kompresije"
@@ -3809,10 +3720,6 @@ bullet2 = "Više vrednosti smanjuju veličinu fajla"
title = "Nijanse sive"
text = "Izaberite ovu opciju da konvertujete sve slike u crno-belo, što može značajno smanjiti veličinu fajla, posebno za skenirane PDF-ove ili dokumente sa mnogo slika."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Došlo je do greške prilikom kompresovanja PDF-a."
@@ -3825,11 +3732,6 @@ failed = "Došlo je do greške prilikom kompresovanja PDF-a."
_value = "Podešavanja kompresije"
1 = "1-3 PDF kompresija,</br> 4-6 blaga kompresija slika,</br> 7-9 intenzivna kompresija slika koja značajno smanjuje kvalitet slika"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Ova datoteka je zaštićena lozinkom. Unesi lozinku:"
cancelled = "Operacija otkazana za PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Obriši izabrane stranice"
closePdf = "Zatvori PDF"
exportAll = "Izvezi PDF"
downloadSelected = "Preuzmi izabrane fajlove"
annotations = "Annotations"
exportSelected = "Izvezi izabrane stranice"
saveChanges = "Sačuvaj izmene"
downloadAll = "Preuzmi sve"
saveAll = "Sačuvaj sve"
toggleTheme = "Uključi/isključi temu"
toggleBookmarks = "Prikaži/sakrij obeleživače"
language = "Jezik"
toggleAnnotations = "Uključi/isključi vidljivost anotacija"
search = "Pretraži PDF"
panMode = "Režim pomeranja"
rotateLeft = "Rotiraj ulevo"
rotateRight = "Rotiraj udesno"
toggleSidebar = "Uključi/isključi bočnu traku"
toggleBookmarks = "Prikaži/sakrij obeleživače"
exportSelected = "Izvezi izabrane stranice"
toggleAnnotations = "Uključi/isključi vidljivost anotacija"
annotationMode = "Uključi/isključi režim anotacija"
print = "Štampaj PDF"
downloadAll = "Preuzmi sve"
saveAll = "Sačuvaj sve"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Crtaj"
save = "Sačuvaj"
saveChanges = "Sačuvaj izmene"
[search]
title = "Pretraži PDF"
@@ -4205,20 +4038,12 @@ settings = "Postavke"
adminSettings = "Admin postavke"
allTools = "All Tools"
reader = "Čitač"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Obilazak alata"
toolsTourDesc = "Saznajte šta alati mogu da urade"
adminTour = "Administratorski obilazak"
adminTourDesc = "Istražite admin podešavanja i funkcije"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Greška"
@@ -5244,7 +5069,6 @@ loading = "Učitavanje..."
back = "Nazad"
continue = "Nastavi"
error = "Greška"
save = "Save"
[config.overview]
title = "Konfiguracija aplikacije"
@@ -5411,16 +5235,6 @@ finish = "Završi"
startTour = "Započni turu"
startTourDescription = "Krenite u vođenu turu kroz ključne funkcije Stirling PDF-a"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Dobrodošli u Stirling PDF!"
description = "Želite li brzu jedno-minutnu turu da naučite ključne funkcije i kako da počnete?"
@@ -5441,10 +5255,6 @@ download = "Preuzmi →"
showMeAround = "Provedi me kroz aplikaciju"
skipTheTour = "Preskoči obilazak"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Preskoči za sada"
seePlans = "Pogledajte planove →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontaktirajte prodaju"
contactToUpgrade = "Kontaktirajte nas za nadogradnju ili prilagođavanje vašeg paketa"
maxUsers = "Maks. broj korisnika"
upTo = "Do"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "mesec"
@@ -5983,8 +5771,6 @@ notAvailable = "Audit sistem nije dostupan"
notAvailableMessage = "Audit sistem nije podešen ili nije dostupan."
disabled = "Audit logovanje je onemogućeno"
disabledMessage = "Omogućite audit logovanje u konfiguraciji aplikacije da biste pratili događaje sistema."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Greška pri učitavanju audit sistema"
@@ -6239,8 +6025,6 @@ reset = "Poništi izmene"
downloadJson = "Preuzmi JSON"
generatePdf = "Generiši PDF"
saveChanges = "Sačuvajte izmene"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Automatski prilagodi tekst okvirima"
@@ -6259,24 +6043,6 @@ descriptionInline = "Savet: Držite Ctrl (Cmd) ili Shift za višestruki izbor te
title = "Zaključaj izmenjeni tekst u jedan PDF element"
description = "Kada je uključeno, editor izvozi svaki izmenjeni tekstualni okvir kao jedan PDF tekstualni element kako bi se izbeglo preklapanje glifova ili mešani fontovi."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Spoji izabrane okvire"
merge = "Spoji izbor"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Avancerat"
edit = "Visa & Redigera"
popular = "Populära"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Preferenser"
@@ -439,25 +435,6 @@ latestVersion = "Senaste version"
checkForUpdates = "Sök efter uppdateringar"
viewDetails = "Visa detaljer"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Kortkommandon"
description = "Anpassa kortkommandon för snabb åtkomst till verktyg. Klicka på \"Ändra genväg\" och tryck en ny tangentkombination. Tryck Esc för att avbryta."
@@ -511,16 +488,11 @@ low = "Låg"
title = "Ändra inloggningsuppgifter"
header = "Uppdatera dina kontouppgifter"
changePassword = "Du använder standardinloggningsuppgifter. Vänligen ange ett nytt lösenord"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Nytt användarnamn"
oldPassword = "Nuvarande lösenord"
newPassword = "Nytt lösenord"
confirmNewPassword = "Bekräfta nytt lösenord"
submit = "Skicka ändringar"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Kontoinställningar"
@@ -736,11 +708,6 @@ tags = "signatur,autograf"
title = "Signera"
desc = "Lägger till signatur till PDF genom ritning, text eller bild"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "förenkla,ta bort,interaktiv"
title = "Platta till"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ till PDFalternativ"
optimizeForEbook = "Optimera PDF för eboksläsare (använder Ghostscript)"
cbzOutputOptions = "PDF till CBZalternativ"
cbzDpi = "DPI för bildrendering"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "konvertering,img,jpg,bild,foto"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Lägg till bilaga"
remove = "Ta bort bilaga"
embed = "Bädda in bilaga"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Sparad"
label = "Ladda upp signaturbild"
placeholder = "Välj bildfil"
hint = "Ladda upp en PNG- eller JPG-bild av din signatur"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Så här lägger du till signatur"
@@ -2408,11 +2351,6 @@ note = "Utplattning tar bort interaktiva element från PDF:en, vilket gör dem i
label = "Platta till endast formulär"
desc = "Platta endast ut formulärfält, låt andra interaktiva element vara intakta"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Resultat för utplattning"
@@ -2987,7 +2925,6 @@ header = "Beskär PDF"
submit = "Skicka"
noFileSelected = "Välj en PDF-fil för att börja beskära"
reset = "Återställ till full PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Val av beskärningsområde"
@@ -3405,19 +3342,6 @@ placeholder = "Ange antal horisontella indelningar"
label = "Vertikala indelningar"
placeholder = "Ange antal vertikala indelningar"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Stämpel,Lägg till bild,centrera bild,Vattenstämpel,PDF,Bädda in,Anpassa"
header = "Stämpla PDF"
@@ -3779,19 +3703,6 @@ filesize = "Filstorlek"
[compress.grayscale]
label = "Tillämpa gråskala för komprimering"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Översikt över komprimeringsinställningar"
@@ -3809,10 +3720,6 @@ bullet2 = "Högre värden minskar filstorleken"
title = "Gråskala"
text = "Välj detta alternativ för att konvertera alla bilder till svartvitt, vilket kan minska filstorleken avsevärt, särskilt för skannade PDF:er eller bildtunga dokument."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Ett fel inträffade vid komprimering av PDF:en."
@@ -3825,11 +3732,6 @@ failed = "Ett fel inträffade vid komprimering av PDF:en."
_value = "Komprimeringsinställningar"
1 = "13 PDF-komprimering,</br> 46 lätt bildkomprimering,</br> 79 kraftig bildkomprimering Försämrar bildkvaliteten avsevärt"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Denna fil är lösenordsskyddad. Fyll i lösenord:"
cancelled = "Operation misslyckades för PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Ta bort markerade sidor"
closePdf = "Stäng PDF"
exportAll = "Exportera PDF"
downloadSelected = "Ladda ner markerade filer"
annotations = "Annotations"
exportSelected = "Exportera markerade sidor"
saveChanges = "Spara ändringar"
downloadAll = "Ladda ner alla"
saveAll = "Spara alla"
toggleTheme = "Växla tema"
toggleBookmarks = "Visa/dölj bokmärken"
language = "Språk"
toggleAnnotations = "Växla synlighet för anteckningar"
search = "Sök i PDF"
panMode = "Panoreringsläge"
rotateLeft = "Rotera åt vänster"
rotateRight = "Rotera åt höger"
toggleSidebar = "Växla sidofält"
toggleBookmarks = "Visa/dölj bokmärken"
exportSelected = "Exportera markerade sidor"
toggleAnnotations = "Växla synlighet för anteckningar"
annotationMode = "Växla anteckningsläge"
print = "Skriv ut PDF"
downloadAll = "Ladda ner alla"
saveAll = "Spara alla"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Rita"
save = "Spara"
saveChanges = "Spara ändringar"
[search]
title = "Sök i PDF"
@@ -4205,20 +4038,12 @@ settings = "Inst."
adminSettings = "Admin inst."
allTools = "All Tools"
reader = "Läsare"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Verktygsrundtur"
toolsTourDesc = "Lär dig vad verktygen kan göra"
adminTour = "Adminrundtur"
adminTourDesc = "Utforska admininställningar och funktioner"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Fel"
@@ -5244,7 +5069,6 @@ loading = "Läser in..."
back = "Tillbaka"
continue = "Fortsätt"
error = "Fel"
save = "Save"
[config.overview]
title = "Programkonfiguration"
@@ -5411,16 +5235,6 @@ finish = "Slutför"
startTour = "Starta rundtur"
startTourDescription = "Ta en guidad tur av Stirling PDFs nyckelfunktioner"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Välkommen till Stirling PDF!"
description = "Vill du ta en snabb 1-minutsrundtur för att lära dig nyckelfunktionerna och hur du kommer igång?"
@@ -5441,10 +5255,6 @@ download = "Ladda ner →"
showMeAround = "Visa mig runt"
skipTheTour = "Hoppa över rundturen"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Hoppa över nu"
seePlans = "Se planer →"
@@ -5758,28 +5568,6 @@ contactSales = "Kontakta sälj"
contactToUpgrade = "Kontakta oss för att uppgradera eller anpassa din plan"
maxUsers = "Max antal användare"
upTo = "Upp till"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "månad"
@@ -5983,8 +5771,6 @@ notAvailable = "Granskningssystemet är inte tillgängligt"
notAvailableMessage = "Granskningssystemet är inte konfigurerat eller inte tillgängligt."
disabled = "Granskningsloggning är inaktiverad"
disabledMessage = "Aktivera granskningsloggning i din applikationskonfiguration för att spåra systemhändelser."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Fel vid inläsning av granskningssystemet"
@@ -6239,8 +6025,6 @@ reset = "Återställ ändringar"
downloadJson = "Ladda ner JSON"
generatePdf = "Skapa PDF"
saveChanges = "Spara ändringar"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Skala text automatiskt för att passa rutor"
@@ -6259,24 +6043,6 @@ descriptionInline = "Tips: Håll Ctrl (Cmd) eller Shift för att markera flera t
title = "Lås redigerad text till ett enda PDF-element"
description = "När detta är aktiverat exporterar editorn varje redigerad textruta som ett PDF-textelement för att undvika överlappande tecken eller blandade typsnitt."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Slå ihop markerade textrutor"
merge = "Slå ihop markering"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "ขั้นสูง"
edit = "ดูและแก้ไข"
popular = "ยอดนิยม"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "ค่ากำหนด"
@@ -439,25 +435,6 @@ latestVersion = "เวอร์ชันล่าสุด"
checkForUpdates = "ตรวจสอบอัปเดต"
viewDetails = "ดูรายละเอียด"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "แป้นพิมพ์ลัด"
description = "ปรับแต่งแป้นพิมพ์ลัดเพื่อเข้าถึงเครื่องมือได้รวดเร็ว คลิก \"Change shortcut\" แล้วกดปุ่มลัดชุดใหม่ กด Esc เพื่อยกเลิก"
@@ -511,16 +488,11 @@ low = "ต่ำ"
title = "เปลี่ยนข้อมูลรับรอง"
header = "อัปเดตรายละเอียดบัญชีของคุณ"
changePassword = "คุณกำลังใช้ข้อมูลรับรองการเข้าสู่ระบบเริ่มต้น กรุณาใส่รหัสผ่านใหม่"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "ชื่อผู้ใช้ใหม่"
oldPassword = "รหัสผ่านปัจจุบัน"
newPassword = "รหัสผ่านใหม่"
confirmNewPassword = "ยืนยันรหัสผ่านใหม่"
submit = "ส่งการเปลี่ยนแปลง"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "การตั้งค่าบัญชี"
@@ -736,11 +708,6 @@ tags = "ลายเซ็น,ลงนาม"
title = "เซ็นชื่อ"
desc = "เพิ่มลายเซ็นลงใน PDF ด้วยการวาด ข้อความ หรือรูปภาพ"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "ทำให้เรียบ,ลบ,โต้ตอบ"
title = "แบน"
@@ -1278,21 +1245,6 @@ cbzOptions = "ตัวเลือก CBZ เป็น PDF"
optimizeForEbook = "ปรับ PDF ให้เหมาะกับเครื่องอ่าน ebook (ใช้ Ghostscript)"
cbzOutputOptions = "ตัวเลือก PDF เป็น CBZ"
cbzDpi = "DPI สำหรับการเรนเดอร์ภาพ"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "การแปลง, รูปภาพ, JPG, ภาพ, รูปถ่าย"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "เพิ่มไฟล์แนบ"
remove = "ลบไฟล์แนบ"
embed = "ฝังไฟล์แนบ"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "ที่บันทึกไว้"
label = "อัปโหลดภาพลายเซ็น"
placeholder = "เลือกไฟล์รูปภาพ"
hint = "อัปโหลดภาพลายเซ็นเป็น PNG หรือ JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "วิธีเพิ่มลายเซ็น"
@@ -2408,11 +2351,6 @@ note = "การทำให้แบนจะเอาองค์ประก
label = "แบนเฉพาะฟอร์ม"
desc = "ทำให้แบนเฉพาะช่องฟอร์ม โดยคงองค์ประกอบเชิงโต้ตอบอื่นไว้"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "ผลการทำให้แบน"
@@ -2987,7 +2925,6 @@ header = "ครอบตัด PDF"
submit = "ส่ง"
noFileSelected = "เลือกไฟล์ PDF เพื่อเริ่มการครอบตัด"
reset = "รีเซ็ตเป็น PDF เต็มหน้า"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "การเลือกพื้นที่ครอบตัด"
@@ -3405,19 +3342,6 @@ placeholder = "ป้อนจำนวนการแบ่งแนวนอ
label = "การแบ่งแนวตั้ง"
placeholder = "ป้อนจำนวนการแบ่งแนวตั้ง"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "ตราประทับ, เพิ่มรูปภาพ, รูปภาพกึ่งกลาง, ลายน้ำ, PDF, ฝัง, ปรับแต่ง"
header = "ตราประทับ PDF"
@@ -3779,19 +3703,6 @@ filesize = "ขนาดไฟล์"
[compress.grayscale]
label = "ใช้ระดับสีเทาสำหรับการบีบอัด"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "ภาพรวมการตั้งค่าการบีบอัด"
@@ -3809,10 +3720,6 @@ bullet2 = "ค่าสูงช่วยลดขนาดไฟล์ได้
title = "ภาพขาวดำ"
text = "เลือกตัวเลือกนี้เพื่อแปลงรูปภาพทั้งหมดเป็นขาวดำ ซึ่งช่วยลดขนาดไฟล์ได้มาก โดยเฉพาะสำหรับ PDF ที่สแกนหรือเอกสารที่มีภาพจำนวนมาก"
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "เกิดข้อผิดพลาดขณะบีบอัด PDF"
@@ -3825,11 +3732,6 @@ failed = "เกิดข้อผิดพลาดขณะบีบอัด
_value = "การตั้งค่าการบีบอัด"
1 = "1-3 บีบอัด PDF,</br> 4-6 บีบอัดรูปภาพแบบเบา,</br> 7-9 บีบอัดรูปภาพอย่างหนัก จะลดคุณภาพของภาพลงอย่างมาก"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "ไฟล์นี้มีการป้องกันด้วยรหัสผ่าน โปรดป้อนรหัสผ่าน:"
cancelled = "ยกเลิกการทำงานสำหรับ PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "ลบหน้าที่เลือก"
closePdf = "ปิด PDF"
exportAll = "ส่งออก PDF"
downloadSelected = "ดาวน์โหลดไฟล์ที่เลือก"
annotations = "Annotations"
exportSelected = "ส่งออกหน้าที่เลือก"
saveChanges = "บันทึกการเปลี่ยนแปลง"
downloadAll = "ดาวน์โหลดทั้งหมด"
saveAll = "บันทึกทั้งหมด"
toggleTheme = "สลับธีม"
toggleBookmarks = "สลับที่คั่นหน้า"
language = "ภาษา"
toggleAnnotations = "สลับการแสดงคำอธิบายประกอบ"
search = "ค้นหาใน PDF"
panMode = "โหมดเลื่อนดู"
rotateLeft = "หมุนซ้าย"
rotateRight = "หมุนขวา"
toggleSidebar = "สลับแถบข้าง"
toggleBookmarks = "สลับที่คั่นหน้า"
exportSelected = "ส่งออกหน้าที่เลือก"
toggleAnnotations = "สลับการแสดงคำอธิบายประกอบ"
annotationMode = "สลับโหมดคำอธิบายประกอบ"
print = "พิมพ์ PDF"
downloadAll = "ดาวน์โหลดทั้งหมด"
saveAll = "บันทึกทั้งหมด"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "วาด"
save = "บันทึก"
saveChanges = "บันทึกการเปลี่ยนแปลง"
[search]
title = "ค้นหาใน PDF"
@@ -4205,20 +4038,12 @@ settings = "ตั้งค่า"
adminSettings = "ตั้งค่า แอดมิน"
allTools = "All Tools"
reader = "ตัวอ่าน"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "แนะนำเครื่องมือ"
toolsTourDesc = "เรียนรู้ว่าเครื่องมือทำอะไรได้บ้าง"
adminTour = "ทัวร์ผู้ดูแล"
adminTourDesc = "สำรวจการตั้งค่าและฟีเจอร์ของผู้ดูแล"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "ข้อผิดพลาด"
@@ -5244,7 +5069,6 @@ loading = "กำลังโหลด..."
back = "ย้อนกลับ"
continue = "ดำเนินการต่อ"
error = "ข้อผิดพลาด"
save = "Save"
[config.overview]
title = "การกำหนดค่าแอปพลิเคชัน"
@@ -5411,16 +5235,6 @@ finish = "เสร็จสิ้น"
startTour = "เริ่มทัวร์"
startTourDescription = "ทัวร์แนะนำฟีเจอร์สำคัญของ Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "ยินดีต้อนรับสู่ Stirling PDF!"
description = "ต้องการทัวร์ด่วน 1 นาทีเพื่อเรียนรู้ฟีเจอร์สำคัญและวิธีเริ่มต้นหรือไม่"
@@ -5441,10 +5255,6 @@ download = "ดาวน์โหลด →"
showMeAround = "พาชมรอบๆ"
skipTheTour = "ข้ามทัวร์"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "ข้ามไปก่อน"
seePlans = "ดูแพ็กเกจ →"
@@ -5758,28 +5568,6 @@ contactSales = "ติดต่อฝ่ายขาย"
contactToUpgrade = "ติดต่อเราเพื่ออัปเกรดหรือปรับแต่งแผนของคุณ"
maxUsers = "ผู้ใช้สูงสุด"
upTo = "สูงสุด"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "เดือน"
@@ -5983,8 +5771,6 @@ notAvailable = "ระบบบันทึกการตรวจสอบไ
notAvailableMessage = "ระบบบันทึกการตรวจสอบยังไม่ได้กำหนดค่าหรือไม่พร้อมใช้งาน"
disabled = "การบันทึกการตรวจสอบถูกปิดใช้งาน"
disabledMessage = "เปิดใช้การบันทึกการตรวจสอบในการกำหนดค่าแอปพลิเคชันของคุณเพื่อการติดตามเหตุการณ์ของระบบ"
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "เกิดข้อผิดพลาดในการโหลดระบบบันทึกการตรวจสอบ"
@@ -6239,8 +6025,6 @@ reset = "รีเซ็ตการเปลี่ยนแปลง"
downloadJson = "ดาวน์โหลด JSON"
generatePdf = "สร้าง PDF"
saveChanges = "บันทึกการเปลี่ยนแปลง"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "ปรับขนาดข้อความอัตโนมัติให้พอดีกล่อง"
@@ -6259,24 +6043,6 @@ descriptionInline = "เคล็ดลับ: กดค้าง Ctrl (Cmd) ห
title = "ล็อกข้อความที่แก้ไขเป็นองค์ประกอบ PDF เดียว"
description = "เมื่อเปิดใช้ เครื่องมือจะส่งออกแต่ละกล่องข้อความที่แก้ไขเป็นองค์ประกอบข้อความ PDF เดียว เพื่อหลีกเลี่ยงอักขระซ้อนทับหรือฟอนต์ปะปน"
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "รวมกล่องที่เลือก"
merge = "รวมที่เลือก"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Gelişmiş"
edit = "Görüntüle ve Düzenle"
popular = "Popüler"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Tercihler"
@@ -439,25 +435,6 @@ latestVersion = "En Son Sürüm"
checkForUpdates = "Güncellemeleri Kontrol Et"
viewDetails = "Ayrıntıları Görüntüle"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Klavye Kısayolları"
description = "Araçlara hızlı erişim için klavye kısayollarını özelleştirin. \"Kısayolu değiştir\"e tıklayın ve yeni bir tuş kombinasyonuna basın. İptal etmek için Esc'ye basın."
@@ -511,16 +488,11 @@ low = "Düşük"
title = "Giriş Bilgilerini Değiştir"
header = "Hesap Detaylarınızı Güncelleyin"
changePassword = "Varsayılan giriş bilgilerini kullanıyorsunuz. Lütfen yeni bir şifre girin."
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Yeni Kullanıcı Adı"
oldPassword = "Mevcut Şifre"
newPassword = "Yeni Şifre"
confirmNewPassword = "Yeni Şifreyi Onayla"
submit = "Değişiklikleri Gönder"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Hesap Ayarları"
@@ -736,11 +708,6 @@ tags = "imza,imzala"
title = "İmzala"
desc = "Çizim, metin veya resim ile PDF'e imza ekler"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "basitleştir,kaldır,etkileşimli"
title = "Düzleştir"
@@ -1278,21 +1245,6 @@ cbzOptions = "CBZ'den PDF'e Seçenekleri"
optimizeForEbook = "PDF'yi e-kitap okuyucular için optimize et (Ghostscript kullanır)"
cbzOutputOptions = "PDF'den CBZ'ye Seçenekleri"
cbzDpi = "Görüntü oluşturma için DPI"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "dönüşüm,img,jpg,fotoğraf,resim"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Ek Ekle"
remove = "Eki Kaldır"
embed = "Eki Göm"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Kaydedildi"
label = "İmza görseli yükle"
placeholder = "Görsel dosyası seç"
hint = "İmzanızın PNG veya JPG görselini yükleyin"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "İmza nasıl eklenir"
@@ -2408,11 +2351,6 @@ note = "Düzleştirme, PDF'den etkileşimli öğeleri kaldırır ve düzenleneme
label = "Yalnızca formları düzleştir"
desc = "Yalnızca form alanlarını düzleştir, diğer etkileşimli öğeleri olduğu gibi bırak"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Düzleştirme Sonuçları"
@@ -2987,7 +2925,6 @@ header = "PDF'i Kırp"
submit = "Gönder"
noFileSelected = "Kırpmaya başlamak için bir PDF seçin"
reset = "Tam PDF'ye sıfırla"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Kırpma Alanı Seçimi"
@@ -3405,19 +3342,6 @@ placeholder = "Yatay bölme sayısını girin"
label = "Dikey Bölümler"
placeholder = "Dikey bölme sayısını girin"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Damga, Görüntü ekle, Görüntüyü ortala, Filigran, PDF, Göm, Özelleştir"
header = "Damga PDF"
@@ -3779,19 +3703,6 @@ filesize = "Dosya Boyutu"
[compress.grayscale]
label = "Sıkıştırma için Gri Ton Uygula"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Sıkıştırma Ayarlarına Genel Bakış"
@@ -3809,10 +3720,6 @@ bullet2 = "Yüksek değerler dosya boyutunu azaltır"
title = "Gri Tonlama"
text = "Tüm görselleri siyah beyaza dönüştürmek için bu seçeneği belirleyin; özellikle taranmış PDF'ler veya görsel ağırlıklı belgeler için dosya boyutunu önemli ölçüde azaltabilir."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "PDF sıkıştırılırken bir hata oluştu."
@@ -3825,11 +3732,6 @@ failed = "PDF sıkıştırılırken bir hata oluştu."
_value = "Sıkıştırma Ayarları"
1 = "1-3 PDF sıkıştırma,</br> 4-6 hafif görüntü sıkıştırma,</br> 7-9 yoğun görüntü sıkıştırma görüntü kalitesini ciddi ölçüde düşürür"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Bu dosya parola korumalı. Lütfen parolayı girin:"
cancelled = "PDF için işlem iptal edildi: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Seçilen Sayfaları Sil"
closePdf = "PDF'yi Kapat"
exportAll = "PDF'yi Dışa Aktar"
downloadSelected = "Seçilen Dosyaları İndir"
annotations = "Annotations"
exportSelected = "Seçilen Sayfaları Dışa Aktar"
saveChanges = "Değişiklikleri Kaydet"
downloadAll = "Tümünü İndir"
saveAll = "Tümünü Kaydet"
toggleTheme = "Temayı Değiştir"
toggleBookmarks = "Yer imlerini aç/kapat"
language = "Dil"
toggleAnnotations = "Açıklamaların Görünürlüğünü Değiştir"
search = "PDF Ara"
panMode = "Kaydırma Modu"
rotateLeft = "Sola Döndür"
rotateRight = "Sağa Döndür"
toggleSidebar = "Kenar Çubuğunu Aç/Kapat"
toggleBookmarks = "Yer imlerini aç/kapat"
exportSelected = "Seçilen Sayfaları Dışa Aktar"
toggleAnnotations = "Açıklamaların Görünürlüğünü Değiştir"
annotationMode = "Açıklama Modunu Değiştir"
print = "PDF'yi Yazdır"
downloadAll = "Tümünü İndir"
saveAll = "Tümünü Kaydet"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Çiz"
save = "Kaydet"
saveChanges = "Değişiklikleri Kaydet"
[search]
title = "PDF Ara"
@@ -4205,20 +4038,12 @@ settings = "Ayarlar"
adminSettings = "Admin Ayarları"
allTools = "All Tools"
reader = "Okuyucu"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Araç Turu"
toolsTourDesc = "Araçların neler yapabildiğini öğrenin"
adminTour = "Yönetici Turu"
adminTourDesc = "Yönetici ayarlarını ve özelliklerini keşfedin"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Hata"
@@ -5244,7 +5069,6 @@ loading = "Yükleniyor..."
back = "Geri"
continue = "Devam et"
error = "Hata"
save = "Save"
[config.overview]
title = "Uygulama Yapılandırması"
@@ -5411,16 +5235,6 @@ finish = "Bitir"
startTour = "Turu Başlat"
startTourDescription = "Stirling PDF'in temel özelliklerinde rehberli bir tura çıkın"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Stirling PDF'ye Hoş Geldiniz!"
description = "Ana özellikleri ve nasıl başlayacağınızı öğrenmek için 1 dakikalık hızlı bir tura çıkmak ister misiniz?"
@@ -5441,10 +5255,6 @@ download = "İndir →"
showMeAround = "Bana etrafı göster"
skipTheTour = "Turu atla"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Şimdilik atla"
seePlans = "Planlara Bak →"
@@ -5758,28 +5568,6 @@ contactSales = "Satış ile İletişime Geçin"
contactToUpgrade = "Planınızı yükseltmek veya özelleştirmek için bizimle iletişime geçin"
maxUsers = "Maksimum Kullanıcı"
upTo = "En fazla"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "ay"
@@ -5983,8 +5771,6 @@ notAvailable = "Denetim sistemi kullanılamıyor"
notAvailableMessage = "Denetim sistemi yapılandırılmamış veya kullanılamıyor."
disabled = "Denetim günlüğü devre dışı"
disabledMessage = "Sistem olaylarını takip etmek için uygulama yapılandırmanızda denetim günlüğünü etkinleştirin."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Denetim sistemi yüklenirken hata"
@@ -6239,8 +6025,6 @@ reset = "Değişiklikleri Sıfırla"
downloadJson = "JSON'u İndir"
generatePdf = "PDF Oluştur"
saveChanges = "Değişiklikleri Kaydet"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Metni kutulara otomatik sığdır"
@@ -6259,24 +6043,6 @@ descriptionInline = "İpucu: Birden çok metin kutusu seçmek için Ctrl (Cmd) v
title = "Düzenlenen metni tek bir PDF öğesine kilitle"
description = "Etkinleştirildiğinde, düzenlenmiş her metin kutusu, üst üste binen glifler veya karışık yazı tiplerini önlemek için tek bir PDF metin öğesi olarak dışa aktarılır."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Seçili kutuları birleştir"
merge = "Seçimi birleştir"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Додаткове"
edit = "Перегляд та Редагування"
popular = "Популярне"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Параметри"
@@ -439,25 +435,6 @@ latestVersion = "Остання версія"
checkForUpdates = "Перевірити оновлення"
viewDetails = "Переглянути деталі"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Комбінації клавіш"
description = "Налаштуйте комбінації клавіш для швидкого доступу до інструментів. Клацніть \"Change shortcut\" і натисніть нову комбінацію клавіш. Натисніть Esc, щоб скасувати."
@@ -511,16 +488,11 @@ low = "Низький"
title = "Змінити облікові дані"
header = "Оновіть дані вашого облікового запису"
changePassword = "Ви використовуєте заводські облікові дані для входу. Будь ласка, введіть новий пароль"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Нове ім'я користувача"
oldPassword = "Поточний пароль"
newPassword = "Новий пароль"
confirmNewPassword = "Підтвердіть новий пароль"
submit = "Надіслати зміни"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Налаштування акаунта"
@@ -736,11 +708,6 @@ tags = "підпис,автограф"
title = "Підпис"
desc = "Додає підпис до PDF за допомогою малюнка, тексту або зображення"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "спростити,прибрати,інтерактивність"
title = "Знеактивування"
@@ -1278,21 +1245,6 @@ cbzOptions = "Параметри CBZ у PDF"
optimizeForEbook = "Оптимізувати PDF для рідерів електронних книг (використовує Ghostscript)"
cbzOutputOptions = "Параметри PDF у CBZ"
cbzDpi = "DPI для рендерингу зображень"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "конвертація,зображення,jpg,картинка,фото"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Додати вкладення"
remove = "Видалити вкладення"
embed = "Вбудувати вкладення"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Збережені"
label = "Завантажити зображення підпису"
placeholder = "Виберіть файл зображення"
hint = "Завантажте зображення підпису у форматі PNG або JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Як додати підпис"
@@ -2408,11 +2351,6 @@ note = "Сплющення видаляє інтерактивні елемен
label = "Згладити тільки форми"
desc = "Сплющувати лише поля форм, залишивши інші інтерактивні елементи без змін"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Результати сплющення"
@@ -2987,7 +2925,6 @@ header = "Обрізати PDF-файл"
submit = "Надіслати"
noFileSelected = "Виберіть PDF, щоб почати обрізання"
reset = "Скинути до повного PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Вибір області обрізки"
@@ -3405,19 +3342,6 @@ placeholder = "Введіть кількість горизонтальних р
label = "Вертикальні розділи"
placeholder = "Введіть кількість вертикальних розділів"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "штамп,додати зображення,центральне зображення,водяний знак,pdf,вставити,налаштувати"
header = "Поставити печатку на PDF"
@@ -3779,19 +3703,6 @@ filesize = "Розмір файлу"
[compress.grayscale]
label = "Застосувати відтінки сірого для стиснення"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Огляд налаштувань стиснення"
@@ -3809,10 +3720,6 @@ bullet2 = "Вищі значення зменшують розмір файлу"
title = "Відтінки сірого"
text = "Увімкніть цю опцію, щоб перетворити всі зображення в чорно-білі, що може суттєво зменшити розмір файлу, особливо для відсканованих PDF або документів із великою кількістю зображень."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Під час стиснення PDF сталася помилка."
@@ -3825,11 +3732,6 @@ failed = "Під час стиснення PDF сталася помилка."
_value = "Параметри стиснення"
1 = "1-3 стиснення PDF,</br> 4-6 невелике стиснення зображень,</br> 7-9 посилене стиснення зображень (різко знизить якість зображень)"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Цей файл захищений паролем. Будь ласка, введіть пароль:"
cancelled = "Операцію скасовано для PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Видалити вибрані сторінки"
closePdf = "Закрити PDF"
exportAll = "Експорт PDF"
downloadSelected = "Завантажити вибрані файли"
annotations = "Annotations"
exportSelected = "Експорт вибраних сторінок"
saveChanges = "Зберегти зміни"
downloadAll = "Завантажити все"
saveAll = "Зберегти все"
toggleTheme = "Перемкнути тему"
toggleBookmarks = "Перемкнути закладки"
language = "Мова"
toggleAnnotations = "Перемкнути видимість анотацій"
search = "Пошук у PDF"
panMode = "Режим переміщення"
rotateLeft = "Повернути ліворуч"
rotateRight = "Повернути праворуч"
toggleSidebar = "Перемкнути бічну панель"
toggleBookmarks = "Перемкнути закладки"
exportSelected = "Експорт вибраних сторінок"
toggleAnnotations = "Перемкнути видимість анотацій"
annotationMode = "Перемкнути режим анотацій"
print = "Надрукувати PDF"
downloadAll = "Завантажити все"
saveAll = "Зберегти все"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Малювати"
save = "Зберегти"
saveChanges = "Зберегти зміни"
[search]
title = "Пошук у PDF"
@@ -4205,20 +4038,12 @@ settings = "Налашт."
adminSettings = "Налашт. адміна"
allTools = "All Tools"
reader = "Перегляд"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Огляд інструментів"
toolsTourDesc = "Дізнайтеся, що вміють інструменти"
adminTour = "Огляд адміністратора"
adminTourDesc = "Ознайомтеся з адміністраторськими налаштуваннями та функціями"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Помилка"
@@ -5244,7 +5069,6 @@ loading = "Завантаження..."
back = "Назад"
continue = "Продовжити"
error = "Помилка"
save = "Save"
[config.overview]
title = "Конфігурація застосунку"
@@ -5411,16 +5235,6 @@ finish = "Готово"
startTour = "Почати тур"
startTourDescription = "Пройдіть покрокову екскурсію ключовими можливостями Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Ласкаво просимо до Stirling PDF!"
description = "Бажаєте пройти коротку 1‑хвилинну екскурсію, щоб дізнатися про ключові можливості та як почати?"
@@ -5441,10 +5255,6 @@ download = "Завантажити →"
showMeAround = "Проведіть екскурсію"
skipTheTour = "Пропустити тур"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Пропустити зараз"
seePlans = "Переглянути плани →"
@@ -5758,28 +5568,6 @@ contactSales = "Зв’язатися з відділом продажу"
contactToUpgrade = "Зв’яжіться з нами, щоб оновити або налаштувати свій план"
maxUsers = "Максимум користувачів"
upTo = "До"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "місяць"
@@ -5983,8 +5771,6 @@ notAvailable = "Система аудиту недоступна"
notAvailableMessage = "Система аудиту не налаштована або недоступна."
disabled = "Ведення журналу аудиту вимкнено"
disabledMessage = "Увімкніть ведення журналу аудиту в конфігурації застосунку, щоб відстежувати події системи."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Помилка завантаження системи аудиту"
@@ -6239,8 +6025,6 @@ reset = "Скинути зміни"
downloadJson = "Завантажити JSON"
generatePdf = "Згенерувати PDF"
saveChanges = "Зберегти зміни"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Автопідгін тексту під рамки"
@@ -6259,24 +6043,6 @@ descriptionInline = "Порада: утримуйте Ctrl (Cmd) або Shift д
title = "Фіксувати відредагований текст в одному елементі PDF"
description = "Якщо ввімкнено, редактор експортує кожен відредагований текстовий блок як один елемент тексту PDF, щоб уникнути перекриття гліфів чи змішаних шрифтів."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Об’єднати вибрані блоки"
merge = "Об’єднати вибране"
+9 -243
View File
@@ -340,10 +340,6 @@ advance = "Nâng cao"
edit = "Xem & Chỉnh sửa"
popular = "Phổ biến"
[footer]
discord = "Discord"
issues = "GitHub"
[settings.preferences]
title = "Tùy chọn"
@@ -439,25 +435,6 @@ latestVersion = "Phiên bản mới nhất"
checkForUpdates = "Kiểm tra cập nhật"
viewDetails = "Xem chi tiết"
[settings.security]
title = "Security"
description = "Update your password to keep your account secure."
[settings.security.password]
subtitle = "Change your password. You will be logged out after updating."
required = "All fields are required."
mismatch = "New passwords do not match."
error = "Unable to update password. Please verify your current password and try again."
success = "Password updated successfully. Please sign in again."
ssoDisabled = "Password changes are managed by your identity provider."
current = "Current password"
currentPlaceholder = "Enter your current password"
new = "New password"
newPlaceholder = "Enter a new password"
confirm = "Confirm new password"
confirmPlaceholder = "Re-enter your new password"
update = "Update password"
[settings.hotkeys]
title = "Phím tắt"
description = "Tùy chỉnh phím tắt để truy cập công cụ nhanh. Nhấp \"Change shortcut\" và nhấn một tổ hợp phím mới. Nhấn Esc để hủy."
@@ -511,16 +488,11 @@ low = "Thấp"
title = "Thay đổi thông tin đăng nhập"
header = "Cập nhật thông tin tài khoản của bạn"
changePassword = "Bạn đang sử dụng thông tin đăng nhập mặc định. Vui lòng nhập mật khẩu mới"
ssoManaged = "Your account is managed by your identity provider."
newUsername = "Tên người dùng mới"
oldPassword = "Mật khẩu hiện tại"
newPassword = "Mật khẩu mới"
confirmNewPassword = "Xác nhận mật khẩu mới"
submit = "Gửi thay đổi"
credsUpdated = "Account updated"
description = "Changes saved. Please log in again."
error = "Unable to update username. Please verify your password and try again."
changeUsername = "Update your username. You will be logged out after updating."
[account]
title = "Cài đặt tài khoản"
@@ -736,11 +708,6 @@ tags = "chữ ký,chữ ký tay"
title = "Ký"
desc = "Thêm chữ ký vào PDF bằng cách vẽ, văn bản hoặc hình ảnh"
[home.annotate]
tags = "annotate,highlight,draw"
title = "Annotate"
desc = "Highlight, draw, add notes and shapes in the viewer"
[home.flatten]
tags = "làm phẳng,loại bỏ,tương tác"
title = "Làm phẳng"
@@ -1278,21 +1245,6 @@ cbzOptions = "Tùy chọn CBZ sang PDF"
optimizeForEbook = "Tối ưu PDF cho thiết bị đọc sách điện tử (dùng Ghostscript)"
cbzOutputOptions = "Tùy chọn PDF sang CBZ"
cbzDpi = "DPI cho kết xuất ảnh"
cbrOptions = "CBR Options"
cbrOutputOptions = "PDF to CBR Options"
cbrDpi = "DPI for image rendering"
[convert.ebookOptions]
ebookOptions = "eBook to PDF Options"
ebookOptionsDesc = "Options for converting eBooks to PDF"
embedAllFonts = "Embed all fonts"
embedAllFontsDesc = "Embed all fonts from the eBook into the generated PDF"
includeTableOfContents = "Include table of contents"
includeTableOfContentsDesc = "Add a generated table of contents to the resulting PDF"
includePageNumbers = "Include page numbers"
includePageNumbersDesc = "Add page numbers to the generated PDF"
optimizeForEbookPdf = "Optimize for ebook readers"
optimizeForEbookPdfDesc = "Optimize the PDF for eBook reading (smaller file size, better rendering on eInk devices)"
[imageToPdf]
tags = "chuyển đổi,img,jpg,hình ảnh,ảnh"
@@ -1409,11 +1361,6 @@ header = "Add attachments"
add = "Thêm tệp đính kèm"
remove = "Xóa tệp đính kèm"
embed = "Nhúng tệp đính kèm"
convertToPdfA3b = "Convert to PDF/A-3b"
convertToPdfA3bDescription = "Creates an archival PDF with embedded attachments"
convertToPdfA3bTooltip = "PDF/A-3b is an archival format ensuring long-term preservation. It allows embedding arbitrary file formats as attachments. Conversion requires Ghostscript and may take longer for large files."
convertToPdfA3bTooltipHeader = "About PDF/A-3b Conversion"
convertToPdfA3bTooltipTitle = "What it does"
submit = "Add attachments"
[watermark]
@@ -2359,10 +2306,6 @@ saved = "Đã lưu"
label = "Tải lên ảnh chữ ký"
placeholder = "Chọn tệp hình ảnh"
hint = "Tải lên ảnh chữ ký định dạng PNG hoặc JPG"
removeBackground = "Remove white background (make transparent)"
processing = "Processing image..."
backgroundRemovalFailedTitle = "Background removal failed"
backgroundRemovalFailedMessage = "Could not remove the background from the image. Using original image instead."
[sign.instructions]
title = "Cách thêm chữ ký"
@@ -2408,11 +2351,6 @@ note = "Làm phẳng sẽ loại bỏ các thành phần tương tác khỏi PDF
label = "Chỉ làm phẳng biểu mẫu"
desc = "Chỉ làm phẳng các trường biểu mẫu, giữ nguyên các thành phần tương tác khác"
[flatten.renderDpi]
label = "Rendering DPI (optional, recommended 150 DPI)"
help = "Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size."
placeholder = "e.g. 150"
[flatten.results]
title = "Kết quả làm phẳng"
@@ -2987,7 +2925,6 @@ header = "Cắt cúp PDF"
submit = "Gửi"
noFileSelected = "Chọn một tệp PDF để bắt đầu cắt xén"
reset = "Đặt lại về toàn bộ PDF"
autoCrop = "Auto-crop whitespace"
[crop.preview]
title = "Chọn vùng cắt"
@@ -3405,19 +3342,6 @@ placeholder = "Nhập số lượng phân chia theo chiều ngang"
label = "Phân chia theo chiều dọc"
placeholder = "Nhập số lượng phân chia theo chiều dọc"
[split-by-sections.splitMode]
label = "Split Mode"
description = "Choose how to split the pages"
splitAll = "Split all pages"
splitAllExceptFirst = "Split all except first"
splitAllExceptLast = "Split all except last"
splitAllExceptFirstAndLast = "Split all except first and last"
custom = "Custom pages"
[split-by-sections.customPages]
label = "Custom Page Numbers"
placeholder = "e.g. 2,4,6"
[AddStampRequest]
tags = "Dấu,Thêm hình ảnh,căn giữa hình ảnh,Hình mờ,PDF,Nhúng,Tùy chỉnh"
header = "Đóng dấu PDF"
@@ -3779,19 +3703,6 @@ filesize = "Kích thước tệp"
[compress.grayscale]
label = "Áp dụng thang độ xám để nén"
[compress.linearize]
label = "Linearize PDF for fast web viewing"
[compress.lineArt]
label = "Convert images to line art"
description = "Uses ImageMagick to reduce pages to high-contrast black and white for maximum size reduction."
unavailable = "ImageMagick is not installed or enabled on this server"
detailLevel = "Detail level"
edgeEmphasis = "Edge emphasis"
edgeLow = "Gentle"
edgeMedium = "Balanced"
edgeHigh = "Strong"
[compress.tooltip.header]
title = "Tổng quan cài đặt nén"
@@ -3809,10 +3720,6 @@ bullet2 = "Giá trị cao giảm kích thước tệp"
title = "Thang xám"
text = "Chọn tùy chọn này để chuyển tất cả hình ảnh sang đen trắng, có thể giảm đáng kể kích thước tệp, đặc biệt với PDF quét hoặc tài liệu nhiều hình ảnh."
[compress.tooltip.lineArt]
title = "Line Art"
text = "Convert pages to high-contrast black and white using ImageMagick. Use detail level to control how much content becomes black, and edge emphasis to control how aggressively edges are detected."
[compress.error]
failed = "Đã xảy ra lỗi khi nén PDF."
@@ -3825,11 +3732,6 @@ failed = "Đã xảy ra lỗi khi nén PDF."
_value = "Cài đặt nén"
1 = "1-3 nén PDF,</br> 4-6 nén ảnh nhẹ,</br> 7-9 nén ảnh mạnh sẽ làm giảm chất lượng hình ảnh đáng kể"
[compress.compressionLevel]
range1to3 = "Lower values preserve quality but result in larger files"
range4to6 = "Medium compression with moderate quality reduction"
range7to9 = "Higher values reduce file size significantly but may reduce image clarity"
[decrypt]
passwordPrompt = "Tệp này được bảo vệ bằng mật khẩu. Vui lòng nhập mật khẩu:"
cancelled = "Đã hủy thao tác cho PDF: {0}"
@@ -4069,92 +3971,23 @@ deleteSelected = "Xóa các trang đã chọn"
closePdf = "Đóng PDF"
exportAll = "Xuất PDF"
downloadSelected = "Tải xuống các tệp đã chọn"
annotations = "Annotations"
exportSelected = "Xuất các trang đã chọn"
saveChanges = "Lưu thay đổi"
downloadAll = "Tải xuống tất cả"
saveAll = "Lưu tất cả"
toggleTheme = "Chuyển đổi chủ đề"
toggleBookmarks = "Bật/tắt dấu trang"
language = "Ngôn ngữ"
toggleAnnotations = "Chuyển đổi hiển thị chú thích"
search = "Tìm kiếm PDF"
panMode = "Chế độ kéo"
rotateLeft = "Xoay trái"
rotateRight = "Xoay phải"
toggleSidebar = "Chuyển đổi thanh bên"
toggleBookmarks = "Bật/tắt dấu trang"
exportSelected = "Xuất các trang đã chọn"
toggleAnnotations = "Chuyển đổi hiển thị chú thích"
annotationMode = "Chuyển đổi chế độ chú thích"
print = "In PDF"
downloadAll = "Tải xuống tất cả"
saveAll = "Lưu tất cả"
[textAlign]
left = "Left"
center = "Center"
right = "Right"
[annotation]
title = "Annotate"
desc = "Use highlight, pen, text, and notes. Changes stay live—no flattening required."
highlight = "Highlight"
pen = "Pen"
text = "Text box"
note = "Note"
rectangle = "Rectangle"
ellipse = "Ellipse"
select = "Select"
exit = "Exit annotation mode"
strokeWidth = "Width"
opacity = "Opacity"
strokeOpacity = "Stroke Opacity"
fillOpacity = "Fill Opacity"
fontSize = "Font size"
chooseColor = "Choose colour"
color = "Colour"
strokeColor = "Stroke Colour"
fillColor = "Fill Colour"
underline = "Underline"
strikeout = "Strikeout"
squiggly = "Squiggly"
inkHighlighter = "Freehand Highlighter"
freehandHighlighter = "Freehand Highlighter"
square = "Square"
circle = "Circle"
polygon = "Polygon"
line = "Line"
stamp = "Add Image"
textMarkup = "Text Markup"
drawing = "Drawing"
shapes = "Shapes"
notesStamps = "Notes & Stamps"
settings = "Settings"
borderOn = "Border: On"
borderOff = "Border: Off"
editInk = "Edit Pen"
editLine = "Edit Line"
editNote = "Edit Note"
editText = "Edit Text Box"
editTextMarkup = "Edit Text Markup"
editSelected = "Edit Annotation"
editSquare = "Edit Square"
editCircle = "Edit Circle"
editPolygon = "Edit Polygon"
unsupportedType = "This annotation type is not fully supported for editing."
textAlignment = "Text Alignment"
noteIcon = "Note Icon"
imagePreview = "Preview"
contents = "Text"
backgroundColor = "Background colour"
clearBackground = "Remove background"
noBackground = "No background"
stampSettings = "Stamp Settings"
savingCopy = "Preparing download..."
saveFailed = "Unable to save copy"
saveReady = "Download ready"
selectAndMove = "Select and Edit"
editSelectDescription = "Click an existing annotation to edit its colour, opacity, text, or size."
editStampHint = "To change the image, delete this stamp and add a new one."
editSwitchToSelect = "Switch to Select & Edit to edit this annotation."
undo = "Undo"
redo = "Redo"
applyChanges = "Apply Changes"
draw = "Vẽ"
save = "Lưu"
saveChanges = "Lưu thay đổi"
[search]
title = "Tìm kiếm PDF"
@@ -4205,20 +4038,12 @@ settings = "Cài đặt"
adminSettings = "Cài đặt quản trị"
allTools = "All Tools"
reader = "Trình đọc"
tours = "Tours"
showMeAround = "Show me around"
[quickAccess.toursTooltip]
admin = "Watch walkthroughs here: Tools tour, New V2 layout tour, and the Admin tour."
user = "Watch walkthroughs here: Tools tour and the New V2 layout tour."
[quickAccess.helpMenu]
toolsTour = "Hướng dẫn công cụ"
toolsTourDesc = "Tìm hiểu công cụ có thể làm gì"
adminTour = "Hướng dẫn quản trị"
adminTourDesc = "Khám phá cài đặt & tính năng quản trị"
whatsNewTour = "See what's new in V2"
whatsNewTourDesc = "Tour the updated layout"
[admin]
error = "Lỗi"
@@ -5244,7 +5069,6 @@ loading = "Đang tải..."
back = "Quay lại"
continue = "Tiếp tục"
error = "Lỗi"
save = "Save"
[config.overview]
title = "Cấu hình ứng dụng"
@@ -5411,16 +5235,6 @@ finish = "Hoàn tất"
startTour = "Bắt đầu tham quan"
startTourDescription = "Tham quan có hướng dẫn các tính năng chính của Stirling PDF"
[onboarding.whatsNew]
quickAccess = "Start at the <strong>Quick Access</strong> rail to jump between Reader, Automate, your files, and all the tours."
leftPanel = "The left <strong>Tools</strong> panel lists everything you can do. Browse categories or search to find a tool quickly."
fileUpload = "Use the <strong>Files</strong> button to upload or pick a recent PDF. We will load a sample so you can see the workspace."
rightRail = "The <strong>Right Rail</strong> holds quick actions to select files, change theme or language, and download results."
topBar = "The top bar lets you swap between <strong>Viewer</strong>, <strong>Page Editor</strong>, and <strong>Active Files</strong>."
pageEditorView = "Switch to the Page Editor to reorder, rotate, or delete pages."
activeFilesView = "Use Active Files to see everything you have open and pick what to work on."
wrapUp = "That is what is new in V2. Open the <strong>Tours</strong> menu anytime to replay this, the Tools tour, or the Admin tour."
[onboarding.welcomeModal]
title = "Chào mừng đến với Stirling PDF!"
description = "Bạn có muốn xem một chuyến tham quan nhanh 1 phút để tìm hiểu các tính năng chính và cách bắt đầu không?"
@@ -5441,10 +5255,6 @@ download = "Tải xuống →"
showMeAround = "Hướng dẫn nhanh"
skipTheTour = "Bỏ qua hướng dẫn"
[onboarding.tourOverview]
title = "Tour Overview"
body = "Stirling PDF V2 ships with dozens of tools and a refreshed layout. Take a quick tour to see what changed and where to find the features you need."
[onboarding.serverLicense]
skip = "Bỏ qua tạm thời"
seePlans = "Xem gói →"
@@ -5758,28 +5568,6 @@ contactSales = "Liên hệ bộ phận kinh doanh"
contactToUpgrade = "Liên hệ với chúng tôi để nâng cấp hoặc tùy chỉnh gói của bạn"
maxUsers = "Số người dùng tối đa"
upTo = "Tối đa"
getLicense = "Get Server License"
upgradeToEnterprise = "Upgrade to Enterprise"
selectPeriod = "Select Billing Period"
monthlyBilling = "Monthly Billing"
yearlyBilling = "Yearly Billing"
checkoutOpened = "Checkout Opened"
checkoutInstructions = "Complete your purchase in the Stripe tab. After payment, return here and refresh the page to activate your license. You will also receive an email with your license key."
activateLicense = "Activate Your License"
[plan.static.licenseActivation]
checkoutOpened = "Checkout Opened in New Tab"
instructions = "Complete your purchase in the Stripe tab. Once your payment is complete, you will receive an email with your license key."
enterKey = "Enter your license key below to activate your plan:"
keyDescription = "Paste the license key from your email"
activate = "Activate License"
doLater = "I'll do this later"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.static.billingPortal]
title = "Email Verification Required"
message = "You will need to verify your email address in the Stripe billing portal. Check your email for a login link."
[plan.period]
month = "tháng"
@@ -5983,8 +5771,6 @@ notAvailable = "Hệ thống kiểm toán không khả dụng"
notAvailableMessage = "Hệ thống kiểm toán chưa được cấu hình hoặc không khả dụng."
disabled = "Ghi nhật ký kiểm toán đã bị tắt"
disabledMessage = "Bật ghi nhật ký kiểm toán trong cấu hình ứng dụng để theo dõi các sự kiện hệ thống."
enterpriseRequired = "Enterprise License Required"
enterpriseRequiredMessage = "The audit logging system is an enterprise feature. Please upgrade to an enterprise license to access audit logs and analytics."
[audit.error]
title = "Lỗi khi tải hệ thống kiểm toán"
@@ -6239,8 +6025,6 @@ reset = "Đặt lại thay đổi"
downloadJson = "Tải JSON"
generatePdf = "Tạo PDF"
saveChanges = "Lưu thay đổi"
applyChanges = "Apply Changes"
downloadCopy = "Download Copy"
[pdfTextEditor.options.autoScaleText]
title = "Tự căn chỉnh văn bản cho vừa hộp"
@@ -6259,24 +6043,6 @@ descriptionInline = "Mẹo: Giữ Ctrl (Cmd) hoặc Shift để chọn nhiều h
title = "Khóa văn bản đã chỉnh sửa thành một phần tử PDF duy nhất"
description = "Khi bật, trình chỉnh sửa xuất mỗi hộp văn bản đã chỉnh sửa thành một phần tử văn bản PDF để tránh chồng ký tự hoặc trộn font."
[pdfTextEditor.options.advanced]
title = "Advanced Settings"
[pdfTextEditor.tooltip.header]
title = "Preview Limitations"
[pdfTextEditor.tooltip.textFocus]
title = "Text and Image Focus"
text = "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here."
[pdfTextEditor.tooltip.previewVariance]
title = "Preview Variance"
text = "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible."
[pdfTextEditor.tooltip.alpha]
title = "Alpha Viewer"
text = "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
[pdfTextEditor.manual]
mergeTooltip = "Gộp các hộp đã chọn"
merge = "Gộp vùng chọn"

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