Compare commits

...
60 Commits
Author SHA1 Message Date
alam00000 9aae81e73c Release v2.8.10 2026-10-19 15:33:11 +05:30
Alam 2f868d4d0e Merge pull request #932 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 051abe5b72a9
2026-10-19 15:25:18 +05:30
alam00000 2be3d6858c build(deps): bump PDF engine and viewer to 051abe5b72a9 2026-10-19 09:46:51 +00:00
alam00000 edd959f345 fix(security): harden sanitize, flatten, redaction, signature validation, CSP, proxies and CI 2026-10-19 14:45:00 +05:30
alam00000 b0a186839a fix: change CLA signature storage branch to 'cla-signatures' 2026-10-19 13:20:31 +05:30
alam00000 70dc47d25c feat: update GitHub Actions workflow for PDF engine and viewer 2026-10-19 13:17:07 +05:30
alam00000 231c012e99 fix(ci): avoid rate limits 2026-10-19 02:07:51 +05:30
Alam 6a75673cbe Merge pull request #927 from alam00000/dependabot/npm_and_yarn/source-map-js-1.2.2
build(deps): bump source-map-js from 1.2.1 to 1.2.2
2026-10-19 02:03:10 +05:30
Alam 66f3628811 Merge pull request #926 from alam00000/dependabot/npm_and_yarn/handlebars-4.7.10
build(deps-dev): bump handlebars from 4.7.9 to 4.7.10
2026-10-19 02:02:59 +05:30
alam00000 4c314b8a13 Update service worker cache version 2026-10-19 01:07:55 +05:30
alam00000 0584def180 Release v2.8.9 2026-10-19 00:52:15 +05:30
github-actions[bot] ccdb4dd8e5 @cosark has signed the CLA in alam00000/bentopdf#904 2026-10-18 05:25:07 +00:00
dependabot[bot] 733c4f0bf9 build(deps): bump source-map-js from 1.2.1 to 1.2.2
Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/7rulnik/source-map-js/compare/v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-17 21:02:32 +00:00
dependabot[bot] dde07a28bd build(deps-dev): bump handlebars from 4.7.9 to 4.7.10
Bumps [handlebars](https://github.com/handlebars-lang/handlebars.js) from 4.7.9 to 4.7.10.
- [Release notes](https://github.com/handlebars-lang/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.10/release-notes.md)
- [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.9...v4.7.10)

---
updated-dependencies:
- dependency-name: handlebars
  dependency-version: 4.7.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-17 12:24:15 +00:00
github-actions[bot] 6ce0d69ba5 @oa-cmu has signed the CLA in alam00000/bentopdf#921 2026-10-17 02:57:30 +00:00
github-actions[bot] 167b7e8f90 @kelseyjmw has signed the CLA in alam00000/bentopdf#919 2026-10-16 16:22:48 +00:00
github-actions[bot] b5a69f9191 @sadfun has signed the CLA in alam00000/bentopdf#917 2026-10-15 12:08:26 +00:00
github-actions[bot] 2651471a84 @sergitost10 has signed the CLA in alam00000/bentopdf#916 2026-10-15 08:06:09 +00:00
github-actions[bot] 872a32929e @anishgowda21 has signed the CLA in alam00000/bentopdf#914 2026-10-14 06:42:53 +00:00
alam00000 46bf0fbb57 Enforce file origin check in annotation PDF viewer 2026-10-13 14:12:12 +05:30
alam00000 3a5f146d1b fix(vercel): docs CSP 2026-10-03 14:17:55 +05:30
alam00000 1a41545fff fixed routing 2026-10-03 14:10:46 +05:30
alam00000 c10511203e added Vercel OSS Program badge 2026-10-01 00:24:47 +05:30
alam00000 4d1dc2a838 fix(vercel): update docs rewrite 2026-09-30 23:58:12 +05:30
alam00000 4874f1e8a7 chore(vercel): add Vercel deployment configuration 2026-09-30 23:49:58 +05:30
github-actions[bot] 2560a31cdd @Harrunos has signed the CLA in alam00000/bentopdf#895 2026-09-26 22:39:25 +00:00
alam00000 daae736907 fix(i18n): add Polish (pl) language support to routing and sitemap generation 2026-09-22 18:26:27 +05:30
github-actions[bot] 044b2eae99 @adrienboulle has signed the CLA in alam00000/bentopdf#887 2026-09-21 11:42:54 +00:00
Alam ea3f42db84 Merge pull request #869 from carminezac/fix/timestamp-default-cors-proxy
fix(timestamp): fall back to the default CORS proxy on official domains
2026-09-21 13:52:45 +05:30
Alam 72d20bba09 Merge pull request #880 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 813903c93c75
2026-09-17 15:17:21 +05:30
alam00000 5a7927572f feat: add fallback font loading and handling for various languages 2026-09-17 13:56:16 +05:30
alam00000 866d40edc8 build(deps): bump PDF engine and viewer to 813903c93c75 2026-09-17 04:40:44 +00:00
github-actions[bot] 9ae5c93886 @Ahson-Shaikh has signed the CLA in alam00000/bentopdf#870 2026-09-16 11:37:48 +00:00
Alam a44ad4d7d3 Merge pull request #761 from nine-dev9/polish-translation
Add Polish translation
2026-09-16 03:24:27 +05:30
Alam 4c4701ef37 Merge pull request #849 from pavel-miniutka/be-locale
fix(i18n): Belarusian translation fixes
2026-09-16 03:23:09 +05:30
Alam fe65e9e999 Merge pull request #859 from alam00000/dependabot/npm_and_yarn/fflate-0.8.3
build(deps): bump fflate from 0.8.2 to 0.8.3
2026-09-16 03:22:38 +05:30
Alam ff6a09ae72 Merge pull request #871 from Stephan-P/patch-1
Update common.json (Dutch)
2026-09-16 03:22:02 +05:30
Stephan Paternotte 81929c7f5e Update common.json (Dutch)
Home -> Startpagina (= Start Page)
2026-09-14 21:20:04 +02:00
github-actions[bot] 2d37ac9f77 @carminezac has signed the CLA in alam00000/bentopdf#869 2026-09-13 21:29:59 +00:00
Carmine Zacchia 3aefd7bb06 fix(timestamp): fall back to the default CORS proxy on official domains
The timestamp tool requires a CORS proxy: none of the built-in TSA endpoints send Access-Control-Allow-Origin, so the browser blocks the RFC 3161 POST. The runtime only used a proxy when VITE_CORS_PROXY_URL was set, and the official build never set it, leaving timestamping broken on www.bentopdf.com and on the published Docker images.

Fall back to the project-operated proxy on the official domains only (bentopdf.com, www.bentopdf.com), matching the origin already allowed in the generated CSP. Self-hosted instances keep requiring their own proxy.
2026-09-13 23:18:59 +02:00
alam00000 c5ec840d10 feat: add testimonial with real users 2026-09-14 02:37:46 +05:30
alam00000 597e36904e feat: add URL redirection rules 2026-09-10 13:43:15 +05:30
github-actions[bot] e01f80867b @franklioxygen has signed the CLA in alam00000/bentopdf#865 2026-09-08 19:55:41 +00:00
alam00000 d69566ebef fix footer issue 2026-09-05 12:55:31 +05:30
alam00000 d931a71589 feat: add FAQ modal in PDF Multi Tool and Workflow pages 2026-09-05 11:43:12 +05:30
alam00000 2117d70837 prettier fix 2026-09-04 16:43:06 +05:30
alam00000 9e980cdea2 seo fixes 2026-09-04 16:26:08 +05:30
dependabot[bot] 31f6f977f9 build(deps): bump fflate from 0.8.2 to 0.8.3
Bumps [fflate](https://github.com/101arrowz/fflate) from 0.8.2 to 0.8.3.
- [Release notes](https://github.com/101arrowz/fflate/releases)
- [Changelog](https://github.com/101arrowz/fflate/blob/master/CHANGELOG.md)
- [Commits](https://github.com/101arrowz/fflate/compare/v0.8.2...v0.8.3)

---
updated-dependencies:
- dependency-name: fflate
  dependency-version: 0.8.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-09-03 21:34:04 +00:00
github-actions[bot] 83ff47db9b @ynlamy has signed the CLA in alam00000/bentopdf#757 2026-09-03 12:19:43 +00:00
alam00000 bfc32874ce remove disallow rules from robots.txt 2026-09-03 03:41:51 +05:30
alam00000 f404ff021a feat: add Kura and Hyper Compress product pages, redesign site 2026-09-02 18:29:22 +05:30
pavel-miniutka 4e2d269dc3 common.save action label fix 2026-09-02 14:04:47 +03:00
github-actions[bot] e95a631909 @tsueri has signed the CLA in alam00000/bentopdf#851 2026-09-02 10:05:23 +00:00
pavel-miniutka 47af6863bd fix(i18n): use a number-independent abbreviation for page count 2026-09-02 09:38:36 +03:00
pavel-miniutka 9c90d08a14 fix(i18n): Belarusian translation fixes 2026-09-01 16:15:21 +03:00
nine-dev9 994fd81626 Revert "Reapply "Fix missing regex in i18n.ts""
This reverts commit 4487f2c1c6.
2026-06-23 01:12:24 +02:00
nine-dev9 4487f2c1c6 Reapply "Fix missing regex in i18n.ts"
This reverts commit 39024e1a63.
2026-06-23 01:11:51 +02:00
nine-dev9 39024e1a63 Revert "Fix missing regex in i18n.ts"
This reverts commit 01c6148904.
2026-06-23 01:11:37 +02:00
nine-dev9 01c6148904 Fix missing regex in i18n.ts 2026-06-23 01:05:12 +02:00
nine-dev9 94c60f01c8 Add Polish translation 2026-06-22 20:46:53 +02:00
314 changed files with 34760 additions and 8051 deletions
+14 -16
View File
@@ -45,7 +45,7 @@ jobs:
run: npm run package
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
with:
files: |
dist-${{ steps.version.outputs.version }}.zip
@@ -77,10 +77,10 @@ jobs:
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -103,7 +103,7 @@ jobs:
- name: Build and push amd64 ${{ matrix.mode.name }} (release)
if: steps.version.outputs.is_release == 'true'
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
@@ -111,12 +111,11 @@ jobs:
tags: |
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64
platforms: linux/amd64
cache-from: type=gha,scope=amd64-${{ matrix.mode.name }}
cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }}
no-cache: true
- name: Build and push amd64 ${{ matrix.mode.name }} (edge)
if: steps.version.outputs.is_release == 'false'
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
@@ -146,10 +145,10 @@ jobs:
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -172,7 +171,7 @@ jobs:
- name: Build and push arm64 ${{ matrix.mode.name }} (release)
if: steps.version.outputs.is_release == 'true'
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
@@ -180,12 +179,11 @@ jobs:
tags: |
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
platforms: linux/arm64
cache-from: type=gha,scope=arm64-${{ matrix.mode.name }}
cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }}
no-cache: true
- name: Build and push arm64 ${{ matrix.mode.name }} (edge)
if: steps.version.outputs.is_release == 'false'
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
@@ -211,7 +209,7 @@ jobs:
suffix: "-simple"
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -275,14 +273,14 @@ jobs:
suffix: "-simple"
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
+2 -4
View File
@@ -11,7 +11,6 @@ permissions:
actions: write
contents: write
pull-requests: write
statuses: write
jobs:
cla-check:
@@ -28,16 +27,15 @@ jobs:
)
steps:
- name: "CLA Assistant"
uses: contributor-assistant/[email protected]
uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ASSISTANT_TOKEN }}
with:
path-to-signatures: 'signatures/cla.json'
path-to-document: 'https://github.com/${{ github.repository }}/blob/main/ICLA.md'
# Branch to store signatures
branch: 'main'
branch: 'cla-signatures'
# Allowlist for bot accounts (won't need to sign CLA)
allowlist: 'bot*,*[bot],dependabot*,renovate*,github-actions*'
+1 -1
View File
@@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: JamesIves/github-sponsors-readme-action@v1
- uses: JamesIves/github-sponsors-readme-action@02650b8cd445fc16dfef73195f9c406dce041623 # v1.6.1
with:
token: ${{ secrets.SPONSORS_TOKEN }}
file: 'README.md'
+8 -8
View File
@@ -28,10 +28,10 @@ jobs:
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Build image for scanning
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ${{ matrix.image.file }}
@@ -41,7 +41,7 @@ jobs:
no-cache: true
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ${{ matrix.image.name }}:scan
format: sarif
@@ -51,7 +51,7 @@ jobs:
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v4
if: always()
if: always() && hashFiles('trivy-*.sarif') != ''
with:
sarif_file: trivy-${{ matrix.image.name }}.sarif
category: trivy-${{ matrix.image.name }}
@@ -63,7 +63,7 @@ jobs:
uses: actions/checkout@v4
- name: Scan npm dependencies with Trivy
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
@@ -74,7 +74,7 @@ jobs:
- name: Upload dependency scan results
uses: github/codeql-action/upload-sarif@v4
if: always()
if: always() && hashFiles('trivy-deps.sarif') != ''
with:
sarif_file: trivy-deps.sarif
category: trivy-dependencies
@@ -86,7 +86,7 @@ jobs:
uses: actions/checkout@v4
- name: Scan Dockerfiles for misconfigurations
uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: config
scan-ref: .
@@ -96,7 +96,7 @@ jobs:
- name: Upload config scan results
uses: github/codeql-action/upload-sarif@v4
if: always()
if: always() && hashFiles('trivy-config.sarif') != ''
with:
sarif_file: trivy-config.sarif
category: trivy-config
+90 -18
View File
@@ -6,8 +6,7 @@ on:
- cron: '17 4 * * *'
permissions:
contents: write
pull-requests: write
contents: read
concurrency:
group: update-engine
@@ -18,12 +17,19 @@ env:
HUSKY: 0
jobs:
update:
build:
runs-on: ubuntu-latest
if: github.repository == 'alam00000/bentopdf'
permissions:
contents: read
outputs:
run: ${{ steps.gate.outputs.run }}
version: ${{ steps.gate.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Read current upstream marker
id: current
@@ -40,13 +46,21 @@ jobs:
- name: Should update?
id: gate
env:
CURRENT: ${{ steps.current.outputs.version }}
UPSTREAM: ${{ steps.upstream.outputs.version }}
run: |
if [ "${{ steps.upstream.outputs.version }}" = "${{ steps.current.outputs.version }}" ]; then
if ! [[ "$UPSTREAM" =~ ^[0-9a-f]{12}$ ]]; then
echo "::error::Unexpected fork HEAD: $UPSTREAM"
exit 1
fi
echo "version=$UPSTREAM" >> "$GITHUB_OUTPUT"
if [ "$UPSTREAM" = "$CURRENT" ]; then
echo "run=false" >> "$GITHUB_OUTPUT"
echo "Already on ${{ steps.current.outputs.version }}."
echo "Already on $CURRENT."
else
echo "run=true" >> "$GITHUB_OUTPUT"
echo "Updating ${{ steps.current.outputs.version }} -> ${{ steps.upstream.outputs.version }}"
echo "Updating $CURRENT -> $UPSTREAM"
fi
- name: Setup Node
@@ -73,9 +87,10 @@ jobs:
- name: Pack the engine
if: steps.gate.outputs.run == 'true'
id: engine
env:
SHA: ${{ steps.gate.outputs.version }}
run: |
set -euo pipefail
SHA=${{ steps.upstream.outputs.version }}
VENDOR=./_fork/packages/pdfium/src/vendor
STAGE=$(mktemp -d)/package
mkdir -p "$STAGE"
@@ -107,9 +122,10 @@ jobs:
- name: Pack the viewer without a second engine
if: steps.gate.outputs.run == 'true'
id: viewer
env:
SHA: ${{ steps.gate.outputs.version }}
run: |
set -euo pipefail
SHA=${{ steps.upstream.outputs.version }}
WORK=$(mktemp -d)
(cd ./_fork && npm pack ./viewers/snippet --pack-destination "$WORK" >/dev/null)
TMP=$(mktemp -d)
@@ -137,14 +153,17 @@ jobs:
- name: Point dependencies at the new tarballs
if: steps.gate.outputs.run == 'true'
env:
ENGINE_TARBALL: ${{ steps.engine.outputs.tarball }}
VIEWER_TARBALL: ${{ steps.viewer.outputs.tarball }}
run: |
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.dependencies['bentopdf-pdfium'] = 'file:' + process.argv[1];
pkg.dependencies['bentopdf-viewer'] = 'file:' + process.argv[2];
pkg.dependencies['bentopdf-pdfium'] = 'file:' + process.env.ENGINE_TARBALL;
pkg.dependencies['bentopdf-viewer'] = 'file:' + process.env.VIEWER_TARBALL;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
" "${{ steps.engine.outputs.tarball }}" "${{ steps.viewer.outputs.tarball }}"
"
- name: Cleanup upstream clone
if: steps.gate.outputs.run == 'true'
@@ -174,19 +193,66 @@ jobs:
- name: Write upstream marker
if: steps.gate.outputs.run == 'true'
env:
SHA: ${{ steps.gate.outputs.version }}
run: |
echo "${{ steps.upstream.outputs.version }}" > vendor/bentopdf-viewer/.upstream-version
echo "${{ steps.upstream.outputs.version }}" > vendor/bentopdf-pdfium/.upstream-version
echo "$SHA" > vendor/bentopdf-viewer/.upstream-version
echo "$SHA" > vendor/bentopdf-pdfium/.upstream-version
- name: Upload update
if: steps.gate.outputs.run == 'true'
uses: actions/upload-artifact@v4
with:
name: engine-update
include-hidden-files: true
retention-days: 1
path: |
package.json
package-lock.json
vendor/bentopdf-pdfium/
vendor/bentopdf-viewer/
pull-request:
runs-on: ubuntu-latest
needs: build
if: needs.build.outputs.run == 'true'
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Download update
uses: actions/download-artifact@v4
with:
name: engine-update
path: ${{ runner.temp }}/engine-update
- name: Apply update
id: apply
env:
UPDATE: ${{ runner.temp }}/engine-update
run: |
set -euo pipefail
rm -rf vendor/bentopdf-pdfium vendor/bentopdf-viewer
mkdir -p vendor
cp -R "$UPDATE/vendor/bentopdf-pdfium" "$UPDATE/vendor/bentopdf-viewer" vendor/
cp "$UPDATE/package.json" "$UPDATE/package-lock.json" .
{
echo 'checksums<<EOF'
sha256sum vendor/bentopdf-pdfium/*.tgz vendor/bentopdf-viewer/*.tgz
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Create Pull Request
if: steps.gate.outputs.run == 'true'
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
commit-message: 'build(deps): bump PDF engine and viewer to ${{ steps.upstream.outputs.version }}'
title: 'build(deps): bump PDF engine and viewer to ${{ steps.upstream.outputs.version }}'
commit-message: 'build(deps): bump PDF engine and viewer to ${{ needs.build.outputs.version }}'
title: 'build(deps): bump PDF engine and viewer to ${{ needs.build.outputs.version }}'
body: |
Both vendored packages built from one clone of the viewer fork at
`${{ steps.upstream.outputs.version }}`, so the text editor and the
`${{ needs.build.outputs.version }}`, so the text editor and the
PDF editor run the same engine.
- `bentopdf-pdfium` — the engine wasm, packed from the fork's published `src/vendor`
@@ -194,5 +260,11 @@ jobs:
The viewer loads the shared engine through `EmbedPDF.init({ wasmUrl })`.
CI verified a single wasm on disk, typecheck, and the test suite.
Built in a read-only job. Tarball checksums:
```
${{ steps.apply.outputs.checksums }}
```
branch: chore/update-pdf-engine
delete-branch: true
+4 -4
View File
@@ -12,7 +12,7 @@ Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'unsafe-eval' blob: https://cdn.jsdelivr.net; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' blob: https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-src 'self' blob:; frame-ancestors 'self'; form-action 'self'"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'unsafe-eval' blob: https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/ https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/assets/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' blob: https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-src 'self' blob:; frame-ancestors 'self'; form-action 'self'"
</IfModule>
# Block source maps from being served
@@ -99,7 +99,7 @@ RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Remove trailing slash (except for language root directories)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/$
RewriteCond %{REQUEST_URI} !^/(ar|be|da|de|es|fr|id|it|ja|ko|nl|pl|pt|ru|sk|sv|tr|uk|vi|zh|zh-TW)/$
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
@@ -117,11 +117,11 @@ RewriteRule ^en/(.+)$ /$1 [R=301,L]
# Language prefix root (e.g., /de/ -> /de/index.html)
RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /$1/index.html [L]
RewriteRule ^(ar|be|da|de|es|fr|id|it|ja|ko|nl|pl|pt|ru|sk|sv|tr|uk|vi|zh|zh-TW)/?$ /$1/index.html [L]
# Language prefix with path (e.g., /de/merge-pdf -> /de/merge-pdf.html)
RewriteCond %{DOCUMENT_ROOT}/$1/$2.html -f
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /$1/$2.html [L]
RewriteRule ^(ar|be|da|de|es|fr|id|it|ja|ko|nl|pl|pt|ru|sk|sv|tr|uk|vi|zh|zh-TW)/([^/]+)/?$ /$1/$2.html [L]
# ============================================
# 5.5. DOCS ROUTING (VitePress)
+5
View File
@@ -1,2 +1,7 @@
# Handlebars partials with template syntax inside HTML attributes
src/partials/footer.html
blog/posts/
public/pdfjs-viewer/
public/pdfjs-annotation-viewer/
+1 -1
View File
@@ -3,7 +3,7 @@
ARG BASE_URL=
# Build stage
FROM public.ecr.aws/docker/library/node:20-alpine AS builder
FROM mirror.gcr.io/library/node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
COPY vendor ./vendor
+1 -1
View File
@@ -5,7 +5,7 @@
ARG BASE_URL=
# Build stage (identical to main Dockerfile)
FROM public.ecr.aws/docker/library/node:20-alpine AS builder
FROM mirror.gcr.io/library/node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
COPY vendor ./vendor
+17 -6
View File
@@ -1,8 +1,13 @@
<p align="center"><img src="public/images/favicon-no-bg.svg" width="80"></p>
<h1 align="center">BentoPDF</h1>
<p align="center"><sub>Supported by</sub></p>
<p align="center">
<a href="https://vercel.com/open-source-program">
<img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge-2026.svg" height="30" />
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="https://www.digitalocean.com/?refcode=d93c189ef6d0&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge">
<img src="https://web-platforms.sfo2.cdn.digitaloceanspaces.com/WWW/Badge%203.svg" alt="DigitalOcean Referral Badge">
<img src="https://web-platforms.sfo2.cdn.digitaloceanspaces.com/WWW/Badge%203.svg" alt="DigitalOcean Referral Badge" height="44">
</a>
</p>
@@ -29,6 +34,7 @@
- [Convert to PDF](#convert-to-pdf)
- [Convert from PDF](#convert-from-pdf)
- [Secure & Optimize PDFs](#secure--optimize-pdfs)
- [Other Products](#-other-products)
- [Translations](#-translations)
- [Getting Started](#-getting-started)
- [Prerequisites](#prerequisites)
@@ -175,6 +181,7 @@ BentoPDF offers a comprehensive suite of tools to handle all your PDF needs.
| Tool Name | Description |
| :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **PDF Editor** | Annotate, highlight, redact, comment, add shapes/images, search, and view PDFs. |
| **Edit PDF Text** | Edit existing text directly in your PDF. Reuses the document's embedded fonts and keeps the rest of the page untouched. |
| **Create Fillable Forms** | Create professional fillable PDF forms with text fields, checkboxes, dropdowns, radio buttons, signatures, and more. Fully compliant with PDF standards for compatibility with all PDF viewers. |
| **PDF Form Filler** | Fill in forms directly in the browser. Also supports XFA forms. |
| **Add Page Numbers** | Easily add page numbers with customizable formatting. |
@@ -1218,16 +1225,20 @@ BentoPDF was originally built using **HTML**, **CSS**, and **vanilla JavaScript*
---
## 📦 Other Products
| Product | Description | Links |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------- |
| **Kura** | PDF standards and preflight engine. Converts to every PDF/A level, PDF/UA, PDF/X, PDF/E and PDF/VT, and can perform preflight checks. | [Website](https://kura.bentopdf.com) · [GitHub](https://github.com/alam00000/bentopdf-kura) |
| **Hyper Compress** | The best open source PDF compression engine. | [Website](https://hyper.bentopdf.com) · [GitHub](https://github.com/alam00000/bentopdf-hyper-compress) |
---
## 🗺️ Roadmap
### Planned Features:
- **HTML to PDF**: Convert HTML files or web pages into PDF documents.
- **Markdown to PDF**: Enhanced support for converting `.md` files to PDF.
- **Convert to PDF/A**: Convert PDFs to the PDF/A archival format.
- **Edit PDF Content**: Directly edit text and other content within your PDF.
- **PDF to Office**: Converts PDF files into editable Word, Excel, and PowerPoint formats.
- **Office to PDF**: Converts Word, Excel, and PowerPoint documents into optimized PDFs.
Contributions and discussions on the roadmap are welcome! Join the conversation via [Discord](https://discord.gg/Bgq3Ay3f2w).
+11
View File
@@ -62,6 +62,17 @@ When the build completes, you can find the website at `https://[your-github-user
If/when you merge changes from the source BentoPDF repository, the build and deploy action will automatically be kicked off and the new version will be automatically deployed to GitHub Pages.
> **Note:** GitHub Pages cannot set custom response headers, so a GitHub Pages deployment is served without BentoPDF's Content-Security-Policy and other security headers. If you need them, use one of the other hosts below or put a proxy or CDN that can add headers in front of your Pages site.
## Security headers
BentoPDF ships a Content-Security-Policy and other security headers for each static host:
- **Netlify and Cloudflare Pages** read `_headers` from the deployed folder. The build copies `public/_headers` into `dist/_headers`, and `scripts/generate-security-headers.mjs` regenerates both during `npm run build`, so any `VITE_WASM_*`, `VITE_TESSERACT_*`, `VITE_CORS_PROXY_URL` or `VITE_OCR_FONT_BASE_URL` values you set at build time are allowed by the policy. The release `dist-{version}.zip` already contains it.
- **Vercel** uses the `headers` block in `vercel.json`. It holds the default policy, so if you point the `VITE_*` URLs at your own servers, update the Content-Security-Policy there to match `public/_headers`.
- **`npx serve`** reads `serve.json` from the folder it serves. To use the repository's `serve.json` with the build output, run `npx serve dist -c ../serve.json`.
- **GitHub Pages** cannot set headers (see the note above).
## SEO and search engine indexing
By default, every self-hosted BentoPDF build emits canonical URLs and an
+253 -192
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Primary Meta Tags -->
<title>About BentoPDF - Privacy-First Free PDF Tools | Our Mission</title>
<title>About BentoPDF - Privacy-First Free PDF Tools | Our Story</title>
<meta
name="description"
content="Learn about BentoPDF - 100% free, privacy-first PDF toolkit. All tools run in your browser, no uploads, no signup. Fast, secure, and forever free."
@@ -51,6 +51,7 @@
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" />
<link href="/src/css/landing.css" rel="stylesheet" />
<!-- Web App Manifest -->
<link rel="manifest" href="/site.webmanifest" />
@@ -77,220 +78,267 @@
<link rel="icon" href="/favicon.ico" sizes="32x32" />
</head>
<body class="antialiased bg-gray-900 text-gray-300">
<body class="lp antialiased">
{{> navbar }}
<div id="app" class="min-h-screen container mx-auto p-4 md:p-8">
<section id="about-hero" class="text-center py-16 md:py-24">
<h1 class="text-3xl md:text-6xl font-bold text-white mb-4">
<span data-i18n="about.hero.title"
>We believe PDF tools should be</span
>
<span class="marker-slanted" data-i18n="about.hero.subtitle"
>fast, private, and free.</span
>
</h1>
<p
class="text-lg md:text-xl text-gray-400"
data-i18n="about.hero.noCompromises"
>
No compromises.
</p>
</section>
<div class="section-divider"></div>
<section id="mission-section" class="py-16 max-w-4xl mx-auto">
<div class="text-center">
<i
data-lucide="rocket"
class="w-16 h-16 text-indigo-400 mx-auto mb-6"
></i>
<h2
class="text-3xl md:text-4xl font-bold text-white mb-4"
data-i18n="about.mission.title"
>
Our Mission
</h2>
<p
class="text-lg text-gray-400 leading-relaxed"
data-i18n="about.mission.description"
>
To provide the most comprehensive PDF toolbox that respects your
privacy and never asks for payment. We believe essential document
tools should be accessible to everyone, everywhere, without
barriers.
</p>
</div>
</section>
<div
class="bg-gray-800 rounded-xl p-8 md:p-12 my-16 border border-gray-700"
>
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
<div class="text-center md:text-left">
<span
class="text-indigo-400 font-bold uppercase"
data-i18n="about.philosophy.label"
>Our Core Philosophy</span
<div id="app">
<section id="story-section" class="lp-sec lp-sec--first">
<div class="lp-frame">
<div class="lp-story">
<div class="lp-story-head">
<h1 class="lp-h2">
<span class="line">Hi, I'm Alam.</span>
<span class="line dim">I build BentoPDF.</span>
</h1>
<div class="lp-story-by">
<img
class="lp-avatar"
src="/images/author-alam.jpg"
alt="Alam"
width="44"
height="44"
/>
<a
href="https://github.com/alam00000"
target="_blank"
rel="me noopener noreferrer"
>GitHub</a
>
<a
href="https://www.linkedin.com/in/abdullah-alam01/"
target="_blank"
rel="me noopener noreferrer"
>LinkedIn</a
>
<a
href="https://x.com/alamdraws"
target="_blank"
rel="me noopener noreferrer"
>X</a
>
</div>
</div>
<div class="lp-story-body">
<p>
BentoPDF started off as just a simple internal tool I used for
quickly merging and splitting PDFs.
</p>
<p>
At some point, I decided to
<a
href="https://www.reddit.com/r/webdev/comments/1nr937y/i_made_bentopdf_a_privacy_first_pdf_toolkit_that/"
target="_blank"
rel="noopener noreferrer"
>share it on Reddit</a
>. Someone in the comments
<a
href="https://www.reddit.com/r/webdev/comments/1nr937y/comment/ngdeqby/"
target="_blank"
rel="noopener noreferrer"
>asked if it was open source</a
>. I thought, “Why not?” So a couple of weeks later, I
<a
href="https://github.com/alam00000/bentopdf"
target="_blank"
rel="noopener noreferrer"
>put the code on GitHub</a
>.
</p>
<p>
I posted it on
<a
href="https://www.reddit.com/r/selfhosted/comments/1o5borw/bentopdf_is_a_self_hostable_pdf_toolkit/"
target="_blank"
rel="noopener noreferrer"
>r/selfhosted</a
>
the next day, and that's when things really started to take off.
</p>
<p>
I honestly never thought BentoPDF would grow into what it is
today. It started as a little tool I made for myself, and
somehow it turned into a much bigger project used by people all
over the world.
</p>
</div>
</div>
<div class="lp-grid lp-grid--4 lp-cross">
<div class="lp-cell lp-stat lp-cell--accent lp-reveal">
<b>15K+</b><span>GitHub stars</span>
</div>
<div class="lp-cell lp-stat lp-cell--white lp-reveal">
<b>10M+</b><span>Downloads</span>
</div>
<div class="lp-cell lp-stat lp-cell--hatch lp-reveal">
<b>1.3K+</b><span>Forks</span>
</div>
<a
href="https://github.com/alam00000/bentopdf/graphs/contributors"
target="_blank"
rel="noopener noreferrer"
class="lp-cell lp-stat lp-cell--raised lp-reveal lp-stat-link"
>
<h2
class="text-3xl md:text-4xl font-bold text-white mt-2 mb-4"
data-i18n="about.philosophy.title"
>
Privacy First. Always.
</h2>
<p
class="text-gray-400 leading-relaxed"
data-i18n="about.philosophy.description"
>
In an era where data is a commodity, we take a different approach.
All processing for BentoPDF tools happens locally in your browser.
This means your files never touch our servers, we never see your
documents, and we don't track what you do. Your documents remain
completely and unequivocally private. It's not just a feature;
it's our foundation.
<b>60+</b
><span>Contributors <i data-lucide="arrow-up-right"></i></span>
</a>
</div>
<div class="lp-story-outro">
<p>
I don't build BentoPDF alone anymore. More than 60 people have
contributed code, translations and fixes, and thousands more have
starred it, shared it, reported bugs and asked for features. Thank
you.
</p>
<p>Enough about me. Here's more about BentoPDF.</p>
</div>
<div class="flex justify-center">
<div class="relative w-48 h-48">
<div
class="absolute inset-0 bg-indigo-500 rounded-full opacity-20 animate-pulse"
></div>
<div
class="absolute inset-4 bg-indigo-500 rounded-full opacity-30 animate-pulse delay-500"
></div>
<i
data-lucide="shield-check"
class="w-48 h-48 text-indigo-400"
></i>
</div>
</section>
<section id="mission-section" class="lp-sec lp-band">
<div class="lp-frame">
<figure class="lp-manifesto lp-reveal">
<h2 class="lp-h2">
<span class="line" data-i18n="about.mission.title">Our</span>
<span class="line dim" data-i18n="about.mission.titleDim"
>Mission</span
>
</h2>
<blockquote
class="lp-manifesto-text"
data-i18n="about.mission.description"
>
To provide the most comprehensive PDF toolbox that respects your
privacy and never asks for payment. We believe essential document
tools should be accessible to everyone, everywhere, without
barriers.
</blockquote>
</figure>
</div>
</section>
<section id="philosophy-section" class="lp-sec">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line" data-i18n="about.hero.title"
>PDF tools should be</span
>
<span class="line dim" data-i18n="about.hero.subtitle"
>fast, private, and free.</span
>
</h2>
<p class="lp-head-p" data-i18n="about.hero.noCompromises">
No compromises.
</p>
<p class="lp-head-p" data-i18n="about.philosophy.description">
Every BentoPDF tool runs locally in your browser. Your files are
never uploaded, nobody else sees your documents, and nothing
tracks what you do.
</p>
</div>
</div>
<div class="lp-grid lp-grid--3 lp-cross">
<div class="lp-cell lp-stat lp-cell--accent lp-reveal">
<b>0</b
><span data-i18n="features.noUploads.title">No Uploads</span>
</div>
<div class="lp-cell lp-stat lp-cell--white lp-reveal">
<b>0</b><span data-i18n="hero.noSignups">No Signups</span>
</div>
<div class="lp-cell lp-stat lp-cell--hatch lp-reveal">
<b>$0</b
><span data-i18n="features.foreverFree.title">Forever Free</span>
</div>
</div>
</div>
</div>
</section>
<section id="why-Bentopdf" class="py-16">
<h2 class="text-3xl md:text-4xl font-bold text-center text-white mb-12">
<span data-i18n="about.whyBentopdf.title">Why</span>
<span class="marker-slanted">BentoPDF?</span>
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-5xl mx-auto">
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4">
<i
data-lucide="zap"
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1"
></i>
<section id="why-bentopdf" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h3
class="text-xl font-bold text-white"
data-i18n="about.whyBentopdf.speed.title"
>
Built for Speed
</h3>
<p
class="text-gray-400 mt-2"
data-i18n="about.whyBentopdf.speed.description"
>
No waiting for uploads or downloads to a server. By processing
files directly in your browser using modern web technologies
like WebAssembly, we offer unparalleled speed for all our tools.
</p>
<h2 class="lp-h2">
<span class="line" data-i18n="about.whyBentopdf.title"
>Why</span
>
<span class="line dim">BentoPDF?</span>
</h2>
</div>
</div>
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4">
<i
data-lucide="badge-dollar-sign"
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1"
></i>
<div>
<h3
class="text-xl font-bold text-white"
data-i18n="about.whyBentopdf.free.title"
>
Completely Free
</h3>
<p
class="text-gray-400 mt-2"
data-i18n="about.whyBentopdf.free.description"
>
No trials, no subscriptions, no hidden fees, and no "premium"
features held hostage. We believe powerful PDF tools should be a
public utility, not a profit center.
<div class="lp-grid lp-grid--2 lp-cross">
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="zap"></i></span>
<h3 data-i18n="about.whyBentopdf.speed.title">Built for Speed</h3>
<p data-i18n="about.whyBentopdf.speed.description">
There's no upload or download step. Files are processed right in
your browser using WebAssembly, so you're never waiting on a
server.
</p>
</div>
</div>
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4">
<i
data-lucide="user-plus"
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1"
></i>
<div>
<h3
class="text-xl font-bold text-white"
data-i18n="about.whyBentopdf.noAccount.title"
>
<div class="lp-cell lp-reveal">
<span class="lp-tile"
><i data-lucide="badge-dollar-sign"></i
></span>
<h3 data-i18n="about.whyBentopdf.free.title">Free to Use</h3>
<p data-i18n="about.whyBentopdf.free.description">
Every tool is free, with no trials, no subscriptions and no
watermarks. Development is funded by commercial licenses.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="user-plus"></i></span>
<h3 data-i18n="about.whyBentopdf.noAccount.title">
No Account Required
</h3>
<p
class="text-gray-400 mt-2"
data-i18n="about.whyBentopdf.noAccount.description"
>
Start using any tool immediately. We don't need your email, a
password, or any personal information. Your workflow should be
frictionless and anonymous.
<p data-i18n="about.whyBentopdf.noAccount.description">
Open any tool and start right away. No email, no password, no
personal information.
</p>
</div>
</div>
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4">
<i
data-lucide="code-2"
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1"
></i>
<div>
<h3
class="text-xl font-bold text-white"
data-i18n="about.whyBentopdf.openSource.title"
>
Open Source Spirit
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="code-2"></i></span>
<h3 data-i18n="about.whyBentopdf.openSource.title">
Open Source
</h3>
<p
class="text-gray-400 mt-2"
data-i18n="about.whyBentopdf.openSource.description"
>
Built with transparency in mind. We leverage incredible
open-source libraries like PDF-lib and PDF.js, and believe in
the community-driven effort to make powerful tools accessible to
everyone.
<p data-i18n="about.whyBentopdf.openSource.description">
The code is public on GitHub under AGPL-3.0, so you can check
exactly how your files are handled. It builds on open-source
projects like PDF.js, pdf-lib, qpdf and LibreOffice.
</p>
</div>
</div>
</div>
</section>
<div class="section-divider"></div>
<section id="cta-section" class="text-center py-16">
<h2
class="text-3xl font-bold text-white mb-4"
data-i18n="about.cta.title"
>
Ready to get started?
</h2>
<p
class="text-lg text-gray-400 mb-8 max-w-2xl mx-auto"
data-i18n="about.cta.description"
>
Join thousands of users who trust BentoPDF for their daily document
needs. Experience the difference that privacy and performance can
make.
</p>
<a
href="index.html#tools-header"
class="inline-block px-8 py-3 rounded-full bg-gradient-to-b from-indigo-500 to-indigo-600 text-white font-semibold focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-indigo-400 hover:shadow-xl hover:shadow-indigo-500/30 transition-all duration-200 transform hover:-translate-y-1"
data-i18n="about.cta.button"
>
Explore All Tools
</a>
<section id="cta-section" class="lp-sec">
<div class="lp-frame">
<div class="lp-cta">
<h2 class="lp-h2" data-i18n="about.cta.title">
Ready to get started?
</h2>
<p data-i18n="about.cta.description">
Join thousands of users who trust BentoPDF for their daily
document needs. Experience the difference that privacy and
performance can make.
</p>
<div class="lp-cta-actions">
<span class="lp-brackets">
<a
href="index.html#tools-header"
class="lp-btn lp-btn--primary"
>
<span data-i18n="about.cta.button">Explore All Tools</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
<a href="https://bentopdf.com/docs/" class="lp-btn lp-btn--ghost">
<i data-lucide="book-open"></i>
<span data-i18n="nav.docs">Docs</span>
</a>
</div>
</div>
</div>
</section>
</div>
@@ -299,6 +347,7 @@
<script type="module" src="src/js/utils/lucide-init.ts"></script>
<script type="module" src="src/js/main.ts"></script>
<script type="module" src="src/js/mobileMenu.ts"></script>
<script type="module" src="src/js/landing.ts"></script>
<!-- JSON-LD Schema -->
<script type="application/ld+json">
@@ -306,8 +355,20 @@
"@context": "https://schema.org",
"@type": "AboutPage",
"name": "About BentoPDF",
"description": "Learn about BentoPDF's mission to provide free, privacy-first PDF tools",
"url": "https://www.bentopdf.com/about"
"description": "How BentoPDF started, told by its creator Alam",
"url": "https://www.bentopdf.com/about",
"mainEntity": {
"@type": "Person",
"name": "Alam",
"url": "https://www.bentopdf.com/blog/author-alam",
"image": "https://www.bentopdf.com/images/author-alam.jpg",
"jobTitle": "Creator and maintainer of BentoPDF",
"sameAs": [
"https://github.com/alam00000",
"https://www.linkedin.com/in/abdullah-alam01/",
"https://x.com/alamdraws"
]
}
}
</script>
</body>
+149
View File
@@ -0,0 +1,149 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Alam, Creator of BentoPDF</title>
<meta
name="description"
content="Alam builds BentoPDF, the open-source, privacy-first PDF toolkit that runs entirely in your browser. Every post on this blog is written by him."
/>
<meta name="robots" content="index, follow" />
<link rel="canonical" href="https://www.bentopdf.com/blog/author-alam" />
<meta property="og:type" content="profile" />
<meta
property="og:url"
content="https://www.bentopdf.com/blog/author-alam"
/>
<meta property="og:title" content="Alam, Creator of BentoPDF" />
<meta
property="og:description"
content="The maintainer behind BentoPDF and the author of every post on this blog."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/author-alam.jpg"
/>
<meta property="og:site_name" content="BentoPDF" />
<meta name="twitter:card" content="summary" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<link href="/src/css/styles.css" rel="stylesheet" />
</head>
<body class="antialiased bg-gray-900">
{{> navbar }}
<section class="max-w-3xl mx-auto px-4 py-12">
<div class="flex items-center gap-5 mb-8">
<img
src="/images/author-alam.jpg"
alt="Alam"
width="80"
height="80"
class="rounded-full"
/>
<div>
<h1 class="text-3xl font-bold text-white">Alam</h1>
<p class="text-gray-400">Creator and maintainer of BentoPDF</p>
</div>
</div>
<p class="text-gray-300 leading-relaxed mb-5">
I’m Alam, and I build
<a href="/" class="text-indigo-300 hover:text-indigo-400">BentoPDF</a>,
a free, open-source PDF toolkit with 100+ tools that run entirely in
your browser.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
There’s no uploading your files to a server, no account to create, and
no tracking. Your documents stay on your device. The
<a
href="https://github.com/alam00000/bentopdf"
rel="noopener"
class="text-indigo-300 hover:text-indigo-400"
>source code</a
>
is public, so you can see how it works yourself. BentoPDF is
AGPL-licensed and self-hostable.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
I write every post on this blog myself. I’ll write about PDFs, how they
work, things I learn while building BentoPDF, and occasionally things
that go wrong.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
When I compare BentoPDF with another PDF tool, I’ll link to its
documentation so you can check what I’m saying. If there’s something
BentoPDF doesn’t do well, I’ll say that too.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
And if I get something wrong, please
<a
href="https://github.com/alam00000/bentopdf/issues"
rel="noopener"
class="text-indigo-300 hover:text-indigo-400"
>open an issue</a
>. I’ll fix it and add a note to the post.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
You can find me on
<a
href="https://github.com/alam00000"
rel="me noopener"
class="text-indigo-300 hover:text-indigo-400"
>GitHub</a
>,
<a
href="https://www.linkedin.com/in/abdullah-alam01/"
rel="me noopener"
class="text-indigo-300 hover:text-indigo-400"
>LinkedIn</a
>
and
<a
href="https://x.com/alamdraws"
rel="me noopener"
class="text-indigo-300 hover:text-indigo-400"
>X</a
>.
</p>
<p class="text-gray-300 leading-relaxed">
<a
href="/blog"
class="inline-flex items-center gap-2 text-indigo-300 hover:text-indigo-400 font-semibold"
>Read the blog <i class="ph ph-arrow-right" aria-hidden="true"></i
></a>
</p>
</section>
{{> footer }}
<script type="module" src="/src/js/utils/lucide-init.ts"></script>
<script type="module">
import '@phosphor-icons/web/regular';
</script>
<script type="module" src="/src/js/mobileMenu.ts"></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProfilePage",
"mainEntity": {
"@type": "Person",
"name": "Alam",
"url": "https://www.bentopdf.com/blog/author-alam",
"image": "https://www.bentopdf.com/images/author-alam.jpg",
"jobTitle": "Creator and maintainer of BentoPDF",
"sameAs": [
"https://github.com/alam00000",
"https://www.linkedin.com/in/abdullah-alam01/",
"https://x.com/alamdraws"
]
}
}
</script>
</body>
</html>
+473
View File
@@ -0,0 +1,473 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
How to Edit a PDF Without Uploading It Anywhere | BentoPDF Blog
</title>
<meta
name="description"
content="Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job."
/>
<meta name="robots" content="index, follow, max-image-preview:large" />
<link
rel="canonical"
href="https://www.bentopdf.com/blog/edit-pdf-without-uploading"
/>
<meta property="og:type" content="article" />
<meta
property="og:url"
content="https://www.bentopdf.com/blog/edit-pdf-without-uploading"
/>
<meta
property="og:title"
content="How to Edit a PDF Without Uploading It Anywhere"
/>
<meta
property="og:description"
content="Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<link href="/src/css/styles.css" rel="stylesheet" />
</head>
<body class="antialiased bg-gray-900">
{{> navbar }}
<article class="max-w-3xl mx-auto px-4 py-12">
<nav
class="flex items-center gap-2 text-sm text-gray-400 mb-6"
aria-label="Breadcrumb"
>
<a href="/blog" class="hover:text-indigo-300">Blog</a>
<i class="ph ph-caret-right text-xs" aria-hidden="true"></i>
<span class="text-gray-300">Edit a PDF without uploading</span>
</nav>
<h1 class="text-3xl md:text-4xl font-bold text-white mb-4 leading-tight">
How to edit a PDF without uploading it anywhere
</h1>
<div class="flex items-center gap-3 mb-10 text-sm text-gray-400">
<img
src="/images/author-alam.jpg"
alt="Alam"
width="40"
height="40"
class="rounded-full"
/>
<div>
<a
href="/blog/author-alam"
class="text-gray-200 font-semibold hover:text-indigo-300"
>Alam</a
>, builds BentoPDF ·
<time datetime="2026-09-03">September 3, 2026</time>
</div>
</div>
<p class="text-gray-300 leading-relaxed mb-5">
You can edit a PDF in your browser without uploading the file to a
server.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Open
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
>BentoPDF&#39;s PDF editor</a
>, pick your file, make your changes, and download the result. The PDF
stays on your device. There&#39;s no account and no watermark.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
But “edit a PDF” can mean a few different things. You might want to
change existing text, fill out a form, add a signature, redact
something, or just highlight a paragraph. The right tool depends on what
you&#39;re trying to do.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
Why edit a PDF without uploading it?
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
Think about the PDFs you normally edit.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Contracts. Bank statements. Tax documents. Forms with your address or ID
number.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Those aren&#39;t necessarily files you want to upload to a random “free
PDF editor.”
</p>
<p class="text-gray-300 leading-relaxed mb-5">
With an on-device PDF editor, the file stays on your computer while
you&#39;re working on it.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
You can even check this yourself. Open your browser&#39;s developer
tools, go to the Network tab, and watch what happens while you edit. The
PDF itself doesn&#39;t need to be sent to a server.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
How to edit the actual text in a PDF
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
If you want to change words that are already in the PDF, use
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf-text"
>Edit PDF Text</a
>.
</p>
<ol
class="list-decimal list-inside text-gray-300 leading-relaxed mb-5 space-y-2"
>
<li>Open the tool.</li>
<li>Drop in your PDF.</li>
<li>Click on the text you want to change.</li>
<li>Type your changes.</li>
<li>Download the edited PDF.</li>
</ol>
<p class="text-gray-300 leading-relaxed mb-5">
BentoPDF loads the PDF in your browser and does the editing on your
device.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
This is one of the harder things to do with PDFs because PDF text
doesn&#39;t work quite like text in a Word document. The PDF is mostly
concerned with putting things at particular positions on a page, so
changing a sentence can mean figuring out how the surrounding text
should move.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
It works well for ordinary documents, but PDFs with unusual embedded
fonts or very complicated layouts can be trickier. I&#39;d always open
the downloaded PDF and check it.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
How to annotate a PDF
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
If you don&#39;t need to change the existing text, annotating a PDF is
much simpler.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
The
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
>PDF editor</a
>
lets you add highlights, comments, shapes, stamps, text boxes, and
images.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Open the PDF, add your annotations, and download the result.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Again, the editing happens in your browser rather than on a remote
server.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
How to fill out a PDF form
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
There are two common kinds of PDF forms.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If the PDF has actual form fields, open it in
<a class="text-indigo-300 hover:text-indigo-400" href="/form-filler"
>PDF Form Filler</a
>
and type into the fields. It handles standard AcroForm fields, and also
XFA forms, which are the legacy XML-based format. XFA is worth calling
out because Chrome and most other viewers show those files as blank
pages, which is why some government forms tell you to open them in Adobe
Reader. Firefox and BentoPDF&#39;s form filler render them properly.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If it&#39;s a scanned or flattened form, there aren&#39;t any fields to
click. In that case, you can put text boxes over the blank spaces in the
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
>PDF editor</a
>
and type into them. If you&#39;d rather have real fields,
<a class="text-indigo-300 hover:text-indigo-400" href="/form-creator"
>Create PDF Form</a
>
can add them to the document first.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
This is especially useful for government and HR forms, which often
contain personal information I&#39;d rather not upload somewhere just to
fill in a few boxes.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If the PDF is a scan and you actually need to edit the scanned text
itself, you&#39;ll need OCR first.
<a class="text-indigo-300 hover:text-indigo-400" href="/ocr-pdf"
>BentoPDF&#39;s OCR tool</a
>
can recognize the text in the document while keeping the processing on
your device.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
How to redact a PDF properly
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
This one is important because putting a black box over text isn&#39;t
necessarily redaction.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If you draw a rectangle over a name, the original name may still exist
underneath it. It might still be selectable, searchable, or extractable.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
Proper redaction removes the underlying content.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
The
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
>PDF editor</a
>
has redaction tools that permanently remove the underlying content
rather than drawing over it. For documents where you also want to strip
metadata or other hidden content,
<a class="text-indigo-300 hover:text-indigo-400" href="/sanitize-pdf"
>Sanitize PDF</a
>
can help with that.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
There&#39;s also a privacy reason to do redaction locally: if you upload
the original, unredacted PDF to a redaction service, that service has
already received the information you&#39;re trying to hide.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
How to sign a PDF without uploading it
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
<a class="text-indigo-300 hover:text-indigo-400" href="/sign-pdf"
>Sign PDF</a
>
lets you add a drawn, typed, or image signature to a PDF. Place it on
the page, resize it, and optionally flatten it so it becomes part of the
page instead of an annotation someone can drag away later.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
The signature is added on your device, so you don&#39;t need to upload
the document to a signing service just to place a signature on it.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
One thing to keep in mind: adding a signature image to a PDF is not the
same thing as applying a cryptographic digital signature. If the
recipient needs a signature that can actually be verified, use
<a
class="text-indigo-300 hover:text-indigo-400"
href="/digital-sign-pdf"
>Digital Signature</a
>
instead. It signs the document with an X.509 certificate (PKCS#12 .pfx
and .p12, or PEM), which proves who signed it and shows whether anything
changed afterwards. You can also add a visible signature block on top of
that. The certificate password and private key stay in your browser,
same as the PDF.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
Can you edit a PDF offline?
</h2>
<p class="text-gray-300 leading-relaxed mb-5">Yes.</p>
<p class="text-gray-300 leading-relaxed mb-5">
There&#39;s an easy way to test it: load the editor, turn off Wi-Fi, and
edit a PDF.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
The PDF processing code runs in your browser using WebAssembly. Once the
application has loaded, the actual PDF processing doesn&#39;t need a
server.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
This is also something you can inspect yourself in your browser&#39;s
developer tools. The website is how you get the software; it doesn&#39;t
have to be where your PDF gets processed.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If you want to run the whole thing yourself, BentoPDF is
<a
rel="noopener"
class="text-indigo-300 hover:text-indigo-400"
href="https://github.com/alam00000/bentopdf"
>open source and self-hostable</a
>. You can run your own instance instead of relying on ours.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
What about scanned PDFs?
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
A scanned PDF is basically a collection of images.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If you want to change the words in it, an ordinary PDF text editor
can&#39;t simply edit them because there isn&#39;t any text there yet.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
You&#39;ll need OCR (optical character recognition) to turn the pixels
into text.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
You can either OCR the PDF first and then edit the resulting text, or,
if you&#39;re just filling out a scanned form, put text boxes on top of
the existing page.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
Is there a file size limit?
</h2>
<p class="text-gray-300 leading-relaxed mb-5">
There isn&#39;t an imposed file-size limit.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
The practical limit is your device&#39;s available memory. Normal PDFs
are usually fine, but a thousand-page scanned archive is a very
different workload from a five-page contract.
</p>
<p class="text-gray-300 leading-relaxed mb-5">
For very large PDFs, a desktop application may be a better choice.
</p>
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
Will editing a digitally signed PDF break the signature?
</h2>
<p class="text-gray-300 leading-relaxed mb-5">Yes.</p>
<p class="text-gray-300 leading-relaxed mb-5">
Changing a digitally signed PDF will invalidate its existing signature.
This isn&#39;t specific to BentoPDF; it&#39;s a consequence of changing
a document that has already been signed.
</p>
<p class="text-gray-300 leading-relaxed mb-5">So the usual order is:</p>
<p class="text-gray-300 leading-relaxed mb-5">
<strong>Edit first. Sign last.</strong>
</p>
<p class="text-gray-300 leading-relaxed mb-5">
If you need to make changes to a signed document, make sure you
understand the signature requirements before doing so.
</p>
<div class="bg-gray-800 border border-gray-700 rounded-xl p-6 my-10">
<p class="text-white font-semibold mb-2">Edit your PDF now</p>
<p class="text-gray-400 mb-4">
Free, no signup. Your file stays on your device.
</p>
<a
href="/edit-pdf"
class="inline-block bg-indigo-600 hover:bg-indigo-700 text-white font-semibold px-5 py-2.5 rounded-lg"
>Open the PDF editor</a
>
</div>
</article>
{{> footer }}
<script type="module" src="/src/js/utils/lucide-init.ts"></script>
<script type="module" src="/src/js/mobileMenu.ts"></script>
<script type="module">
import '@phosphor-icons/web/regular';
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "How to edit a PDF without uploading it anywhere",
"description": "Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job.",
"url": "https://www.bentopdf.com/blog/edit-pdf-without-uploading",
"datePublished": "2026-09-03",
"dateModified": "2026-09-03",
"image": "https://www.bentopdf.com/images/og-tools.png",
"author": {
"@type": "Person",
"name": "Alam",
"url": "https://www.bentopdf.com/blog/author-alam",
"sameAs": [
"https://github.com/alam00000",
"https://www.linkedin.com/in/abdullah-alam01/",
"https://x.com/alamdraws"
]
},
"publisher": {
"@type": "Organization",
"name": "BentoPDF",
"url": "https://www.bentopdf.com"
}
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Blog",
"item": "https://www.bentopdf.com/blog/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Edit a PDF without uploading",
"item": "https://www.bentopdf.com/blog/edit-pdf-without-uploading"
}
]
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Why edit a PDF without uploading it?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Think about the PDFs you normally edit. Contracts. Bank statements. Tax documents. Forms with your address or ID number. Those aren't necessarily files you want to upload to a random “free PDF editor.” With an on-device PDF editor, the file stays on your computer while you're working on it. You can even check this yourself. Open your browser's developer tools, go to the Network tab, and watch what happens while you edit. The PDF itself doesn't need to be sent to a server."
}
},
{
"@type": "Question",
"name": "Can you edit a PDF offline?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. There's an easy way to test it: load the editor, turn off Wi-Fi, and edit a PDF. The PDF processing code runs in your browser using WebAssembly. Once the application has loaded, the actual PDF processing doesn't need a server. This is also something you can inspect yourself in your browser's developer tools. The website is how you get the software; it doesn't have to be where your PDF gets processed. If you want to run the whole thing yourself, BentoPDF is open source and self-hostable. You can run your own instance instead of relying on ours."
}
},
{
"@type": "Question",
"name": "What about scanned PDFs?",
"acceptedAnswer": {
"@type": "Answer",
"text": "A scanned PDF is basically a collection of images. If you want to change the words in it, an ordinary PDF text editor can't simply edit them because there isn't any text there yet. You'll need OCR (optical character recognition) to turn the pixels into text. You can either OCR the PDF first and then edit the resulting text, or, if you're just filling out a scanned form, put text boxes on top of the existing page."
}
},
{
"@type": "Question",
"name": "Is there a file size limit?",
"acceptedAnswer": {
"@type": "Answer",
"text": "There isn't an imposed file-size limit. The practical limit is your device's available memory. Normal PDFs are usually fine, but a thousand-page scanned archive is a very different workload from a five-page contract. For very large PDFs, a desktop application may be a better choice."
}
},
{
"@type": "Question",
"name": "Will editing a digitally signed PDF break the signature?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. Changing a digitally signed PDF will invalidate its existing signature. This isn't specific to BentoPDF; it's a consequence of changing a document that has already been signed. So the usual order is: Edit first. Sign last. If you need to make changes to a signed document, make sure you understand the signature requirements before doing so."
}
}
]
}
</script>
</body>
</html>
+87
View File
@@ -0,0 +1,87 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The BentoPDF Blog | Privacy-First PDF Guides</title>
<meta
name="description"
content="Guides and honest comparisons from the maintainer of BentoPDF: how PDF tools handle your files, and how to get things done without uploading them."
/>
<meta name="robots" content="index, follow, max-image-preview:large" />
<link rel="canonical" href="https://www.bentopdf.com/blog/" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/blog/" />
<meta property="og:title" content="The BentoPDF Blog" />
<meta
property="og:description"
content="Guides and honest comparisons from the maintainer of BentoPDF."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<link href="/src/css/styles.css" rel="stylesheet" />
</head>
<body class="antialiased bg-gray-900">
{{> navbar }}
<section class="max-w-3xl mx-auto px-4 py-12">
<h1 class="text-3xl md:text-4xl font-bold text-white mb-4">
The BentoPDF Blog
</h1>
<p class="text-gray-300 leading-relaxed mb-2">
I'm
<a
href="/blog/author-alam"
class="text-indigo-300 hover:text-indigo-400"
>Alam</a
>. I build BentoPDF and write about PDFs, how they work, and the weird
things I run into along the way.
</p>
</section>
<section class="max-w-3xl mx-auto px-4 pb-16">
<div class="space-y-6">
<a
href="/blog/edit-pdf-without-uploading"
class="block bg-gray-800 border border-gray-700 rounded-xl p-6 hover:border-indigo-500 transition-colors"
>
<h2 class="text-xl font-bold text-white mb-2">
How to edit a PDF without uploading it anywhere
</h2>
<p class="text-gray-400 mb-3">
Rewrite text, fill forms, redact properly, and sign, locally on your
device.
</p>
<span class="text-sm text-gray-500">September 3, 2026</span>
</a>
</div>
</section>
{{> footer }}
<script type="module" src="/src/js/utils/lucide-init.ts"></script>
<script type="module" src="/src/js/mobileMenu.ts"></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Blog",
"name": "The BentoPDF Blog",
"url": "https://www.bentopdf.com/blog/",
"description": "Guides and honest comparisons from the maintainer of BentoPDF.",
"publisher": {
"@type": "Organization",
"name": "BentoPDF",
"url": "https://www.bentopdf.com"
}
}
</script>
</body>
</html>
+134
View File
@@ -0,0 +1,134 @@
---
{
"title": "How to Edit a PDF Without Uploading It Anywhere | BentoPDF Blog",
"h1": "How to edit a PDF without uploading it anywhere",
"ogTitle": "How to Edit a PDF Without Uploading It Anywhere",
"breadcrumb": "Edit a PDF without uploading",
"description": "Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job.",
"card": "Rewrite text, fill forms, redact properly, and sign, locally on your device.",
"date": "2026-09-03",
"cta": {
"heading": "Edit your PDF now",
"text": "Free, no signup. Your file stays on your device.",
"href": "/edit-pdf",
"label": "Open the PDF editor"
}
}
---
You can edit a PDF in your browser without uploading the file to a server.
Open [BentoPDF's PDF editor](/edit-pdf), pick your file, make your changes, and download the result. The PDF stays on your device. There's no account and no watermark.
But “edit a PDF” can mean a few different things. You might want to change existing text, fill out a form, add a signature, redact something, or just highlight a paragraph. The right tool depends on what you're trying to do.
## Why edit a PDF without uploading it?
Think about the PDFs you normally edit.
Contracts. Bank statements. Tax documents. Forms with your address or ID number.
Those aren't necessarily files you want to upload to a random “free PDF editor.”
With an on-device PDF editor, the file stays on your computer while you're working on it.
You can even check this yourself. Open your browser's developer tools, go to the Network tab, and watch what happens while you edit. The PDF itself doesn't need to be sent to a server.
## How to edit the actual text in a PDF
If you want to change words that are already in the PDF, use [Edit PDF Text](/edit-pdf-text).
1. Open the tool.
2. Drop in your PDF.
3. Click on the text you want to change.
4. Type your changes.
5. Download the edited PDF.
BentoPDF loads the PDF in your browser and does the editing on your device.
This is one of the harder things to do with PDFs because PDF text doesn't work quite like text in a Word document. The PDF is mostly concerned with putting things at particular positions on a page, so changing a sentence can mean figuring out how the surrounding text should move.
It works well for ordinary documents, but PDFs with unusual embedded fonts or very complicated layouts can be trickier. I'd always open the downloaded PDF and check it.
## How to annotate a PDF
If you don't need to change the existing text, annotating a PDF is much simpler.
The [PDF editor](/edit-pdf) lets you add highlights, comments, shapes, stamps, text boxes, and images.
Open the PDF, add your annotations, and download the result.
Again, the editing happens in your browser rather than on a remote server.
## How to fill out a PDF form
There are two common kinds of PDF forms.
If the PDF has actual form fields, open it in [PDF Form Filler](/form-filler) and type into the fields. It handles standard AcroForm fields, and also XFA forms, which are the legacy XML-based format. XFA is worth calling out because Chrome and most other viewers show those files as blank pages, which is why some government forms tell you to open them in Adobe Reader. Firefox and BentoPDF's form filler render them properly.
If it's a scanned or flattened form, there aren't any fields to click. In that case, you can put text boxes over the blank spaces in the [PDF editor](/edit-pdf) and type into them. If you'd rather have real fields, [Create PDF Form](/form-creator) can add them to the document first.
This is especially useful for government and HR forms, which often contain personal information I'd rather not upload somewhere just to fill in a few boxes.
If the PDF is a scan and you actually need to edit the scanned text itself, you'll need OCR first. [BentoPDF's OCR tool](/ocr-pdf) can recognize the text in the document while keeping the processing on your device.
## How to redact a PDF properly
This one is important because putting a black box over text isn't necessarily redaction.
If you draw a rectangle over a name, the original name may still exist underneath it. It might still be selectable, searchable, or extractable.
Proper redaction removes the underlying content.
The [PDF editor](/edit-pdf) has redaction tools that permanently remove the underlying content rather than drawing over it. For documents where you also want to strip metadata or other hidden content, [Sanitize PDF](/sanitize-pdf) can help with that.
There's also a privacy reason to do redaction locally: if you upload the original, unredacted PDF to a redaction service, that service has already received the information you're trying to hide.
## How to sign a PDF without uploading it
[Sign PDF](/sign-pdf) lets you add a drawn, typed, or image signature to a PDF. Place it on the page, resize it, and optionally flatten it so it becomes part of the page instead of an annotation someone can drag away later.
The signature is added on your device, so you don't need to upload the document to a signing service just to place a signature on it.
One thing to keep in mind: adding a signature image to a PDF is not the same thing as applying a cryptographic digital signature. If the recipient needs a signature that can actually be verified, use [Digital Signature](/digital-sign-pdf) instead. It signs the document with an X.509 certificate (PKCS#12 .pfx and .p12, or PEM), which proves who signed it and shows whether anything changed afterwards. You can also add a visible signature block on top of that. The certificate password and private key stay in your browser, same as the PDF.
## Can you edit a PDF offline?
Yes.
There's an easy way to test it: load the editor, turn off Wi-Fi, and edit a PDF.
The PDF processing code runs in your browser using WebAssembly. Once the application has loaded, the actual PDF processing doesn't need a server.
This is also something you can inspect yourself in your browser's developer tools. The website is how you get the software; it doesn't have to be where your PDF gets processed.
If you want to run the whole thing yourself, BentoPDF is [open source and self-hostable](https://github.com/alam00000/bentopdf). You can run your own instance instead of relying on ours.
## What about scanned PDFs?
A scanned PDF is basically a collection of images.
If you want to change the words in it, an ordinary PDF text editor can't simply edit them because there isn't any text there yet.
You'll need OCR (optical character recognition) to turn the pixels into text.
You can either OCR the PDF first and then edit the resulting text, or, if you're just filling out a scanned form, put text boxes on top of the existing page.
## Is there a file size limit?
There isn't an imposed file-size limit.
The practical limit is your device's available memory. Normal PDFs are usually fine, but a thousand-page scanned archive is a very different workload from a five-page contract.
For very large PDFs, a desktop application may be a better choice.
## Will editing a digitally signed PDF break the signature?
Yes.
Changing a digitally signed PDF will invalidate its existing signature. This isn't specific to BentoPDF; it's a consequence of changing a document that has already been signed.
So the usual order is:
**Edit first. Sign last.**
If you need to make changes to a signed document, make sure you understand the signature requirements before doing so.
+2 -2
View File
@@ -7,10 +7,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.7
version: 1.0.9
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: '2.8.8'
appVersion: '2.8.10'
+1 -1
View File
@@ -83,7 +83,7 @@ npx wrangler deploy -c wasm-wrangler.toml
## Security Features
- **Origin validation**: Only allows requests from configured origins
- **Rate limiting**: 100 requests/minute per IP (requires KV namespace)
- **Rate limiting**: 100 requests/minute per IP, per /64 for IPv6 (requires KV namespace; fails open on KV errors)
- **File type restrictions**: Only WASM-related files (.js, .wasm, .data, etc.)
- **Size limits**: Max 100MB per file
- **Caching**: Reduces origin requests and improves performance
+166 -76
View File
@@ -81,53 +81,134 @@ function isAllowedOrigin(origin) {
return ALLOWED_ORIGINS.includes(origin);
}
function parseIPv4(address) {
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(address);
if (!match) return null;
const octets = match.slice(1).map(Number);
if (octets.some((octet) => octet > 255)) return null;
return octets.reduce((value, octet) => value * 256 + octet, 0);
}
function parseIPv6(address) {
let text = address.toLowerCase();
const embedded = /^(.*:)(\d+\.\d+\.\d+\.\d+)$/.exec(text);
if (embedded) {
const ipv4 = parseIPv4(embedded[2]);
if (ipv4 === null) return null;
text = `${embedded[1]}${Math.floor(ipv4 / 65536).toString(16)}:${(ipv4 % 65536).toString(16)}`;
}
const sections = text.split('::');
if (sections.length > 2) return null;
const head = sections[0] ? sections[0].split(':') : [];
const tail =
sections.length === 2 && sections[1] ? sections[1].split(':') : [];
const missing = 8 - head.length - tail.length;
if (sections.length === 1 ? missing !== 0 : missing < 1) return null;
const groups = [...head, ...Array(missing).fill('0'), ...tail];
if (!groups.every((group) => /^[0-9a-f]{1,4}$/.test(group))) return null;
return groups.map((group) => parseInt(group, 16));
}
const BLOCKED_IPV4_RANGES = [
'0.0.0.0/8',
'10.0.0.0/8',
'100.64.0.0/10',
'127.0.0.0/8',
'169.254.0.0/16',
'172.16.0.0/12',
'192.0.0.0/24',
'192.0.2.0/24',
'192.168.0.0/16',
'198.18.0.0/15',
'198.51.100.0/24',
'203.0.113.0/24',
'224.0.0.0/4',
'240.0.0.0/4',
].map((cidr) => {
const [address, prefixLength] = cidr.split('/');
return { base: parseIPv4(address), size: 2 ** (32 - Number(prefixLength)) };
});
const BLOCKED_IPV6_RANGES = [
'::/128',
'::1/128',
'::/96',
'::ffff:0:0/96',
'64:ff9b::/96',
'64:ff9b:1::/48',
'100::/64',
'2001::/32',
'2001:db8::/32',
'2002::/16',
'fc00::/7',
'fe80::/10',
'fec0::/10',
'ff00::/8',
].map((cidr) => {
const [address, prefixLength] = cidr.split('/');
return { groups: parseIPv6(address), prefixLength: Number(prefixLength) };
});
function isBlockedIPv4(value) {
return BLOCKED_IPV4_RANGES.some(
({ base, size }) => value >= base && value < base + size
);
}
function isBlockedIPv6(groups) {
return BLOCKED_IPV6_RANGES.some((range) =>
range.groups.every((group, index) => {
const bitsInGroup = Math.min(
16,
Math.max(0, range.prefixLength - index * 16)
);
const groupMask = (0xffff << (16 - bitsInGroup)) & 0xffff;
return (groups[index] & groupMask) === (group & groupMask);
})
);
}
function isBlockedIp(address) {
const ipv4 = parseIPv4(address);
if (ipv4 !== null) return isBlockedIPv4(ipv4);
const ipv6Groups = parseIPv6(address);
if (ipv6Groups !== null) return isBlockedIPv6(ipv6Groups);
return true;
}
function isIpLiteral(host) {
return /^[\d.]+$/.test(host) || host.includes(':');
}
function getRateLimitKey(ip) {
const ipv6Groups = ip.includes(':') ? parseIPv6(ip) : null;
if (!ipv6Groups) return ip;
return `${ipv6Groups
.slice(0, 4)
.map((group) => group.toString(16))
.join(':')}::/64`;
}
function isPrivateOrReservedHost(hostname) {
if (
/^10\./.test(hostname) ||
/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(hostname) ||
/^192\.168\./.test(hostname) ||
/^169\.254\./.test(hostname) || // link-local (cloud metadata)
/^100\.(6[4-9]|[7-9]\d|1[0-1]\d|12[0-7])\./.test(hostname) || // CGNAT
/^127\./.test(hostname) ||
/^0\./.test(hostname)
) {
const host = hostname
.toLowerCase()
.replace(/^\[|\]$/g, '')
.replace(/\.$/, '');
if (['localhost', 'localhost.localdomain'].includes(host)) {
return true;
}
if (/^\d+$/.test(hostname)) {
return true;
}
const lower = hostname.toLowerCase().replace(/^\[|\]$/g, '');
if (
lower === '::1' ||
lower.startsWith('::ffff:') ||
lower.startsWith('fe80') ||
lower.startsWith('fc') ||
lower.startsWith('fd') ||
lower.startsWith('ff')
) {
return true;
}
const blockedNames = [
'localhost',
'localhost.localdomain',
'0.0.0.0',
'[::1]',
];
if (blockedNames.includes(hostname.toLowerCase())) {
return true;
}
return false;
return isIpLiteral(host) && isBlockedIp(host);
}
async function hostnameResolvesToPrivate(hostname) {
const clean = hostname.replace(/^\[|\]$/g, '');
if (/^\d+\.\d+\.\d+\.\d+$/.test(clean) || clean.includes(':')) {
return isPrivateOrReservedHost(clean);
}
const clean = hostname
.toLowerCase()
.replace(/^\[|\]$/g, '')
.replace(/\.$/, '');
if (isPrivateOrReservedHost(clean)) return true;
if (isIpLiteral(clean)) return false;
const ips = [];
for (const type of ['A', 'AAAA']) {
try {
@@ -138,14 +219,16 @@ async function hostnameResolvesToPrivate(hostname) {
if (!res.ok) return true;
const data = await res.json();
for (const ans of data.Answer || []) {
if (ans && ans.data) ips.push(String(ans.data).replace(/\.$/, ''));
if (ans && (ans.type === 1 || ans.type === 28) && ans.data) {
ips.push(String(ans.data));
}
}
} catch {
return true;
}
}
if (ips.length === 0) return true;
return ips.some((ip) => isPrivateOrReservedHost(ip));
return ips.some((ip) => isBlockedIp(ip));
}
function isValidCertificateUrl(urlString) {
@@ -372,49 +455,56 @@ export default {
}
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown';
const rateLimitKey = `ratelimit:${clientIP}`;
const rateLimitKey = `ratelimit:${getRateLimitKey(clientIP)}`;
const now = Date.now();
if (env.RATE_LIMIT_KV) {
const rateLimitData = await env.RATE_LIMIT_KV.get(rateLimitKey, {
type: 'json',
});
const requests = rateLimitData?.requests || [];
try {
const rateLimitData = await env.RATE_LIMIT_KV.get(rateLimitKey, {
type: 'json',
});
const requests = rateLimitData?.requests || [];
const recentRequests = requests.filter(
(t) => now - t < RATE_LIMIT_WINDOW_MS
);
const recentRequests = requests.filter(
(t) => now - t < RATE_LIMIT_WINDOW_MS
);
if (recentRequests.length >= RATE_LIMIT_MAX_REQUESTS) {
return new Response(
JSON.stringify({
error: 'Rate limit exceeded',
message: `Maximum ${RATE_LIMIT_MAX_REQUESTS} requests per minute. Please try again later.`,
retryAfter: Math.ceil(
(recentRequests[0] + RATE_LIMIT_WINDOW_MS - now) / 1000
),
}),
{
status: 429,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
'Retry-After': Math.ceil(
if (recentRequests.length >= RATE_LIMIT_MAX_REQUESTS) {
return new Response(
JSON.stringify({
error: 'Rate limit exceeded',
message: `Maximum ${RATE_LIMIT_MAX_REQUESTS} requests per minute. Please try again later.`,
retryAfter: Math.ceil(
(recentRequests[0] + RATE_LIMIT_WINDOW_MS - now) / 1000
).toString(),
},
),
}),
{
status: 429,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
'Retry-After': Math.ceil(
(recentRequests[0] + RATE_LIMIT_WINDOW_MS - now) / 1000
).toString(),
},
}
);
}
recentRequests.push(now);
await env.RATE_LIMIT_KV.put(
rateLimitKey,
JSON.stringify({ requests: recentRequests }),
{
expirationTtl: 120,
}
);
} catch (error) {
console.error(
'[CORS Proxy] Rate limit KV error, allowing request:',
error
);
}
recentRequests.push(now);
await env.RATE_LIMIT_KV.put(
rateLimitKey,
JSON.stringify({ requests: recentRequests }),
{
expirationTtl: 120,
}
);
} else {
console.warn(
'[CORS Proxy] RATE_LIMIT_KV not configured — rate limiting is disabled'
+97 -36
View File
@@ -39,9 +39,38 @@ const ALLOWED_EXTENSIONS = [
'.mem',
'.asm.js',
'.worker.js',
'.html',
'.whl',
];
const SAFE_SUBPATH = /^\/[A-Za-z0-9._/-]*$/;
function isSafeSubpath(subpath) {
return (
SAFE_SUBPATH.test(subpath) &&
!subpath.split('/').some((segment) => segment === '.' || segment === '..')
);
}
function getRateLimitKey(ip) {
if (!ip.includes(':') || ip.includes('.')) return ip;
const sections = ip.toLowerCase().split('::');
if (sections.length > 2) return ip;
const leadingGroups = sections[0] ? sections[0].split(':') : [];
const trailingGroups = sections[1] ? sections[1].split(':') : [];
const missing = 8 - leadingGroups.length - trailingGroups.length;
if (sections.length === 1 ? missing !== 0 : missing < 1) return ip;
const groups = [
...leadingGroups,
...Array(missing).fill('0'),
...trailingGroups,
];
if (!groups.every((group) => /^[0-9a-f]{1,4}$/.test(group))) return ip;
return `${groups
.slice(0, 4)
.map((group) => parseInt(group, 16).toString(16))
.join(':')}::/64`;
}
function isAllowedOrigin(origin) {
if (!origin) return true; // Allow no-origin requests (e.g., direct browser navigation)
return ALLOWED_ORIGINS.some((allowed) =>
@@ -66,6 +95,7 @@ function corsHeaders(origin) {
'Access-Control-Expose-Headers':
'Content-Length, Content-Range, Content-Type',
'Access-Control-Max-Age': '86400',
'X-Content-Type-Options': 'nosniff',
};
}
@@ -89,7 +119,6 @@ function getContentType(pathname) {
'.so': 'application/octet-stream',
'.zip': 'application/zip',
'.mem': 'application/octet-stream',
'.html': 'text/html',
};
return contentTypes[ext] || 'application/octet-stream';
}
@@ -115,7 +144,34 @@ async function proxyRequest(request, env, sourceBaseUrl, subpath, origin) {
? sourceBaseUrl.slice(0, -1)
: sourceBaseUrl;
const normalizedPath = subpath.startsWith('/') ? subpath : `/${subpath}`;
const targetUrl = `${normalizedBase}${normalizedPath}`;
let targetUrl = null;
if (isSafeSubpath(normalizedPath)) {
try {
const candidate = new URL(`${normalizedBase}${normalizedPath}`).href;
if (candidate.startsWith(new URL(`${normalizedBase}/`).href)) {
targetUrl = candidate;
}
} catch {
targetUrl = null;
}
}
if (!targetUrl) {
return new Response(
JSON.stringify({
error: 'Invalid path',
message: 'The requested path is not allowed.',
}),
{
status: 400,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
if (!isAllowedFile(normalizedPath)) {
return new Response(
@@ -151,8 +207,6 @@ async function proxyRequest(request, env, sourceBaseUrl, subpath, origin) {
JSON.stringify({
error: 'Failed to fetch resource',
status: response.status,
statusText: response.statusText,
targetUrl: targetUrl,
}),
{
status: response.status,
@@ -204,14 +258,14 @@ async function proxyRequest(request, env, sourceBaseUrl, subpath, origin) {
'Content-Type': getContentType(normalizedPath),
'Content-Length': bodyData.byteLength.toString(),
'Cache-Control': `public, max-age=${CACHE_TTL_SECONDS}`,
'X-Proxied-From': new URL(targetUrl).hostname,
},
});
} catch (error) {
console.error('[WASM Proxy] Fetch error:', error);
return new Response(
JSON.stringify({
error: 'Proxy error',
message: error.message,
message: 'Failed to fetch the requested resource',
}),
{
status: 500,
@@ -260,42 +314,49 @@ export default {
if (env.RATE_LIMIT_KV) {
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown';
const rateLimitKey = `wasm-ratelimit:${clientIP}`;
const rateLimitKey = `wasm-ratelimit:${getRateLimitKey(clientIP)}`;
const now = Date.now();
const rateLimitData = await env.RATE_LIMIT_KV.get(rateLimitKey, {
type: 'json',
});
const requests = rateLimitData?.requests || [];
const recentRequests = requests.filter(
(t) => now - t < RATE_LIMIT_WINDOW_MS
);
try {
const rateLimitData = await env.RATE_LIMIT_KV.get(rateLimitKey, {
type: 'json',
});
const requests = rateLimitData?.requests || [];
const recentRequests = requests.filter(
(t) => now - t < RATE_LIMIT_WINDOW_MS
);
if (recentRequests.length >= RATE_LIMIT_MAX_REQUESTS) {
return new Response(
JSON.stringify({
error: 'Rate limit exceeded',
message: `Maximum ${RATE_LIMIT_MAX_REQUESTS} requests per minute.`,
}),
if (recentRequests.length >= RATE_LIMIT_MAX_REQUESTS) {
return new Response(
JSON.stringify({
error: 'Rate limit exceeded',
message: `Maximum ${RATE_LIMIT_MAX_REQUESTS} requests per minute.`,
}),
{
status: 429,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
'Retry-After': '60',
},
}
);
}
recentRequests.push(now);
await env.RATE_LIMIT_KV.put(
rateLimitKey,
JSON.stringify({ requests: recentRequests }),
{
status: 429,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
'Retry-After': '60',
},
expirationTtl: 120,
}
);
} catch (error) {
console.error(
'[WASM Proxy] Rate limit KV error, allowing request:',
error
);
}
recentRequests.push(now);
await env.RATE_LIMIT_KV.put(
rateLimitKey,
JSON.stringify({ requests: recentRequests }),
{
expirationTtl: 120,
}
);
}
if (pathname.startsWith('/pymupdf/')) {
+70 -28
View File
@@ -49,6 +49,7 @@
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" />
<link href="/src/css/landing.css" rel="stylesheet" />
<!-- Web App Manifest -->
<link rel="manifest" href="/site.webmanifest" />
@@ -75,38 +76,78 @@
<link rel="icon" href="/favicon.ico" sizes="32x32" />
</head>
<body class="antialiased bg-gray-900 text-gray-300">
<body class="lp antialiased">
{{> navbar }}
<div id="app" class="min-h-screen container mx-auto p-4 md:p-8">
<section id="contact-hero" class="text-center py-16 md:py-24">
<h1
class="text-4xl md:text-5xl font-bold text-white mb-4"
data-i18n="contact.title"
>
Get in Touch
</h1>
<p
class="text-lg md:text-xl text-gray-400 max-w-3xl mx-auto"
data-i18n="contact.subtitle"
>
We'd love to hear from you. Whether you have a question, feedback, or
a feature request, please don't hesitate to reach out.
</p>
<div id="app">
<section id="contact-hero" class="lp-sec lp-sec--first">
<div class="lp-frame">
<div class="lp-cta">
<div>
<h1 class="lp-h2">
<span class="line" data-i18n="contact.title">Get in Touch</span>
</h1>
<p class="lp-head-p" data-i18n="contact.subtitle">
We'd love to hear from you. Whether you have a question,
feedback, or a feature request, please don't hesitate to reach
out.
</p>
</div>
</div>
</div>
</section>
<div class="max-w-2xl mx-auto text-center py-8">
<p class="text-lg text-gray-400">
<span data-i18n="contact.email"
>You can reach us directly by email at:</span
>
<a
href="mailto:[email protected]"
class="text-indigo-400 underline hover:text-indigo-300"
>[email protected]</a
>
</p>
</div>
<section id="contact-channels" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-grid lp-grid--2 lp-cross">
<a class="lp-cell lp-reveal" href="mailto:[email protected]">
<span class="lp-tile"><i data-lucide="mail"></i></span>
<h3 data-i18n="contact.emailTitle">Email</h3>
<p data-i18n="contact.email">
You can reach us directly by email at:
</p>
<b>[email protected]</b>
</a>
<a
class="lp-cell lp-reveal"
href="https://github.com/alam00000/bentopdf/issues"
target="_blank"
rel="noopener noreferrer"
>
<span class="lp-tile"><i data-lucide="github"></i></span>
<h3>GitHub</h3>
<p data-i18n="contact.githubText">
Report a bug, request a feature, or read the source.
</p>
<b>github.com/alam00000/bentopdf</b>
</a>
<a
class="lp-cell lp-reveal"
href="https://discord.gg/Bgq3Ay3f2w"
target="_blank"
rel="noopener noreferrer"
>
<span class="lp-tile"><i data-lucide="message-circle"></i></span>
<h3>Discord</h3>
<p data-i18n="contact.discordText">
Join the community to chat with us and other users.
</p>
<b>discord.gg/Bgq3Ay3f2w</b>
</a>
<a class="lp-cell lp-reveal" href="faq.html">
<span class="lp-tile"><i data-lucide="help-circle"></i></span>
<h3 data-i18n="footer.faqLink">FAQ</h3>
<p data-i18n="contact.faqText">
Find quick answers to the questions we get most often.
</p>
<b data-i18n="contact.faqLink">Read the FAQ</b>
</a>
</div>
</div>
</section>
</div>
{{> footer }}
@@ -114,6 +155,7 @@
<script type="module" src="src/js/utils/lucide-init.ts"></script>
<script type="module" src="src/js/main.ts"></script>
<script type="module" src="src/js/mobileMenu.ts"></script>
<script type="module" src="src/js/landing.ts"></script>
<!-- JSON-LD Schema -->
<script type="application/ld+json">
{
+4 -3
View File
@@ -7,6 +7,7 @@ export default defineConfig({
description: "Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit",
base: '/docs/',
cleanUrls: true,
metaChunk: true,
transformPageData(pageData) {
const relPath = pageData.relativePath.replace(/\.md$/, '')
@@ -115,7 +116,7 @@ export default defineConfig({
{ text: 'PDF to Excel', link: '/tools/pdf-to-excel' },
{ text: 'PDF to Greyscale', link: '/tools/pdf-to-greyscale' },
{ text: 'PDF to JSON', link: '/tools/pdf-to-json' },
{ text: 'PDF to Word', link: '/tools/pdf-to-docx' },
{ text: 'PDF to Word', link: '/tools/pdf-to-word' },
{ text: 'Extract Images', link: '/tools/extract-images' },
{ text: 'PDF to Markdown', link: '/tools/pdf-to-markdown' },
{ text: 'Prepare PDF for AI', link: '/tools/prepare-pdf-for-ai' },
@@ -176,9 +177,9 @@ export default defineConfig({
text: 'Secure PDF',
collapsed: true,
items: [
{ text: 'Encrypt PDF', link: '/tools/encrypt-pdf' },
{ text: 'Protect PDF', link: '/tools/protect-pdf' },
{ text: 'Sanitize PDF', link: '/tools/sanitize-pdf' },
{ text: 'Decrypt PDF', link: '/tools/decrypt-pdf' },
{ text: 'Unlock PDF', link: '/tools/unlock-pdf' },
{ text: 'Flatten PDF', link: '/tools/flatten-pdf' },
{ text: 'Remove Metadata', link: '/tools/remove-metadata' },
{ text: 'Change Permissions', link: '/tools/change-permissions' },
+1 -1
View File
@@ -123,7 +123,7 @@ The included Cloudflare Worker has several security measures:
| **Private IP Blocking** | Blocks IPv4/IPv6 private ranges, link-local, loopback, decimal IPs, and cloud metadata |
| **Content-Type Safety** | Only returns safe certificate MIME types, blocks upstream content-type injection |
| **File Size Limit** | Streams response with 10MB limit, aborts mid-download if exceeded |
| **Rate Limiting** | 60 requests per IP per minute (requires KV) |
| **Rate Limiting** | 60 requests per minute per IP or IPv6 /64 (requires KV, fails open on KV errors) |
| **HMAC Signatures** | Optional client-side signing (deters casual abuse) |
### DNS rebinding (self-hosting off Cloudflare)
+4 -3
View File
@@ -126,10 +126,11 @@ The nginx image ships with an enforcing `Content-Security-Policy` header. The CS
As a result:
- If you override `VITE_CORS_PROXY_URL` or `VITE_WASM_*_URL` at build time, the CSP permits those origins automatically — no extra config needed.
- If you configure custom WASM URLs at _runtime_ via the in-app Advanced Settings page, those origins are **not** in the CSP and the browser will block fetches to them. Runtime configuration is intended for experimentation; for permanent custom URLs set the matching `VITE_*` build arg.
- Air-gapped deployments that override all three `VITE_WASM_*_URL` values also get the public `cdn.jsdelivr.net` removed from CSP (each default is replaced, not appended). Similarly, setting `VITE_CORS_PROXY_URL` replaces the public `bentopdf-cors-proxy.bentopdf.workers.dev` default.
- For URLs on `cdn.jsdelivr.net`, `script-src` allows only the exact versioned package folder, for example `https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/`, not the whole CDN. jsDelivr serves any public npm package or GitHub repository, so allowing the whole host would let any of them run on your instance. URLs on any other host are allowed by origin.
- If you configure custom WASM URLs at _runtime_ via the in-app Advanced Settings page, those origins are **not** in the CSP and the browser will block fetches to them. This also applies to a different version of the same package on `cdn.jsdelivr.net`, because only the version set at build time is allowed. Runtime configuration is intended for experimentation; for permanent custom URLs set the matching `VITE_*` build arg.
- Air-gapped deployments that override all three `VITE_WASM_*_URL` values also get those `cdn.jsdelivr.net` package folders removed from CSP (each default is replaced, not appended). The Tesseract OCR defaults on `cdn.jsdelivr.net` stay in the policy until you also set the three `VITE_TESSERACT_*` values. Similarly, setting `VITE_CORS_PROXY_URL` replaces the public `bentopdf-cors-proxy.bentopdf.workers.dev` default.
The CSP includes `'unsafe-eval'` in `script-src` because the LibreOffice WASM runtime (used by Word/Excel/PowerPoint conversion tools) compiles internal dispatch code via `new Function()`. Removing it would break all LibreOffice-backed tools. If you build in `SIMPLE_MODE` (without LibreOffice), you can manually edit the generated `security-headers.conf` to drop `'unsafe-eval'` for a stricter policy.
The CSP includes `'unsafe-eval'` in `script-src` because the LibreOffice WASM runtime (used by Word/Excel/PowerPoint conversion tools) and the wasm-vips image library (used by PDF to TIFF) compile internal dispatch code via `new Function()`. Removing it would break those tools. If you build in `SIMPLE_MODE` (without LibreOffice) and do not need PDF to TIFF, you can manually edit the generated `security-headers.conf` to drop `'unsafe-eval'` for a stricter policy.
For OCR, leave the `VITE_TESSERACT_*` variables empty to use the default online assets, or set all three together for self-hosted/offline OCR. Partial OCR overrides are rejected because the worker, core runtime, and traineddata directory must match. For fully offline searchable PDF output, also set `VITE_OCR_FONT_BASE_URL` so the OCR text-layer fonts are loaded from your internal server instead of the public Noto font URLs.
+2 -2
View File
@@ -56,6 +56,6 @@ If you set only an owner password (no user password), anyone can open the file b
## Related Tools
- [Encrypt PDF](./encrypt-pdf) -- simple password protection without granular permissions
- [Decrypt PDF](./decrypt-pdf) -- remove encryption entirely
- [Encrypt PDF](./protect-pdf) -- simple password protection without granular permissions
- [Decrypt PDF](./unlock-pdf) -- remove encryption entirely
- [Remove Restrictions](./remove-restrictions) -- strip all restrictions when you have the owner password
+1 -1
View File
@@ -61,5 +61,5 @@ Signing may require an internet connection. The signing library fetches the cert
- [Validate Signature](./validate-signature-pdf) -- verify digital signatures in signed PDFs
- [Flatten PDF](./flatten-pdf) -- flatten forms before signing to prevent modifications
- [Encrypt PDF](./encrypt-pdf) -- add password protection on top of the digital signature
- [Encrypt PDF](./protect-pdf) -- add password protection on top of the digital signature
- [Remove Metadata](./remove-metadata) -- strip metadata before signing
+2 -1
View File
@@ -18,7 +18,7 @@ BentoPDF's PDF Editor lets you annotate, highlight, redact, comment, add shapes
- Full annotation toolbar with highlighting, underlining, strikethrough, and freehand drawing
- Text insertion and commenting
- Redaction tools for permanently removing sensitive content
- Redaction tools that permanently remove marked content once you apply the redaction. If any marks haven't been applied when you click **Download Edited PDF**, the editor offers to apply them first.
- Shape tools for rectangles, circles, lines, and arrows
- Image insertion onto PDF pages
- Built-in text search across the document
@@ -37,6 +37,7 @@ BentoPDF's PDF Editor lets you annotate, highlight, redact, comment, add shapes
- You can open multiple PDFs at once and switch between them using the tab bar at the top of the editor.
- The editor preserves the original PDF structure, so fonts, layouts, and form fields remain intact.
- Marking text or an area for redaction doesn't remove anything until the redaction is applied. When you redact selected text, copies of it in the file's properties, bookmarks, comments, and attachments are also removed from the download, unless the file is encrypted.
- For bulk watermarking or page numbering, use the dedicated tools instead for more control over formatting.
## Related Tools
+1 -1
View File
@@ -48,4 +48,4 @@ The tool uses pdf-lib to flatten form fields (via `form.flatten()`) and a dedica
- [Sanitize PDF](./sanitize-pdf) -- flatten forms plus remove metadata, scripts, and more
- [Rasterize PDF](./rasterize-pdf) -- convert to image-based PDF for maximum flattening
- [Font to Outline](./font-to-outline) -- flatten fonts to vector paths
- [Encrypt PDF](./encrypt-pdf) -- lock the flattened PDF with a password
- [Encrypt PDF](./protect-pdf) -- lock the flattened PDF with a password
+3 -3
View File
@@ -95,7 +95,7 @@ Extract content from PDFs into images, documents, and data formats.
- [**PDF to Excel**](./pdf-to-excel) — Extract tables from PDF and convert to Excel (XLSX).
- [**PDF to Greyscale**](./pdf-to-greyscale) — Convert all colors to black and white.
- [**PDF to JSON**](./pdf-to-json) — Convert PDF files to JSON format.
- [**PDF to Word**](./pdf-to-docx) — Convert PDF files to editable Word documents.
- [**PDF to Word**](./pdf-to-word) — Convert PDF files to editable Word documents.
- [**Extract Images**](./extract-images) — Extract all embedded images from your PDF files.
- [**PDF to Markdown**](./pdf-to-markdown) — Convert PDF text and tables to Markdown format.
- [**Prepare PDF for AI**](./prepare-pdf-for-ai) — Extract PDF content as LlamaIndex JSON for RAG/LLM pipelines.
@@ -171,9 +171,9 @@ Protect, encrypt, and control access to your PDF documents.
<div class="tool-grid">
- [**Encrypt PDF**](./encrypt-pdf) — Lock your PDF by adding a password.
- [**Encrypt PDF**](./protect-pdf) — Lock your PDF by adding a password.
- [**Sanitize PDF**](./sanitize-pdf) — Remove metadata, annotations, scripts, and more.
- [**Decrypt PDF**](./decrypt-pdf) — Unlock PDF by removing password protection.
- [**Decrypt PDF**](./unlock-pdf) — Unlock PDF by removing password protection.
- [**Flatten PDF**](./flatten-pdf) — Make form fields and annotations non-editable.
- [**Remove Metadata**](./remove-metadata) — Strip hidden data from your PDF.
- [**Change Permissions**](./change-permissions) — Set or change user permissions on a PDF.
+1 -1
View File
@@ -39,5 +39,5 @@ Converts PDF files to Markdown (`.md`) format, preserving headings, paragraphs,
## Related Tools
- [PDF to Text](./pdf-to-text)
- [PDF to Word](./pdf-to-docx)
- [PDF to Word](./pdf-to-word)
- [Prepare PDF for AI](./prepare-pdf-for-ai)
+1 -1
View File
@@ -40,4 +40,4 @@ This tool has no configurable options. All text content is extracted from every
- [PDF to Markdown](./pdf-to-markdown)
- [Prepare PDF for AI](./prepare-pdf-for-ai)
- [PDF to Word](./pdf-to-docx)
- [PDF to Word](./pdf-to-word)
@@ -58,7 +58,7 @@ AES-256 is computationally infeasible to brute-force with current technology. Th
## Related Tools
- [Decrypt PDF](./decrypt-pdf) -- remove encryption when you know the password
- [Decrypt PDF](./unlock-pdf) -- remove encryption when you know the password
- [Change Permissions](./change-permissions) -- modify specific usage restrictions
- [Remove Restrictions](./remove-restrictions) -- strip all security from a PDF
- [Sanitize PDF](./sanitize-pdf) -- remove hidden content before encrypting
+1 -1
View File
@@ -46,5 +46,5 @@ No options to configure. The tool is thorough by design: it clears everything.
## Related Tools
- [Sanitize PDF](./sanitize-pdf) -- remove metadata plus scripts, attachments, and more
- [Encrypt PDF](./encrypt-pdf) -- protect the cleaned PDF with a password
- [Encrypt PDF](./protect-pdf) -- protect the cleaned PDF with a password
- [Compress PDF](./compress-pdf) -- removing metadata can slightly reduce file size; compress for more savings
+2 -2
View File
@@ -40,6 +40,6 @@ The tool uses QPDF's `--decrypt` and `--remove-restrictions` flags to produce a
## Related Tools
- [Decrypt PDF](./decrypt-pdf) -- unlock a PDF when you know the user password
- [Encrypt PDF](./encrypt-pdf) -- re-apply encryption with new settings
- [Decrypt PDF](./unlock-pdf) -- unlock a PDF when you know the user password
- [Encrypt PDF](./protect-pdf) -- re-apply encryption with new settings
- [Change Permissions](./change-permissions) -- selectively modify which actions are allowed
+1 -1
View File
@@ -49,5 +49,5 @@ All options are enabled by default. Uncheck any you want to preserve.
- [Remove Metadata](./remove-metadata) -- strip only metadata without touching other content
- [Flatten PDF](./flatten-pdf) -- flatten forms and annotations specifically
- [Encrypt PDF](./encrypt-pdf) -- add password protection after sanitizing
- [Encrypt PDF](./protect-pdf) -- add password protection after sanitizing
- [Rasterize PDF](./rasterize-pdf) -- the nuclear option: convert to images to eliminate all hidden content
@@ -41,6 +41,6 @@ If you have the password to an encrypted PDF, this tool removes the encryption e
## Related Tools
- [Encrypt PDF](./encrypt-pdf) -- re-apply encryption with a new password
- [Encrypt PDF](./protect-pdf) -- re-apply encryption with a new password
- [Remove Restrictions](./remove-restrictions) -- remove usage restrictions without full decryption
- [Change Permissions](./change-permissions) -- modify specific permissions on an encrypted PDF
+56 -85
View File
@@ -49,6 +49,7 @@
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" />
<link href="/src/css/landing.css" rel="stylesheet" />
<!-- Web App Manifest -->
<link rel="manifest" href="/site.webmanifest" />
@@ -75,10 +76,13 @@
<link rel="icon" href="/favicon.ico" sizes="32x32" />
</head>
<body class="antialiased bg-gray-900 text-gray-300">
<body class="lp antialiased bg-gray-900 text-gray-300">
{{> navbar }}
<div id="app" class="min-h-screen container mx-auto p-4 md:p-8">
<div
id="app"
class="min-h-screen container mx-auto px-4 pt-4 md:px-8 md:pt-8"
>
<section id="faq-hero" class="text-center py-16 md:py-24">
<h1 class="text-4xl md:text-5xl font-bold text-white mb-4">
Frequently Asked Questions
@@ -89,42 +93,32 @@
</p>
</section>
<div class="max-w-4xl mx-auto space-y-4">
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<div class="faq-list">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Are my files safe and private?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
<strong>Absolutely.</strong> This is the most important feature of
BentoPDF. All processing happens 100% locally in your web browser.
Your files are never uploaded to any server, which means we—or
anyone else—can never see them. Your privacy is guaranteed.
Your files are never uploaded to any server, which means we, or
anyone else, can never see them. Your privacy is guaranteed.
</p>
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Is BentoPDF really free? What's the catch?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
Yes, it's completely free, and there's no catch. There are no
hidden fees, no subscription plans, no usage limits, and no
@@ -134,19 +128,14 @@
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Do I need an internet connection to use the tools?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
After you load the website for the first time, most tools will
work completely offline! Because all the processing libraries are
@@ -158,19 +147,14 @@
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Are there any file size or usage limitations?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
No, we do not impose any artificial limits on file size, the
number of files, or how many times you can use a tool. The only
@@ -181,19 +165,14 @@
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Why did my PDF fail to process?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>Failures are rare but can happen for a few reasons:</p>
<ul class="list-disc list-inside mt-2 space-y-1">
<li>
@@ -212,19 +191,14 @@
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
Do you track my activity on BentoPDF?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
No. BentoPDF does not track you at all. We do not use cookies,
analytics, or any tracking scripts, not even on the live website
@@ -234,19 +208,14 @@
</div>
</details>
<details
class="bg-gray-800 border border-gray-700 rounded-lg p-5 group"
>
<summary class="flex items-center justify-between cursor-pointer">
<details class="faq-d">
<summary class="faq-d-q">
<h3 class="font-semibold text-white text-lg">
What technology does BentoPDF use?
</h3>
<i
data-lucide="plus"
class="w-6 h-6 text-indigo-400 icon flex-shrink-0"
></i>
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<div class="mt-4 text-gray-400">
<div class="faq-d-a">
<p>
BentoPDF is built on the power of modern web technologies. We
primarily use JavaScript libraries like
@@ -259,22 +228,24 @@
</details>
</div>
<div class="section-divider mt-16"></div>
<section id="contact-section" class="text-center py-16">
<h2 class="text-3xl font-bold text-white mb-4">
Still have questions?
</h2>
<p class="text-lg text-gray-400 mb-8 max-w-2xl mx-auto">
If you can't find the answer you're looking for, feel free to reach
out to our support team. We're always Bento to help.
</p>
<a
href="contact.html"
class="inline-block px-8 py-3 rounded-full bg-gray-700 text-white font-semibold focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-indigo-400 hover:bg-gray-600 transition-colors duration-200"
>
Contact Us
</a>
<section id="contact-section" class="lp-sec">
<div class="lp-frame">
<div class="lp-cta">
<h2 class="lp-h2">Still have questions?</h2>
<p>
If you can't find the answer you're looking for, feel free to
reach out. We're always happy to help.
</p>
<div class="lp-cta-actions">
<span class="lp-brackets">
<a href="contact.html" class="lp-btn lp-btn--primary">
<span data-i18n="footer.contactUs">Contact Us</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
</div>
</div>
</div>
</section>
</div>
@@ -293,7 +264,7 @@
"name": "Are my files safe and private?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Absolutely. This is the most important feature of BentoPDF. All processing happens 100% locally in your web browser. Your files are never uploaded to any server, which means we—or anyone else—can never see them. Your privacy is guaranteed."
"text": "Absolutely. This is the most important feature of BentoPDF. All processing happens 100% locally in your web browser. Your files are never uploaded to any server, which means we, or anyone else, can never see them. Your privacy is guaranteed."
}
},
{
+692
View File
@@ -0,0 +1,692 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Primary Meta Tags -->
<title>Hyper Compress - PDF Compression Engine | BentoPDF</title>
<meta
name="description"
content="Hyper Compress is a content-preserving PDF compression engine. Free under the AGPL, commercial licenses from $99/year."
/>
<meta name="author" content="BentoPDF" />
<meta name="robots" content="index, follow" />
<!-- Canonical URL -->
<link rel="canonical" href="https://www.bentopdf.com/hyper-compress" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/hyper-compress" />
<meta
property="og:title"
content="Hyper Compress - PDF Compression Engine | BentoPDF"
/>
<meta
property="og:description"
content="Hyper Compress is a content-preserving PDF compression engine. Free under the AGPL, commercial licenses from $99/year."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content="Hyper Compress - PDF Compression Engine | BentoPDF"
/>
<meta
name="twitter:description"
content="Hyper Compress is a content-preserving PDF compression engine. Free under the AGPL, commercial licenses from $99/year."
/>
<meta
name="twitter:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" />
<link href="/src/css/landing.css" rel="stylesheet" />
<!-- Web App Manifest -->
<link rel="manifest" href="/site.webmanifest" />
<!-- Favicons -->
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/images/favicon-192x192.png"
/>
<link
rel="icon"
type="image/png"
sizes="512x512"
href="/images/favicon-512x512.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/images/apple-touch-icon.png"
/>
<link rel="icon" href="/favicon.ico" sizes="32x32" />
</head>
<body class="lp antialiased">
{{> navbar }}
<div id="app">
<section id="hyper-compress-hero" class="lp-sec lp-sec--first">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h1 class="lp-h1">
<span class="line">Meet</span>
<span class="line dim">Hyper Compress</span>
</h1>
<p class="lp-head-p">
The best open source PDF compression engine. It never returns a
file larger than the original, offers a true lossless mode, and
posted the lowest corruption rate of every engine we
benchmarked.
</p>
<p class="lp-head-p">
Ships as a CLI, Node SDK, C library, self-hosted service and
WebAssembly build.
</p>
<div class="lp-actions">
<span class="lp-brackets">
<a href="#pricing" class="lp-btn lp-btn--primary">
<span>See pricing</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
<a
href="https://hyper.bentopdf.com"
target="_blank"
rel="noopener"
class="lp-btn lp-btn--ghost"
>
<i data-lucide="external-link"></i>
<span>Visit website</span>
</a>
<a
href="https://github.com/alam00000/bentopdf-hyper-compress"
target="_blank"
rel="noopener"
class="lp-btn lp-btn--ghost"
>
<i data-lucide="github"></i>
<span>View on GitHub</span>
</a>
</div>
</div>
</div>
<div class="lp-grid lp-grid--4">
<div class="lp-cell lp-stat lp-cell--accent lp-reveal">
<b>64.8%</b><span>median reduction, strongest preset</span>
</div>
<div class="lp-cell lp-stat lp-cell--white lp-reveal">
<b>22.4%</b><span>median reduction, lossless</span>
</div>
<div class="lp-cell lp-stat lp-cell--hatch lp-reveal">
<b>0.39%</b><span>corruption rate, lowest tested</span>
</div>
<div class="lp-cell lp-stat lp-cell--raised lp-reveal">
<b>2,104</b><span>real-world PDFs benchmarked</span>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-pad--tight">
<div class="lp-note lp-reveal">
<i data-lucide="badge-check"></i>
<p>
<strong
>Open source, self-hosting and internal use stay free.</strong
>
Hyper Compress is licensed under the AGPL-3.0. If your project
is AGPL-compatible, or you run Hyper Compress as-is for
yourself, you never need a commercial license. Commercial
licenses are only for shipping Hyper Compress inside
closed-source software.
</p>
</div>
</div>
</div>
</section>
<section id="pricing" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Commercial</span>
<span class="line dim">Licenses</span>
</h2>
<p class="lp-head-p">
Per product, billed annually. Every tier includes all updates
and new releases while active.
</p>
</div>
</div>
<div class="lp-grid lp-grid--4">
<div class="lp-cell lp-tier lp-reveal">
<h3>Solo</h3>
<p class="lp-tier-for">
One developer, under $100k annual revenue
</p>
<div class="lp-tier-price"><b>$99</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_38OODBtvzFt24gT3W2ibWPZmm5HVMdUuWOjBt3ImRJA"
class="lp-btn lp-btn--ghost lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Solo</a
>
</div>
<div class="lp-cell lp-tier lp-cell--accent lp-reveal">
<h3>Indie</h3>
<p class="lp-tier-for">Companies under $1M annual revenue</p>
<div class="lp-tier-price"><b>$199</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>Unlimited developers</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_SWybHH8hi4Yufhn6seVrlJnlXZfymvLQgCadU3pWjT9"
class="lp-btn lp-btn--primary lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Indie</a
>
</div>
<div class="lp-cell lp-tier lp-reveal">
<h3>Business</h3>
<p class="lp-tier-for">Companies at $1M annual revenue or more</p>
<div class="lp-tier-price"><b>$499</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>Unlimited developers</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Priority email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_k2hYaoG49OZyB3WbAkmVyB55MRHqYQqex1bja0z7DfY"
class="lp-btn lp-btn--ghost lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Business</a
>
</div>
<div class="lp-cell lp-tier lp-reveal">
<h3>OEM</h3>
<p class="lp-tier-for">
Redistribution, reselling as an SDK, or offering Hyper Compress
as a service
</p>
<div class="lp-tier-price">
<span class="lp-tier-from">from</span><b>$1,999</b
><span>/ year</span>
</div>
<ul>
<li><i data-lucide="check"></i>Redistribution rights</li>
<li><i data-lucide="check"></i>Terms shaped to your product</li>
<li><i data-lucide="check"></i>Priority support</li>
</ul>
<a
href="mailto:[email protected]?subject=Hyper%20Compress%20commercial%20license%20OEM"
class="lp-btn lp-btn--ghost lp-btn--sm"
>Contact us</a
>
</div>
</div>
</div>
</section>
<section id="license-details" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Commercial license</span>
<span class="line dim">details</span>
</h2>
</div>
</div>
<div class="lp-pad">
<div class="grid grid-cols-1 gap-6">
<div class="lp-panel">
<h3
class="text-xl font-semibold text-white mb-4 flex items-center gap-3"
>
<i data-lucide="package" class="w-6 h-6 text-indigo-400"></i>
Delivery &amp; licensing model
</h3>
<ul class="space-y-3 text-gray-400">
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
><strong class="text-white"
>No license key is required or provided.</strong
>
Hyper Compress intentionally does not use license keys, to
streamline deployment and reduce operational
friction.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Upon purchase you receive a ZIP archive containing the
complete Hyper Compress source code.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Because Hyper Compress is open source, every release and
every update can always be downloaded from our
<a
href="https://github.com/alam00000/bentopdf-hyper-compress/releases"
target="_blank"
rel="noopener noreferrer"
class="text-indigo-400 hover:underline"
>GitHub releases page</a
>.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>The source code provided is identical to the code
published in our public open-source repository.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="x-circle"
class="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5"
></i>
<span
><strong class="text-white">No refunds.</strong> Under no
circumstances shall a refund be made after purchase.</span
>
</li>
</ul>
<p class="mt-4 text-gray-300">
<strong class="text-white">GitHub repository:</strong>
<a
href="https://github.com/alam00000/bentopdf-hyper-compress"
target="_blank"
rel="noopener noreferrer"
class="text-indigo-400 hover:underline"
>github.com/alam00000/bentopdf-hyper-compress</a
>
</p>
</div>
<div class="lp-panel">
<h3
class="text-xl font-semibold text-white mb-4 flex items-center gap-3"
>
<i
data-lucide="file-text"
class="w-6 h-6 text-indigo-400"
></i>
Invoicing
</h3>
<ul class="space-y-3 text-gray-400">
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>We use <strong class="text-white">Polar</strong> for
payments, which
<strong class="text-white"
>automatically sends invoices</strong
>
via email after purchase.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Polar handles
<strong class="text-white">VAT invoices</strong> for
businesses in applicable regions.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="info"
class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5"
></i>
<span
>For VAT invoices, select
<strong class="text-white"
>"I'm purchasing as a business"</strong
>
during checkout and enter your billing address and Tax/VAT
number.</span
>
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<section id="compare" class="lp-sec">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">What each tier</span>
<span class="line dim">covers</span>
</h2>
<p class="lp-head-p">
Every tier lets you ship Hyper Compress inside one closed-source
product. The tiers differ by who you are, how many developers
you have, and whether Hyper Compress is passed on to anyone
else.
</p>
</div>
</div>
<div class="lp-pad--tight lp-reveal">
<div class="overflow-x-auto">
<table class="lp-table lp-compare">
<thead>
<tr>
<th></th>
<th>Solo</th>
<th>Indie</th>
<th>Business</th>
<th>OEM</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Who it's for</th>
<td>One developer, under $100k annual revenue</td>
<td>Companies under $1M annual revenue</td>
<td>Companies at $1M annual revenue or more</td>
<td>
Anyone redistributing, reselling or hosting the engine
</td>
</tr>
<tr>
<th scope="row">Annual price</th>
<td>$99</td>
<td>$199</td>
<td>$499</td>
<td>from $1,999</td>
</tr>
<tr>
<th scope="row">Developers covered</th>
<td>One developer</td>
<td>Unlimited</td>
<td>Unlimited</td>
<td>Discussed with you</td>
</tr>
<tr>
<th scope="row">Closed-source products covered</th>
<td>One</td>
<td>One</td>
<td>One</td>
<td>Terms shaped to your product</td>
</tr>
<tr>
<th scope="row">Updates while active</th>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">Support</th>
<td>Email</td>
<td>Email</td>
<td>Priority email</td>
<td>Priority</td>
</tr>
<tr>
<th scope="row">
Redistribute inside someone else's product
</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">Resell as an SDK</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">
Offer Hyper Compress as a hosted service
</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
</tbody>
</table>
</div>
<p class="lp-table-note">
Redistribution, reselling and hosting are what separate OEM from
the rest. If Hyper Compress only ships inside your own
closed-source product, the choice between Solo, Indie and Business
is purely a question of your size.
</p>
</div>
</div>
</section>
<section class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">License</span>
<span class="line dim">Terms</span>
</h2>
</div>
</div>
<div class="lp-grid lp-grid--2">
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="package"></i></span>
<h3>Per product</h3>
<p>
A license covers one shipped product. A second product needs a
second license, or ask about covering your whole catalogue at
OEM.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="refresh-cw"></i></span>
<h3>Updates included</h3>
<p>
Every release published while your license is active is yours.
If you let it lapse, you keep a perpetual right to the last
version you received.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="unlock"></i></span>
<h3>No AGPL obligations</h3>
<p>
The commercial license replaces the AGPL for your product. You
ship closed source, with no requirement to publish your changes
or your application.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="shield-check"></i></span>
<h3>Clean provenance</h3>
<p>
Hyper Compress is written and owned by BentoPDF, and every
third-party component it bundles, including PDFium, qpdf, jpegli
and Leptonica, is permissively licensed. No copyleft surprises
in your supply chain.
</p>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Frequently Asked</span>
<span class="line dim">Questions</span>
</h2>
</div>
</div>
<div class="lp-faq-wrap">
<div id="faq-accordion" class="lp-faq lp-reveal">
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>Do I need a commercial license?</span>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
Only if you ship Hyper Compress inside closed-source
software. Open-source projects under an AGPL-compatible
license, self-hosting, and internal use are all free under
the AGPL-3.0.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span
>Does the BentoPDF commercial license cover Hyper
Compress?</span
>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
No. Hyper Compress is a separate project with its own
license. The BentoPDF app license does not grant any rights
to Hyper Compress, and a Hyper Compress license does not
cover BentoPDF.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>What happens if my company outgrows its tier?</span>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
You move up to the matching tier at your next renewal.
Nothing retroactive. Growing past a threshold mid-term never
invalidates your current license.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-cta">
<h2 class="lp-h2">Not sure which tier fits?</h2>
<p>
Tell us what you're building and we'll tell you what it costs. No
calls required.
</p>
<div class="lp-cta-actions">
<span class="lp-brackets">
<a
href="mailto:[email protected]?subject=Hyper%20Compress%20commercial%20license%20pricing"
class="lp-btn lp-btn--primary"
>
<span>[email protected]</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
</div>
</div>
</div>
</section>
</div>
{{> footer }}
<script type="module" src="src/js/utils/lucide-init.ts"></script>
<script type="module" src="src/js/main.ts"></script>
<script type="module" src="src/js/mobileMenu.ts"></script>
<script type="module" src="src/js/landing.ts"></script>
<!-- JSON-LD Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Hyper Compress - PDF Compression Engine | BentoPDF",
"url": "https://www.bentopdf.com/hyper-compress"
}
</script>
</body>
</html>
+443 -544
View File
File diff suppressed because it is too large Load Diff
+683
View File
@@ -0,0 +1,683 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Primary Meta Tags -->
<title>Kura - PDF/A, PDF/UA &amp; PDF/X Conversion Engine | BentoPDF</title>
<meta
name="description"
content="Kura converts any PDF to archival, print and accessibility standards. Free under the AGPL, commercial licenses from $99/year."
/>
<meta name="author" content="BentoPDF" />
<meta name="robots" content="index, follow" />
<!-- Canonical URL -->
<link rel="canonical" href="https://www.bentopdf.com/kura" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/kura" />
<meta
property="og:title"
content="Kura - PDF/A, PDF/UA &amp; PDF/X Conversion Engine | BentoPDF"
/>
<meta
property="og:description"
content="Kura converts any PDF to archival, print and accessibility standards. Free under the AGPL, commercial licenses from $99/year."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content="Kura - PDF/A, PDF/UA &amp; PDF/X Conversion Engine | BentoPDF"
/>
<meta
name="twitter:description"
content="Kura converts any PDF to archival, print and accessibility standards. Free under the AGPL, commercial licenses from $99/year."
/>
<meta
name="twitter:image"
content="https://www.bentopdf.com/images/og-tools.png"
/>
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" />
<link href="/src/css/landing.css" rel="stylesheet" />
<!-- Web App Manifest -->
<link rel="manifest" href="/site.webmanifest" />
<!-- Favicons -->
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/images/favicon-192x192.png"
/>
<link
rel="icon"
type="image/png"
sizes="512x512"
href="/images/favicon-512x512.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/images/apple-touch-icon.png"
/>
<link rel="icon" href="/favicon.ico" sizes="32x32" />
</head>
<body class="lp antialiased">
{{> navbar }}
<div id="app">
<section id="kura-hero" class="lp-sec lp-sec--first">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h1 class="lp-h1">
<span class="line">Meet</span>
<span class="line dim">Kura</span>
</h1>
<p class="lp-head-p">
The PDF standards and preflight engine. Convert any PDF to every
PDF/A level, PDF/UA, PDF/X, PDF/E and PDF/VT, then preflight the
result against 396 bundled profiles to confirm it conforms.
</p>
<p class="lp-head-p">
Ships as a CLI, npm package, browser WebAssembly build, Docker
image and C library.
</p>
<div class="lp-actions">
<span class="lp-brackets">
<a href="#pricing" class="lp-btn lp-btn--primary">
<span>See pricing</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
<a
href="https://kura.bentopdf.com"
target="_blank"
rel="noopener"
class="lp-btn lp-btn--ghost"
>
<i data-lucide="external-link"></i>
<span>Visit website</span>
</a>
<a
href="https://github.com/alam00000/bentopdf-kura"
target="_blank"
rel="noopener"
class="lp-btn lp-btn--ghost"
>
<i data-lucide="github"></i>
<span>View on GitHub</span>
</a>
</div>
</div>
</div>
<div class="lp-grid lp-grid--4">
<div class="lp-cell lp-stat lp-cell--accent lp-reveal">
<b>25</b><span>conformance targets</span>
</div>
<div class="lp-cell lp-stat lp-cell--white lp-reveal">
<b>396</b><span>bundled preflight profiles</span>
</div>
<div class="lp-cell lp-stat lp-cell--hatch lp-reveal">
<b>0</b><span>false findings in conformance testing</span>
</div>
<div class="lp-cell lp-stat lp-cell--raised lp-reveal">
<b>5</b><span>form factors, one engine</span>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-pad--tight">
<div class="lp-note lp-reveal">
<i data-lucide="badge-check"></i>
<p>
<strong
>Open source, self-hosting and internal use stay free.</strong
>
Kura is licensed under the AGPL-3.0. If your project is
AGPL-compatible, or you run Kura as-is for yourself, you never
need a commercial license. Commercial licenses are only for
shipping Kura inside closed-source software.
</p>
</div>
</div>
</div>
</section>
<section id="pricing" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Commercial</span>
<span class="line dim">Licenses</span>
</h2>
<p class="lp-head-p">
Per product, billed annually. Every tier includes all updates
and new releases while active.
</p>
</div>
</div>
<div class="lp-grid lp-grid--4">
<div class="lp-cell lp-tier lp-reveal">
<h3>Solo</h3>
<p class="lp-tier-for">
One developer, under $100k annual revenue
</p>
<div class="lp-tier-price"><b>$99</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_NLuLBtXkHXyelWdxPy6zarYyNJqMd4NF1PWJI2sEeZa"
class="lp-btn lp-btn--ghost lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Solo</a
>
</div>
<div class="lp-cell lp-tier lp-cell--accent lp-reveal">
<h3>Indie</h3>
<p class="lp-tier-for">Companies under $1M annual revenue</p>
<div class="lp-tier-price"><b>$199</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>Unlimited developers</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_MMPcXzyyNvVfX3Fuvac1eGgG7pTgDiIDB2RCs4HUbxx"
class="lp-btn lp-btn--primary lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Indie</a
>
</div>
<div class="lp-cell lp-tier lp-reveal">
<h3>Business</h3>
<p class="lp-tier-for">Companies at $1M annual revenue or more</p>
<div class="lp-tier-price"><b>$499</b><span>/ year</span></div>
<ul>
<li><i data-lucide="check"></i>One closed-source product</li>
<li><i data-lucide="check"></i>Unlimited developers</li>
<li><i data-lucide="check"></i>All updates while active</li>
<li><i data-lucide="check"></i>Priority email support</li>
</ul>
<a
href="https://buy.polar.sh/polar_cl_r4HLyDK1rda9cERr31Jbg99m3GEVDC2K4ooFo4FtoFb"
class="lp-btn lp-btn--ghost lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Get Business</a
>
</div>
<div class="lp-cell lp-tier lp-reveal">
<h3>OEM</h3>
<p class="lp-tier-for">
Redistribution, reselling as an SDK, or offering Kura as a
service
</p>
<div class="lp-tier-price">
<span class="lp-tier-from">from</span><b>$1,999</b
><span>/ year</span>
</div>
<ul>
<li><i data-lucide="check"></i>Redistribution rights</li>
<li><i data-lucide="check"></i>Terms shaped to your product</li>
<li><i data-lucide="check"></i>Priority support</li>
</ul>
<a
href="mailto:[email protected]?subject=Kura%20commercial%20license%20OEM"
class="lp-btn lp-btn--ghost lp-btn--sm"
>Contact us</a
>
</div>
</div>
</div>
</section>
<section id="license-details" class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Commercial license</span>
<span class="line dim">details</span>
</h2>
</div>
</div>
<div class="lp-pad">
<div class="grid grid-cols-1 gap-6">
<div class="lp-panel">
<h3
class="text-xl font-semibold text-white mb-4 flex items-center gap-3"
>
<i data-lucide="package" class="w-6 h-6 text-indigo-400"></i>
Delivery &amp; licensing model
</h3>
<ul class="space-y-3 text-gray-400">
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
><strong class="text-white"
>No license key is required or provided.</strong
>
Kura intentionally does not use license keys, to
streamline deployment and reduce operational
friction.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Upon purchase you receive a ZIP archive containing the
complete Kura source code.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Because Kura is open source, every release and every
update can always be downloaded from our
<a
href="https://github.com/alam00000/bentopdf-kura/releases"
target="_blank"
rel="noopener noreferrer"
class="text-indigo-400 hover:underline"
>GitHub releases page</a
>.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>The source code provided is identical to the code
published in our public open-source repository.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="x-circle"
class="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5"
></i>
<span
><strong class="text-white">No refunds.</strong> Under no
circumstances shall a refund be made after purchase.</span
>
</li>
</ul>
<p class="mt-4 text-gray-300">
<strong class="text-white">GitHub repository:</strong>
<a
href="https://github.com/alam00000/bentopdf-kura"
target="_blank"
rel="noopener noreferrer"
class="text-indigo-400 hover:underline"
>github.com/alam00000/bentopdf-kura</a
>
</p>
</div>
<div class="lp-panel">
<h3
class="text-xl font-semibold text-white mb-4 flex items-center gap-3"
>
<i
data-lucide="file-text"
class="w-6 h-6 text-indigo-400"
></i>
Invoicing
</h3>
<ul class="space-y-3 text-gray-400">
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>We use <strong class="text-white">Polar</strong> for
payments, which
<strong class="text-white"
>automatically sends invoices</strong
>
via email after purchase.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="check-circle"
class="w-5 h-5 text-green-400 flex-shrink-0 mt-0.5"
></i>
<span
>Polar handles
<strong class="text-white">VAT invoices</strong> for
businesses in applicable regions.</span
>
</li>
<li class="flex items-start gap-3">
<i
data-lucide="info"
class="w-5 h-5 text-blue-400 flex-shrink-0 mt-0.5"
></i>
<span
>For VAT invoices, select
<strong class="text-white"
>"I'm purchasing as a business"</strong
>
during checkout and enter your billing address and Tax/VAT
number.</span
>
</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<section id="compare" class="lp-sec">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">What each tier</span>
<span class="line dim">covers</span>
</h2>
<p class="lp-head-p">
Every tier lets you ship Kura inside one closed-source product.
The tiers differ by who you are, how many developers you have,
and whether Kura is passed on to anyone else.
</p>
</div>
</div>
<div class="lp-pad--tight lp-reveal">
<div class="overflow-x-auto">
<table class="lp-table lp-compare">
<thead>
<tr>
<th></th>
<th>Solo</th>
<th>Indie</th>
<th>Business</th>
<th>OEM</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Who it's for</th>
<td>One developer, under $100k annual revenue</td>
<td>Companies under $1M annual revenue</td>
<td>Companies at $1M annual revenue or more</td>
<td>
Anyone redistributing, reselling or hosting the engine
</td>
</tr>
<tr>
<th scope="row">Annual price</th>
<td>$99</td>
<td>$199</td>
<td>$499</td>
<td>from $1,999</td>
</tr>
<tr>
<th scope="row">Developers covered</th>
<td>One developer</td>
<td>Unlimited</td>
<td>Unlimited</td>
<td>Discussed with you</td>
</tr>
<tr>
<th scope="row">Closed-source products covered</th>
<td>One</td>
<td>One</td>
<td>One</td>
<td>Terms shaped to your product</td>
</tr>
<tr>
<th scope="row">Updates while active</th>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">Support</th>
<td>Email</td>
<td>Email</td>
<td>Priority email</td>
<td>Priority</td>
</tr>
<tr>
<th scope="row">
Redistribute inside someone else's product
</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">Resell as an SDK</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
<tr>
<th scope="row">Offer Kura as a hosted service</th>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-no"><i data-lucide="x"></i></td>
<td class="lp-yes"><i data-lucide="check"></i></td>
</tr>
</tbody>
</table>
</div>
<p class="lp-table-note">
Redistribution, reselling and hosting are what separate OEM from
the rest. If Kura only ships inside your own closed-source
product, the choice between Solo, Indie and Business is purely a
question of your size.
</p>
</div>
</div>
</section>
<section class="lp-sec lp-band">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">License</span>
<span class="line dim">Terms</span>
</h2>
</div>
</div>
<div class="lp-grid lp-grid--2">
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="package"></i></span>
<h3>Per product</h3>
<p>
A license covers one shipped product. A second product needs a
second license, or ask about covering your whole catalogue at
OEM.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="refresh-cw"></i></span>
<h3>Updates included</h3>
<p>
Every release published while your license is active is yours.
If you let it lapse, you keep a perpetual right to the last
version you received.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="unlock"></i></span>
<h3>No AGPL obligations</h3>
<p>
The commercial license replaces the AGPL for your product. You
ship closed source, with no requirement to publish your changes
or your application.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="shield-check"></i></span>
<h3>Clean provenance</h3>
<p>
Kura is written and owned by BentoPDF, and every third-party
component it links, including qpdf, PDFium and FreeType, is
permissively licensed. No copyleft surprises in your supply
chain.
</p>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-head lp-head--center">
<div>
<h2 class="lp-h2">
<span class="line">Frequently Asked</span>
<span class="line dim">Questions</span>
</h2>
</div>
</div>
<div class="lp-faq-wrap">
<div id="faq-accordion" class="lp-faq lp-reveal">
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>Do I need a commercial license?</span>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
Only if you ship Kura inside closed-source software.
Open-source projects under an AGPL-compatible license,
self-hosting, and internal use are all free under the
AGPL-3.0.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>Does the BentoPDF commercial license cover Kura?</span>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
No. Kura is a separate project with its own license. The
BentoPDF app license does not grant any rights to Kura, and
a Kura license does not cover BentoPDF.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>What happens if my company outgrows its tier?</span>
<i data-lucide="plus" class="faq-icon"></i>
</button>
<div
class="faq-answer max-h-0 overflow-hidden transition-all duration-300 ease-in-out"
>
<p>
You move up to the matching tier at your next renewal.
Nothing retroactive. Growing past a threshold mid-term never
invalidates your current license.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-cta">
<h2 class="lp-h2">Not sure which tier fits?</h2>
<p>
Tell us what you're building and we'll tell you what it costs. No
calls required.
</p>
<div class="lp-cta-actions">
<span class="lp-brackets">
<a
href="mailto:[email protected]?subject=Kura%20commercial%20license%20pricing"
class="lp-btn lp-btn--primary"
>
<span>[email protected]</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
</div>
</div>
</div>
</section>
</div>
{{> footer }}
<script type="module" src="src/js/utils/lucide-init.ts"></script>
<script type="module" src="src/js/main.ts"></script>
<script type="module" src="src/js/mobileMenu.ts"></script>
<script type="module" src="src/js/landing.ts"></script>
<!-- JSON-LD Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Kura - PDF/A, PDF/UA &amp; PDF/X Conversion Engine | BentoPDF",
"url": "https://www.bentopdf.com/kura"
}
</script>
</body>
</html>
+1133 -1081
View File
File diff suppressed because it is too large Load Diff
+49 -3
View File
@@ -43,6 +43,21 @@ http {
return 301 /uk$1;
}
if ($request_uri ~ ^/en/?(\?.*)?$) {
return 301 /$1;
}
if ($request_uri ~ ^/en/([A-Za-z0-9].*)$) {
return 301 /$1;
}
if ($request_uri ~ ^(/(?:ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/src/pages/([a-z0-9][a-z0-9-]*)\.html(\?.*)?$) {
return 301 $1/$2$3;
}
if ($request_uri ~ ^(/(?:ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/change-text-color(?:\.html)?/?(\?.*)?$) {
return 301 $1/text-color$2;
}
if ($request_uri ~ ^/tools/$) {
return 301 /tools;
}
@@ -68,18 +83,45 @@ http {
return 301 /docs/$1$2;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pt|ru|sv|tr|vi|zh|zh-TW|uk|ja))?/index\.html(\?.*)?$) {
if ($request_uri ~ ^/docs/tools/pdf-to-docx/?(\?.*)?$) {
return 301 /docs/tools/pdf-to-word$1;
}
if ($request_uri ~ ^/docs/tools/decrypt-pdf/?(\?.*)?$) {
return 301 /docs/tools/unlock-pdf$1;
}
if ($request_uri ~ ^/docs/tools/encrypt-pdf/?(\?.*)?$) {
return 301 /docs/tools/protect-pdf$1;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/index\.html(\?.*)?$) {
return 301 $1/$2;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pt|ru|sv|tr|vi|zh|zh-TW|uk|ja))?/([a-z0-9][a-z0-9-]*)\.html(\?.*)?$) {
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/pdf-to-docx(?:\.html)?/?(\?.*)?$) {
return 301 $1/pdf-to-word$2;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/decrypt-pdf(?:\.html)?/?(\?.*)?$) {
return 301 $1/unlock-pdf$2;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/encrypt-pdf(?:\.html)?/?(\?.*)?$) {
return 301 $1/protect-pdf$2;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))?/([a-z0-9][a-z0-9-]*)\.html(\?.*)?$) {
return 301 $1/$2$3;
}
if ($request_uri ~ ^(/(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja))/([a-z0-9][a-z0-9-]*)/(\?.*)?$) {
return 301 $1/$2$3;
}
if ($request_uri ~ ^/((?!(?:en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja|docs|blog)/)[a-z0-9][a-z0-9-]*)/(\?.*)?$) {
return 301 /$1$2;
}
location ~ /src/pages/ {
return 404;
}
location ~ ^/(en|ar|be|da|de|es|fr|id|it|ko|nl|pt|ru|sv|tr|vi|zh|zh-TW|uk|ja)(/.*)?$ {
location ~ ^/(en|ar|be|da|de|es|fr|id|it|ko|nl|pl|pt|ru|sk|sv|tr|vi|zh|zh-TW|uk|ja)(/.*)?$ {
try_files $uri $uri/ $uri.html =404;
expires 5m;
}
@@ -106,6 +148,10 @@ http {
expires 1y;
}
location ~ ^/((sw\.js|coherentpdf\.browser\.min\.js|qpdf\.wasm)$|(workers|pdfjs-viewer|pdfjs-annotation-viewer)/) {
expires epoch;
}
location ~* \.(wasm|wasm\.gz|data|data\.gz)$ {
expires 1y;
}
+20 -19
View File
@@ -1,12 +1,12 @@
{
"name": "bento-pdf",
"version": "2.8.7",
"version": "2.8.9",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "bento-pdf",
"version": "2.8.7",
"version": "2.8.9",
"license": "AGPL-3.0-only",
"dependencies": {
"@fontsource/cedarville-cursive": "^5.2.7",
@@ -27,8 +27,8 @@
"@types/node-forge": "^1.3.14",
"@types/papaparse": "^5.5.2",
"archiver": "^7.0.1",
"bentopdf-pdfium": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-8ff5002c6cd5.tgz",
"bentopdf-viewer": "file:vendor/bentopdf-viewer/bentopdf-viewer-8ff5002c6cd5.tgz",
"bentopdf-pdfium": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-051abe5b72a9.tgz",
"bentopdf-viewer": "file:vendor/bentopdf-viewer/bentopdf-viewer-051abe5b72a9.tgz",
"blob-stream": "^0.1.3",
"bwip-js": "^4.8.0",
"cropperjs": "^1.6.2",
@@ -102,6 +102,7 @@
"husky": "^9.1.7",
"jsdom": "^28.1.0",
"lint-staged": "^16.3.1",
"marked": "^16.4.2",
"prettier": "^3.8.1",
"typescript": "~5.9.3",
"typescript-eslint": "^8.56.1",
@@ -4271,15 +4272,15 @@
"license": "MIT"
},
"node_modules/bentopdf-pdfium": {
"version": "0.0.0-8ff5002c6cd5",
"resolved": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-8ff5002c6cd5.tgz",
"integrity": "sha512-bVDsJNwtan8snh2cibjvRNIjuM1UBvfKNd6OEn9RNYTZddH0JF4ekQBVSMbY9aVBNbNGCIwKPeaAFbrF8Jzvhw==",
"version": "0.0.0-051abe5b72a9",
"resolved": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-051abe5b72a9.tgz",
"integrity": "sha512-ctM0Y6MEVa2UQO8+uD7/GYzl7GWyrEJJxzUJURHJttJKzxn02DtNpyEWgcLREXnfaFIo7UJ4j5sFmioVGi/WpQ==",
"license": "AGPL-3.0"
},
"node_modules/bentopdf-viewer": {
"version": "2.9.1",
"resolved": "file:vendor/bentopdf-viewer/bentopdf-viewer-8ff5002c6cd5.tgz",
"integrity": "sha512-ucbsz9WeAf2Y8VIsR32dNl/NSgidMi85UFUKgWvUE4i93c4ds0P3u4imfg/T641iWAahbK75agNDfhuuzp2AFQ==",
"resolved": "file:vendor/bentopdf-viewer/bentopdf-viewer-051abe5b72a9.tgz",
"integrity": "sha512-A+utjVLgFdE/MA2mlPLimi7jXdhMXex6RozdcJbt0YgNj4tt1W3ihk9QYbVi3dUHm2zfwGPntE+CSn1d8OGoZw==",
"license": "MIT",
"dependencies": {
"preact": "^10.17.0",
@@ -6392,9 +6393,9 @@
}
},
"node_modules/fflate": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz",
"integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==",
"license": "MIT"
},
"node_modules/file-entry-cache": {
@@ -6743,13 +6744,13 @@
"license": "MIT"
},
"node_modules/handlebars": {
"version": "4.7.9",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz",
"integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==",
"version": "4.7.10",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.10.tgz",
"integrity": "sha512-P5VJMVM7qgBn6vjXMw8WG9uVI+ncf2pi72j4de4yz5ZULLj2RGqLYaKOYGsgyrViQ0tePOVlN1tDCCXXtFqXKg==",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.5",
"minimist": "^1.2.8",
"neo-async": "^2.6.2",
"source-map": "^0.6.1",
"wordwrap": "^1.0.0"
@@ -10419,9 +10420,9 @@
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
"integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
+5 -4
View File
@@ -1,12 +1,12 @@
{
"name": "bento-pdf",
"private": true,
"version": "2.8.8",
"version": "2.8.10",
"license": "AGPL-3.0-only",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build && NODE_OPTIONS='--max-old-space-size=3072' node scripts/generate-i18n-pages.mjs && node scripts/generate-sitemap.mjs && node scripts/generate-security-headers.mjs && node scripts/seo-audit.mjs",
"build": "node scripts/generate-blog.mjs && node scripts/generate-static-tool-links.mjs && tsc && vite build && node scripts/enhance-seo-pages.mjs && NODE_OPTIONS='--max-old-space-size=3072' node scripts/generate-i18n-pages.mjs && node scripts/generate-sitemap.mjs && node scripts/generate-security-headers.mjs && node scripts/seo-audit.mjs",
"seo-audit": "node scripts/seo-audit.mjs",
"build:with-docs": "npm run build && npm run docs:build && node scripts/include-docs-in-dist.js",
"build:gzip": "COMPRESSION_MODE=g npm run build",
@@ -60,6 +60,7 @@
"husky": "^9.1.7",
"jsdom": "^28.1.0",
"lint-staged": "^16.3.1",
"marked": "^16.4.2",
"prettier": "^3.8.1",
"typescript": "~5.9.3",
"typescript-eslint": "^8.56.1",
@@ -90,8 +91,8 @@
"@types/node-forge": "^1.3.14",
"@types/papaparse": "^5.5.2",
"archiver": "^7.0.1",
"bentopdf-pdfium": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-8ff5002c6cd5.tgz",
"bentopdf-viewer": "file:vendor/bentopdf-viewer/bentopdf-viewer-8ff5002c6cd5.tgz",
"bentopdf-pdfium": "file:vendor/bentopdf-pdfium/bentopdf-pdfium-051abe5b72a9.tgz",
"bentopdf-viewer": "file:vendor/bentopdf-viewer/bentopdf-viewer-051abe5b72a9.tgz",
"blob-stream": "^0.1.3",
"bwip-js": "^4.8.0",
"cropperjs": "^1.6.2",
+132 -44
View File
@@ -193,7 +193,7 @@
<h3 class="font-semibold text-white">JSON to PDF</h3>
<p class="text-gray-400 text-sm">Data to PDF</p>
</a>
<a href="/pdf-to-docx" class="tool-card">
<a href="/pdf-to-word" class="tool-card">
<i
class="ph ph-microsoft-word-logo text-4xl text-indigo-400 mb-2"
></i>
@@ -422,59 +422,147 @@
Frequently Asked Questions
</h2>
<div class="space-y-4">
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are these pdf converter tools really free?
<i class="ph ph-caret-down text-xl"></i>
<div class="faq-list">
<details class="faq-d">
<summary class="faq-d-q">
Which file formats can I convert to PDF?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Yes! All BentoPDF pdf converter tools are 100% free with no hidden
fees, no premium tiers, and no subscription required. Use
unlimited tools, unlimited times.
<p class="faq-d-a">
Word, Excel, and PowerPoint files (including the older DOC, XLS,
and PPT formats), OpenDocument text, spreadsheets, presentations,
and drawings, RTF, plain text, Markdown, CSV, XML, ebooks in EPUB,
MOBI, FB2, and CBZ, XPS, Publisher, Visio, WordPerfect, Microsoft
Works, Apple Pages, and images in JPG, PNG, HEIC, WebP, TIFF, BMP,
SVG, and PSD. If you have a folder of mixed image types,
<a
href="/image-to-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Images to PDF</a
>
accepts them all in one batch and puts each image on its own page.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are my files private and secure?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
What can I convert a PDF into?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Absolutely! All processing happens entirely in your browser. Your
files never leave your device, are never uploaded to servers.
Complete privacy guaranteed.
<p class="faq-d-a">
Word (DOCX), Excel (XLSX), CSV, plain text, Markdown, SVG, and
page images in JPG, PNG, WebP, TIFF, or BMP, with multi-page PDFs
delivered as a ZIP holding one image per page. For long-term
archiving,
<a
href="/pdf-to-pdfa"
class="text-indigo-300 hover:text-indigo-400"
>PDF to PDF/A</a
>
outputs PDF/A-1b, 2b, or 3b, and a separate tool turns a color PDF
into a grayscale one.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Is there a file size limit?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
Does PDF to Word keep the layout?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No file size limits! Process files of any size. Browser-based
processing means no artificial limitations.
<p class="faq-d-a">
<a
href="/pdf-to-word"
class="text-indigo-300 hover:text-indigo-400"
>PDF to Word</a
>
rebuilds the document with its text, basic formatting, and general
layout, and it can convert a batch of files in one run. Pages with
multiple columns, embedded forms, or heavy graphics may not come
across perfectly, so expect to tidy those up in your word
processor.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Do I need to install software?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
Why is my converted Word or text file empty?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No installation required! All tools are web-based and work
directly in your browser. Just open the page and start using -
works on any device.
<p class="faq-d-a">
The PDF is almost certainly a scan, which stores each page as a
picture with no text layer, so PDF to Word, PDF to Text, and the
table converters have nothing to pull out. Run the file through
<a href="/ocr-pdf" class="text-indigo-300 hover:text-indigo-400"
>OCR PDF</a
>
first to add a searchable text layer, then convert the result.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Can I get tables out of a PDF into Excel?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/pdf-to-excel"
class="text-indigo-300 hover:text-indigo-400"
>PDF to Excel</a
>
scans every page for tables and writes each one to its own
worksheet, named after the page it came from. If it reports that
no tables were found, the PDF lays the data out as loose text
rather than a real table structure; PDF to CSV and Extract Tables
rely on the same detection, so try PDF to Text to grab the raw
content instead.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Do I need Microsoft Office installed to convert Word, Excel, or
PowerPoint files?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
No. Those files, along with Publisher, Visio, RTF, and
WordPerfect, are converted by a LibreOffice engine that runs
inside your browser, so there's nothing to install;
<a
href="/word-to-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Word to PDF</a
>, for example, also takes DOC, ODT, and RTF directly. The engine
downloads once per session, which makes the first conversion take
a few seconds longer than the ones after it.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Will converting a PDF to JPG or PNG lose quality?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
Pages are rendered at twice their native size, so a letter-size
page becomes an image of roughly 1,224 by 1,584 pixels.
<a
href="/pdf-to-jpg"
class="text-indigo-300 hover:text-indigo-400"
>PDF to JPG</a
>
is lossy with a quality slider that defaults to 90%, which keeps a
good balance between sharpness and file size; PDF to PNG and PDF
to TIFF are lossless, and PNG adds a scale control from 1x to 3x
for print-quality output.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Are my files uploaded to a server during conversion?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
No. Every converter on this page, including the Office, ebook, and
image converters, runs as WebAssembly inside your browser tab, so
the file is read from your device and the result is written
straight back to it. There's no upload queue, no server copy, and
nothing to delete afterward.
</p>
</details>
</div>
+134 -46
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Primary Meta Tags -->
<title>PDF Editor - Free Online PDF Editor Tools | BentoPDF</title>
<title>PDF Editing Tools - All Free Online PDF Editors | BentoPDF</title>
<meta
name="description"
content="Edit, modify, and enhance your PDFs with 25+ free online tools. Compress, rotate, crop, add watermarks, page numbers, and more. Privacy-first PDF editing in your browser."
@@ -25,7 +25,7 @@
<meta property="og:url" content="https://www.bentopdf.com/pdf-editor" />
<meta
property="og:title"
content="PDF Editor - Free Online PDF Editor Tools | BentoPDF"
content="PDF Editing Tools - All Free Online PDF Editors | BentoPDF"
/>
<meta
property="og:description"
@@ -41,7 +41,10 @@
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="PDF Editor - Free Online Tools" />
<meta
name="twitter:title"
content="PDF Editing Tools - All Free Online PDF Editors | BentoPDF"
/>
<meta
name="twitter:description"
content="Edit, modify, and enhance your PDFs with 25+ free online tools. Compress, rotate, crop, add watermarks, page numbers, and more. Privacy-first PDF editing in your browser."
@@ -296,59 +299,144 @@
Frequently Asked Questions
</h2>
<div class="space-y-4">
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are these pdf editor tools really free?
<i class="ph ph-caret-down text-xl"></i>
<div class="faq-list">
<details class="faq-d">
<summary class="faq-d-q">
Can I change the existing text in a PDF?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Yes! All BentoPDF pdf editor tools are 100% free with no hidden
fees, no premium tiers, and no subscription required. Use
unlimited tools, unlimited times.
<p class="faq-d-a">
<a
href="/edit-pdf-text"
class="text-indigo-300 hover:text-indigo-400"
>Edit PDF Text</a
>
lets you click any paragraph and rewrite it in place, with the
surrounding text reflowing as you type and controls for fonts and
styling. For adding new text boxes, comments, highlights, shapes,
or images on top of the page, use the general Edit PDF tool
instead.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are my files private and secure?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
What can I do in the Edit PDF tool?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Absolutely! All processing happens entirely in your browser. Your
files never leave your device, are never uploaded to servers.
Complete privacy guaranteed.
<p class="faq-d-a">
The
<a href="/edit-pdf" class="text-indigo-300 hover:text-indigo-400"
>Edit PDF</a
>
toolbar covers highlighting, underlining, strikethrough, freehand
drawing, text and comments, shapes and images, permanent
redaction, and full-text search. It keeps the original PDF
structure, so fonts, layouts, and form fields stay intact, and you
can keep up to 10 documents open in tabs and switch between them.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Is there a file size limit?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
How do I make a PDF smaller?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No file size limits! Process files of any size. Browser-based
processing means no artificial limitations.
<p class="faq-d-a">
<a
href="/compress-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Compress PDF</a
>
offers two methods. Condense strips unused structure, downsamples
images to a target DPI, and subsets fonts while keeping text
selectable and links working; Photon re-renders each page as a
JPEG, which saves more on scans and photo-heavy files but leaves
text unselectable. Start with the Balanced level and only step up
to Aggressive or Extreme if the file is still too large.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Do I need to install software?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
Which editing tools keep my text selectable?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No installation required! All tools are web-based and work
directly in your browser. Just open the page and start using -
works on any device.
<p class="faq-d-a">
Page-level tools such as Rotate, Organize, Delete Pages,
Background Color, and Remove Annotations work on the PDF structure
and leave text searchable. Invert Colors, Change Text Color, and
PDF to Greyscale re-render every page as an image, so text in
their output can no longer be selected or searched, and the Photon
compression mode does the same. If you need searchable text after
one of those, run the result through
<a href="/ocr-pdf" class="text-indigo-300 hover:text-indigo-400"
>OCR PDF</a
>.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Can I add page numbers or a header and footer?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/page-numbers"
class="text-indigo-300 hover:text-indigo-400"
>Page Numbers</a
>
puts a number in any of six positions on every page, in plain or
"page X of Y" style, with your choice of font size and color.
Header and Footer adds text to six slots per page (left, center,
and right at top and bottom), understands {page} and {total}
placeholders so a footer like "Page {page} of {total}" fills in
correctly on each page, and can be limited to a page range.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Can I put a watermark on every page?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/add-watermark"
class="text-indigo-300 hover:text-indigo-400"
>Add Watermark</a
>
stamps text or an image onto your pages, and you position it by
dragging on a live preview, then set opacity, rotation, and size.
A tiled mode repeats the mark across the whole page so it's much
harder to crop out, and you can apply one watermark to all pages,
restrict it to a page range, or set a different watermark on each
page.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Can I rotate a single page, or fix a slightly tilted scan?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/rotate-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Rotate PDF</a
>
shows a thumbnail of every page with its own left and right
buttons for 90-degree turns, plus a bulk control for the whole
document. For a scan that's off by a few degrees, Rotate by Custom
Degrees accepts any angle, per page or for all pages at once.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Does editing a PDF here upload it anywhere?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
No. The editor and every other tool on this page run as
WebAssembly inside your browser, so the file is opened, changed,
and saved on your own device without a server in between. Nothing
is stored, so there's no copy to delete when you're done.
</p>
</details>
</div>
+129 -43
View File
@@ -251,59 +251,145 @@
Frequently Asked Questions
</h2>
<div class="space-y-4">
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are these pdf merge & split tools really free?
<i class="ph ph-caret-down text-xl"></i>
<div class="faq-list">
<details class="faq-d">
<summary class="faq-d-q">
How do I combine several PDFs into one file?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Yes! All BentoPDF pdf merge & split tools are 100% free with no
hidden fees, no premium tiers, and no subscription required. Use
unlimited tools, unlimited times.
<p class="faq-d-a">
Add two or more files to
<a href="/merge-pdf" class="text-indigo-300 hover:text-indigo-400"
>Merge PDF</a
>
and drag them into the order you want. File Mode joins whole
documents, with an optional page range per file such as 1-3, 5,
while Page Mode lays out every page as a thumbnail so you can
build the exact sequence. There's no cap on file count or total
pages, and pages are copied without re-encoding, so quality
doesn't change.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are my files private and secure?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
What are the different ways to split a PDF?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Absolutely! All processing happens entirely in your browser. Your
files never leave your device, are never uploaded to servers.
Complete privacy guaranteed.
<p class="faq-d-a">
<a href="/split-pdf" class="text-indigo-300 hover:text-indigo-400"
>Split PDF</a
>
has six modes: page ranges, visual selection from thumbnails, even
or odd pages only, one file per page, splitting at bookmark
boundaries with a choice of bookmark level, and fixed chunks of
every N pages. A single range downloads as one PDF, while multiple
ranges or per-page output arrive as a ZIP. Bookmark mode needs a
PDF that actually contains bookmarks.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Is there a file size limit?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
What's the difference between Split, Extract Pages, and Delete
Pages?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No file size limits! Process files of any size. Browser-based
processing means no artificial limitations.
<p class="faq-d-a">
<a
href="/extract-pages"
class="text-indigo-300 hover:text-indigo-400"
>Extract Pages</a
>
keeps only the pages you list and saves them as a new file, Delete
Pages removes the pages you list and keeps everything else, and
Split breaks one document into several files. Extract and Delete
are inverses of each other, so pick whichever needs the shorter
list of page numbers.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Do I need to install software?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
Can I reorder pages or duplicate a page?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No installation required! All tools are web-based and work
directly in your browser. Just open the page and start using -
works on any device.
<p class="faq-d-a">
<a
href="/organize-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Organize PDF</a
>
shows every page as a draggable thumbnail with a duplicate and a
delete button on each one. You can also type a complete page order
such as 3, 1, 2, 4 to rearrange everything in one step, and
Reverse Pages flips an entire document, or a batch of them, in one
click.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
My scanner put all the front pages first and all the backs after.
How do I fix the order?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/duplex-collate"
class="text-indigo-300 hover:text-indigo-400"
>Duplex Collate</a
>
handles exactly that: it interleaves the two blocks into front 1,
back 1, front 2, back 2 order, with an option to reverse the back
block for stacks that were flipped before the second pass. If the
fronts and backs are in two separate files, Alternate Merge
interleaves pages from multiple PDFs the same way.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
How do I print a PDF as a folded booklet?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/pdf-booklet"
class="text-indigo-300 hover:text-indigo-400"
>PDF Booklet</a
>
reorders the pages into saddle-stitch imposition and shows a
preview of each sheet before you download. Print the result
double-sided with "flip on short edge", fold the stack in half,
and staple at the spine; if the page count isn't a multiple of
four, blank pages are added automatically to fill the last sheet.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Can I see what changed between two versions of a PDF?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/compare-pdfs"
class="text-indigo-300 hover:text-indigo-400"
>Compare PDFs</a
>
pairs up the pages of two documents and highlights differences in
text, images, annotations, headers and footers, and formatting, in
either a side-by-side or an overlay view. Filters let you hide the
change types you don't care about, OCR can be switched on for
scanned documents, and the comparison can be exported as a PDF
report.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Are my files uploaded when I merge or split them?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
No. Merging, splitting, and reordering run as WebAssembly inside
your browser, so the files are read from your disk and the result
is written back to it without passing through a server. That holds
for large scans and multi-file batches too.
</p>
</details>
</div>
+143 -45
View File
@@ -111,12 +111,12 @@
<div
class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4"
>
<a href="/encrypt-pdf" class="tool-card">
<a href="/protect-pdf" class="tool-card">
<i class="ph ph-lock text-4xl text-indigo-400 mb-2"></i>
<h3 class="font-semibold text-white">Encrypt PDF</h3>
<p class="text-gray-400 text-sm">Add password</p>
</a>
<a href="/decrypt-pdf" class="tool-card">
<a href="/unlock-pdf" class="tool-card">
<i class="ph ph-lock-open text-4xl text-indigo-400 mb-2"></i>
<h3 class="font-semibold text-white">Decrypt PDF</h3>
<p class="text-gray-400 text-sm">Remove password</p>
@@ -226,59 +226,157 @@
Frequently Asked Questions
</h2>
<div class="space-y-4">
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are these PDF security tools really free?
<i class="ph ph-caret-down text-xl"></i>
<div class="faq-list">
<details class="faq-d">
<summary class="faq-d-q">
What's the difference between protecting a PDF with a password and
restricting its permissions?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Yes! All BentoPDF PDF security tools are 100% free with no hidden
fees, no premium tiers, and no subscription required. Use
unlimited tools, unlimited times.
<p class="faq-d-a">
A user password, set with
<a
href="/protect-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Protect PDF</a
>, is required to open the file at all. Permissions are flags
stored inside the encryption that control what a reader can do
after opening, such as printing, copying, editing, annotating, or
filling forms, and they only take effect when an owner password is
set. Change Permissions lets you allow or deny each action
individually, while Protect PDF applies the strictest set as soon
as you add an owner password.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Are my files private and secure?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
How strong is the password protection?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
Absolutely! All processing happens entirely in your browser. Your
files never leave your device and are never uploaded to servers.
Complete privacy is guaranteed.
<p class="faq-d-a">
Protect PDF and Change Permissions use 256-bit AES encryption, the
PDF 2.0 standard, applied by QPDF running in your browser. The
encryption itself isn't practical to brute-force, so the weak
point is the password: use a long passphrase and send it through a
different channel than the file. Permission flags are a separate
matter, since they rely on the reader honoring them and some
third-party tools ignore them.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Is there a file size limit?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
Can I remove a password from a PDF if I don't know it?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No file size limits! Process files of any size. Browser-based
processing means no artificial limitations.
<p class="faq-d-a">
No.
<a
href="/unlock-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Unlock PDF</a
>
needs the password and then saves a copy with no encryption or
restrictions left, and none of the tools crack or brute-force
passwords. For a file that opens fine but blocks printing or
copying, use Remove Restrictions instead, which asks for the owner
password if the file has one.
</p>
</details>
<details class="bg-gray-800 p-5 rounded-lg border border-gray-700">
<summary
class="cursor-pointer font-semibold text-white flex items-center justify-between"
>
Do I need to install software?
<i data-lucide="chevron-down" class="w-5 h-5"></i>
<details class="faq-d">
<summary class="faq-d-q">
What's the difference between Sign PDF and a digital signature?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="mt-3 text-gray-400">
No installation required! All tools are web-based and work
directly in your browser. Just open the page and start using -
works on any device.
<p class="faq-d-a">
Sign PDF places a drawn, typed, or uploaded signature image on the
page, with an option to flatten it so nobody can move or delete it
later.
<a
href="/digital-sign-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Digital Signature</a
>
applies a cryptographic signature with your own X.509 certificate
(.pfx, .p12, or .pem), which proves who signed and that the file
hasn't changed since, and Validate Signature checks signatures
already in a file. Certificate signing may need an internet
connection to fetch the certificate chain, and self-signed
certificates will show warnings in Adobe Reader.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
How do I redact text so it's actually gone?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
Use the redaction tool in the
<a href="/edit-pdf" class="text-indigo-300 hover:text-indigo-400"
>PDF Editor</a
>. Marking text or an area only flags it. Once you apply the
redaction, the marked content is permanently removed from the page
instead of just being covered with a box, and if you download with
marks that haven't been applied yet, the editor offers to apply
them first. When you redact selected text, copies of it in the
file's properties, bookmarks, comments, and attachments are
removed on download too, unless the file is encrypted. Area
redactions have no text to search for, so if the file's
properties, comments, or attachments could reveal the same
information, run Remove Metadata or Sanitize PDF on the result as
well.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
What's the difference between Remove Metadata and Sanitize PDF?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/remove-metadata"
class="text-indigo-300 hover:text-indigo-400"
>Remove Metadata</a
>
strips only the document properties: title, author, dates,
producer, XMP data, document IDs, and application-specific data,
and it leaves pages, forms, links, and bookmarks untouched.
Sanitize PDF goes further and can also flatten forms and delete
annotations, embedded JavaScript, attachments, layers, links, and
structure tags, with each item selectable. Both are irreversible,
so keep your original file.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
What does flattening a PDF do, and when should I use it?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
<a
href="/flatten-pdf"
class="text-indigo-300 hover:text-indigo-400"
>Flatten PDF</a
>
burns form fields and annotations (comments, highlights, stamps,
sticky notes, signature fields) into the page content, so they
look the same but can no longer be edited, moved, or removed. Use
it after a form is filled in or a signature is placed and before
you send the file, because there's no way to unflatten. Text stays
selectable and searchable, and bookmarks are kept.
</p>
</details>
<details class="faq-d">
<summary class="faq-d-q">
Are my passwords, certificates, or files sent to a server?
<i data-lucide="plus" class="faq-d-icon"></i>
</summary>
<p class="faq-d-a">
No. Encrypting, unlocking, sanitizing, and signing all run as
WebAssembly in your browser, so the document, the password you
type, and your certificate's private key stay on your device. The
one network exception is Digital Signature, which may contact your
certificate authority's servers to fetch the certificate chain;
the document itself is still never sent.
</p>
</details>
</div>
+18
View File
@@ -0,0 +1,18 @@
/*
Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'unsafe-eval' blob: https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/ https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/assets/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' blob: https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-src 'self' blob:; frame-ancestors 'self'; form-action 'self'
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=(), interest-cohort=()
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: credentialless
Cross-Origin-Resource-Policy: cross-origin
/docs
! Content-Security-Policy
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-DQUgNM9X0iH2019NkUxeBvnBoEoRKkHBc/I0iLqPNPA=' 'sha256-La1r0VSk0Po4KFI0duEKhmPu+u0I416JW3oONqtdf4M='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'
/docs/*
! Content-Security-Policy
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-DQUgNM9X0iH2019NkUxeBvnBoEoRKkHBc/I0iLqPNPA=' 'sha256-La1r0VSk0Po4KFI0duEKhmPu+u0I416JW3oONqtdf4M='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

+8 -5
View File
@@ -212,7 +212,7 @@
},
"browserBased": {
"question": "كيف تحافظ المعالجة عبر المتصفح على أمانك؟",
"answer": "بالعمل بالكامل داخل متصفحك، يضمن BentoPDF أن ملفاتك لا تغادر جهازك أبدًا. هذا يلغي مخاطر اختراق الخوادم أو تسريب البيانات أو الوصول غير المصرح به. ملفاتك تبقى ملكك — دائمًا."
"answer": "بالعمل بالكامل داخل متصفحك، يضمن BentoPDF أن ملفاتك لا تغادر جهازك أبدًا. هذا يلغي مخاطر اختراق الخوادم أو تسريب البيانات أو الوصول غير المصرح به. ملفاتك تبقى ملكك، دائمًا."
},
"analytics": {
"question": "هل تستخدمون ملفات تعريف الارتباط أو التحليلات لتتبعي؟",
@@ -222,7 +222,7 @@
"testimonials": {
"title": "ماذا يقول",
"users": "مستخدمونا",
"say": ""
"say": " "
},
"support": {
"title": "أعجبك عملنا؟",
@@ -239,7 +239,9 @@
"legal": "قانوني",
"termsAndConditions": "الشروط والأحكام",
"privacyPolicy": "سياسة الخصوصية",
"followUs": "تابعنا"
"followUs": "تابعنا",
"privacyShort": "الخصوصية",
"termsShort": "الشروط"
},
"merge": {
"title": "دمج ملفات PDF",
@@ -287,12 +289,13 @@
},
"mission": {
"title": "مهمتنا",
"titleDim": " ",
"description": "تقديم أشمل مجموعة أدوات PDF تحترم خصوصيتك ولا تطلب أي مقابل. نؤمن بأن أدوات المستندات الأساسية يجب أن تكون متاحة للجميع، في كل مكان، بدون عوائق."
},
"philosophy": {
"label": "فلسفتنا الأساسية",
"title": "الخصوصية أولاً. دائمًا.",
"description": "في عصر أصبحت فيه البيانات سلعة، نتبع نهجًا مختلفًا. تتم جميع معالجة أدوات Bentopdf محليًا في متصفحك. هذا يعني أن ملفاتك لا تلمس خوادمنا أبدًا، ولا نرى مستنداتك، ولا نتتبع ما تفعله. مستنداتك تبقى خاصة تمامًا وبشكل قاطع. إنها ليست مجرد ميزة؛ إنها أساسنا."
"description": "في عصر أصبحت فيه البيانات سلعة، نتبع نهجًا مختلفًا. تتم جميع معالجة أدوات BentoPDF محليًا في متصفحك. هذا يعني أن ملفاتك لا تلمس خوادمنا أبدًا، ولا نرى مستنداتك، ولا نتتبع ما تفعله. مستنداتك تبقى خاصة تمامًا وبشكل قاطع. إنها ليست مجرد ميزة؛ إنها أساسنا."
},
"whyBentopdf": {
"title": "لماذا",
@@ -315,7 +318,7 @@
},
"cta": {
"title": "مستعد للبدء؟",
"description": "انضم إلى آلاف المستخدمين الذين يثقون بـ Bentopdf لاحتياجات مستنداتهم اليومية. اختبر الفرق الذي يمكن أن تحدثه الخصوصية والأداء.",
"description": "انضم إلى آلاف المستخدمين الذين يثقون بـ BentoPDF لاحتياجات مستنداتهم اليومية. اختبر الفرق الذي يمكن أن تحدثه الخصوصية والأداء.",
"button": "استكشف جميع الأدوات"
}
},
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "انقر على أي فقرة وحرّرها في مكانها مع إعادة تدفق فوري للنص والخطوط والأنماط.",
"saved": "تم حفظ ملف PDF بنجاح! ({{size}} كيلوبايت)",
"failedToLoad": "تعذّر تحميل محرّر نصوص PDF.",
"loadingFonts": "جارٍ تحميل الخطوط...",
"fontsUnavailable": "تعذّر تنزيل خط مطلوب لبعض الأحرف. تحقّق من اتصالك وحاول مرة أخرى، وإلا فقد لا تظهر هذه الأحرف بشكل صحيح في ملف PDF المحفوظ.",
"howToUpload": "رفع ملف PDF",
"howToClick": "انقر على فقرة",
"howToRestyle": "غيّر تنسيق أي شيء",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "نعم! فعّل خيار \"التكرار\" وستتكرر صفحات التراكب على جميع صفحات الملف الأساسي. العلامة المائية ذات الصفحة الواحدة ستُطبق على كل صفحة.",
"faqPrivacyQuestion": "هل ملفاتي خاصة وآمنة؟",
"faqPrivacyAnswer": "بالتأكيد! تتم جميع المعالجة في متصفحك. لا تغادر ملفاتك جهازك أبداً، مما يضمن خصوصية كاملة."
},
"unlockPdf": {
"name": "فك تشفير PDF",
"subtitle": "فتح PDF بإزالة حماية كلمة المرور."
},
"protectPdf": {
"name": "تشفير PDF",
"subtitle": "قفل PDF بإضافة كلمة مرور."
}
}
+18 -15
View File
@@ -5,7 +5,7 @@
"contact": "Кантакты",
"licensing": "Ліцэнзія",
"allTools": "Усе інструменты",
"docs": "Docs",
"docs": "Дакументацыя",
"openMainMenu": "Адкрыць галоўнае меню",
"language": "Мова",
"searchLanguage": "Пошук мовы…",
@@ -59,7 +59,7 @@
"title": "Пачніце працу з",
"toolsLabel": "інструментамі",
"subtitle": "Націсніце на інструмент, каб адкрыць запампоўшчык",
"searchPlaceholder": "Пошук (напр., \"выдаліць\", \"сціснуць\"...)",
"searchPlaceholder": "Пошук (напр., «выдаліць», «сціснуць»...)",
"backToTools": "Назад да інструментаў",
"firstLoadNotice": "Першае адкрыццё займае крыху часу, пакуль загружаецца рухавік канвертацыі. Потым усё будзе адкрывацца імгненна."
},
@@ -100,11 +100,11 @@
},
"howItWorks": {
"title": "Як гэта працуе",
"step1Title": "Загрузіць файл",
"step1Title": "Запампуйце файл",
"step1": "Націсніце або перацягніце файл, каб пачаць",
"step2Title": "Апрацоўка",
"step2Title": "Апрацуйце",
"step2": "Націсніце кнопку апрацоўкі",
"step3Title": "Спампаваць",
"step3Title": "Спампуйце",
"step3": "Імгненна захавайце апрацаваны файл"
},
"relatedTools": {
@@ -175,7 +175,7 @@
},
"ccpa": {
"title": "Адпаведнасць CCPA",
"description": "Дае жыхарам Каліфорніі правы ведаць, як збіраецца, выкарыстоўваецца і перадаецца іх персанальная інфармацыя."
"description": "Дае жыхарам Каліфорніі правы адносна таго, як збіраецца, выкарыстоўваецца і перадаецца іх персанальная інфармацыя."
},
"hipaa": {
"title": "Адпаведнасць HIPAA",
@@ -211,7 +211,7 @@
"answer": "Звычайна інструменты PDF запампоўваюць вашы файлы на сервер для апрацоўкі. BentoPDF ніколі так не робіць. Мы выкарыстоўваем бяспечныя сучасныя вэб-тэхналогіі, каб апрацоўваць вашы файлы непасрэдна ў браўзеры. Гэта азначае большую хуткасць, лепшую прыватнасць і поўны спакой."
},
"browserBased": {
"question": "Чаму апрацоўка ў браўзеры - гэта бяспечна?",
"question": "Чаму апрацоўка ў браўзеры — гэта бяспечна?",
"answer": "Працуючы цалкам у браўзеры, BentoPDF гарантуе, што вашы файлы ніколі не пакінуць вашу прыладу. Гэта ліквідуе рызыкі ўзлому сервераў, уцечак даных або несанкцыянаванага доступу. Вашы файлы застаюцца вашымі — заўсёды."
},
"analytics": {
@@ -239,7 +239,9 @@
"legal": "Прававая інфармацыя",
"termsAndConditions": "Умовы выкарыстання",
"privacyPolicy": "Палітыка прыватнасці",
"followUs": "Сачыце за намі"
"followUs": "Сачыце за намі",
"privacyShort": "Прыватнасць",
"termsShort": "Умовы"
},
"merge": {
"title": "Аб'яднаць PDF",
@@ -286,7 +288,8 @@
"noCompromises": "Без кампрамісаў."
},
"mission": {
"title": "Наша місія",
"title": "Наша",
"titleDim": "місія",
"description": "Даць найбольш поўны набор інструментаў PDF, які шануе вашу прыватнасць і ніколі не патрабуе аплаты. Мы лічым, што неабходныя інструменты для дакументаў павінны быць даступнымі ўсім, паўсюль, без бар'ераў."
},
"philosophy": {
@@ -302,7 +305,7 @@
},
"free": {
"title": "Цалкам бясплатна",
"description": "Без пробных версій, падпісак, схаваных плацяжоў і без \"прэміум\" функцый. Мы верым, што магутныя інструменты PDF павінны быць грамадскай карысцю, а не цэнтрам прыбытку."
"description": "Без пробных версій, падпісак, схаваных плацяжоў і без «прэміум» функцый. Мы верым, што магутныя інструменты PDF павінны быць грамадскай карысцю, а не цэнтрам прыбытку."
},
"noAccount": {
"title": "Не патрэбны ўліковы запіс",
@@ -350,12 +353,12 @@
"download": "Спампаваць:",
"downloadSelected": "Спампаваць выбранае",
"exportPdf": "Экспартаваць PDF",
"uploadPdfFiles": "Выбраць PDF або выявы",
"dragAndDrop": "Перацягніце PDF або выявы сюды або націсніце, каб выбраць",
"uploadPdfFiles": "Выбраць PDF або відарысы",
"dragAndDrop": "Перацягніце PDF або відарысы сюды або націсніце, каб выбраць",
"selectFiles": "Выбраць файлы",
"dropToAdd": "Адпусціце PDF або выявы для дабаўлення",
"convertingImages": "Канвертацыя выяў у PDF...",
"failedToConvertImages": "Не ўдалося канвертаваць выявы ў PDF.",
"dropToAdd": "Адпусціце PDF або відарысы, каб дадаць",
"convertingImages": "Канвертаванне відарысаў у PDF...",
"failedToConvertImages": "Не ўдалося канвертаваць відарысы ў PDF.",
"renderingPages": "Апрацоўка старонак...",
"actions": {
"duplicatePage": "Дубляваць гэту старонку",
+259 -248
View File
@@ -19,7 +19,8 @@
"name": "Аб'яднаць PDF",
"subtitle": "Аб'яднаць некалькі PDF у адзін файл. Закладкі захоўваюцца.",
"retainPageLabels": "Захоўваць арыгінальныя пазнакі старонак з кожнага файла",
"retainPageLabelsHint": "Выключана (па змаўчанні): аб’яднаны PDF выкарыстоўвае натуральную нумарацыю 1–N. Уключана: арыгінальныя пазнакі старонак кожнага файла захоўваюцца (могуць узнікнуць паўторы)."
"retainPageLabelsHint": "Выключана (прадвызначана): аб'яднаны PDF выкарыстоўвае натуральную нумарацыю 1–N. Уключана: арыгінальныя пазнакі старонак кожнага файла захоўваюцца (могуць узнікнуць паўторы).",
"removeDuplicateFonts": "Выдаліць дублікаты шрыфтоў"
},
"splitPdf": {
"name": "Падзяліць PDF",
@@ -32,7 +33,7 @@
"condense": "Condense (Рэкамендуецца)",
"photon": "Photon (Для PDF з вялікай колькасцю фота)",
"condenseInfo": "Condense выкарыстоўвае прасунутае сцісканне: выдаляе лішняе, аптымізуе відарысы, паднаборы шрыфтоў. Найлепш пасуе для большасці PDF.",
"photonInfo": "Photon ператварае старонкі ў відарысы. Для PDF з вялікай колькасцю фота або сканіраваных PDF.",
"photonInfo": "Photon канвертуе старонкі ў відарысы. Для PDF з вялікай колькасцю фота або сканаваных PDF.",
"photonWarning": "Папярэджанне: стане немагчыма вылучыць тэкст, і перастануць працаваць спасылкі.",
"levelLabel": "Узровень сціскання",
"light": "Лёгкі (Захаванне якасці)",
@@ -57,24 +58,26 @@
},
"editPdfText": {
"name": "Рэдагаваць тэкст PDF",
"subtitle": "Націсніце на любы абзац і рэдагуйце яго на месцы з імгненнай перакампаноўкай тэксту, шрыфтамі і стылямі.",
"subtitle": "Рэдагаваць любы абзац на месцы — з імгненнай перакампаноўкай тэксту, шрыфтамі і стылямі.",
"saved": "PDF паспяхова захаваны! ({{size}} КБ)",
"failedToLoad": "Не ўдалося загрузіць рэдактар тэксту PDF.",
"howToUpload": "Загрузіць PDF",
"loadingFonts": "Загрузка шрыфтоў...",
"fontsUnavailable": "Не ўдалося спампаваць шрыфт, патрэбны для некаторых сімвалаў. Праверце злучэнне і паспрабуйце яшчэ раз, інакш гэтыя сімвалы могуць адлюстроўвацца няправільна ў захаваным PDF.",
"howToUpload": "Запампуйце PDF",
"howToClick": "Націсніце на абзац",
"howToRestyle": "Змяніце стыль",
"relatedPdfEditor": "Каментуйце і разметьце PDF",
"relatedSignPdf": "Намалюйце, увядзіце або загрузіце подпіс",
"relatedWatermark": "Нанясіце тэкст або выявы",
"relatedStamps": "Размяшчайце штампы на старонках",
"relatedCompress": "Паменшыце памер файла",
"relatedPdfEditor": "Анатаваць і размячаць PDF",
"relatedSignPdf": "Намаляваць, увесці або запампаваць подпіс",
"relatedWatermark": "Нанесці тэкст або відарысы",
"relatedStamps": "Размясціць штампы на старонках",
"relatedCompress": "Паменшыць памер файла",
"relatedOrganizeName": "Упарадкаваць PDF",
"relatedOrganize": "Мяняйце парадак і кіруйце старонкамі",
"relatedOrganize": "Змяніць парадак і кіраваць старонкамі",
"open": "Адкрыць",
"export": "Экспарт",
"filterAll": "Усе",
"filterText": "Тэкст",
"filterImages": "Выявы",
"filterImages": "Відарысы",
"filterShapes": "Фігуры",
"addText": "Дадаць тэкст",
"langAuto": "Аўта",
@@ -83,7 +86,7 @@
"next": "Далей",
"replace": "Замяніць",
"replaceAll": "Замяніць усё",
"emptyState": "Адкрыйце PDF, каб рэдагаваць тэкст, выявы і фігуры.",
"emptyState": "Адкрыйце PDF, каб рэдагаваць тэкст, відарысы і фігуры.",
"choosePdf": "Выберыце PDF…",
"font": "Шрыфт",
"systemFonts": "Сістэмныя шрыфты",
@@ -96,32 +99,32 @@
"direction": "Напрамак",
"dirAuto": "Аўта",
"pathStroke": "Абвядзенне контуру",
"tipBackToUpload": "Назад да загрузкі",
"tipBackToUpload": "Назад да запампоўкі",
"tipOpenAnotherPdf": "Адкрыць іншы PDF",
"tipExportS": "Экспарт (⌘S)",
"tipUndoZ": "Адмяніць (⌘Z)",
"tipRedoZ": "Паўтарыць (⇧⌘Z)",
"tipUndoZ": "Адрабіць (⌘Z)",
"tipRedoZ": "Узнавіць (⇧⌘Z)",
"tipFileDetails": "Звесткі пра файл",
"tipEditExistingContent": "Рэдагаваць наяўнае змесціва",
"tipWhatTheEditToolTouchesNarrowTheScopeOnBus": "На што дзейнічае інструмент рэдагавання — звузьце вобласць на насычаных старонках",
"tipClickThePageToAddATextBox": "Націсніце на старонку, каб дадаць тэкставае поле",
"tipSpellCheckLanguage": "Мова праверкі правапісу",
"tipFindAndReplace": "Знайсці і замяніць",
"tipAddAnImage": "Дадаць выяву",
"tipCopyThisPageSTextInReadingOrder": "Скапіяваць тэкст старонкі ў парадку чытання",
"tipAddAnImage": "Дадаць відарыс",
"tipCopyThisPageSTextInReadingOrder": "Скапіраваць тэкст старонкі ў парадку чытання",
"tipCheckTheSpellingOfThisPage": "Праверыць правапіс на гэтай старонцы",
"tipShowOrHideTheFormatPanel": "Паказаць або схаваць панэль фарматавання",
"phReplaceWith": "Замяніць на",
"tipAddToYourDictionary": "Дадаць у слоўнік",
"tipClose": "Закрыць",
"phFind": "Знайсці",
"tipPreviousMatch": "Папярэдні супадзенне",
"tipPreviousMatch": "Папярэдняе супадзенне",
"tipNextMatch": "Наступнае супадзенне",
"tipRotateLeft90": "Павярнуць на 90° улева",
"tipRotateRight90": "Павярнуць на 90° управа",
"tipFlipHorizontal": "Адлюстраваць гарызантальна",
"tipFlipVertical": "Адлюстраваць вертыкальна",
"tipReplaceThisImageKeepingItsPlacement": "Замяніць выяву, захаваўшы размяшчэнне",
"tipReplaceThisImageKeepingItsPlacement": "Замяніць відарыс, захаваўшы размяшчэнне",
"tipAlternateTextForAccessibilityTaggedPdfs": "Альтэрнатыўны тэкст для даступнасці (тэгаваныя PDF)",
"tipBringToFront": "На пярэдні план",
"tipSendToBack": "На задні план",
@@ -160,7 +163,7 @@
"tipRightToLeft": "Справа налева",
"tipStrokeColor": "Колер абвядзення",
"tipStrokeWidth": "Таўшчыня абвядзення",
"tipZoomPresets": "Прадусталёўкі маштабу",
"tipZoomPresets": "Перадвызначаныя налады маштабу",
"tipZoomOut": "Паменшыць",
"tipZoomIn": "Павялічыць",
"tipFitPage": "Па памеры старонкі",
@@ -199,12 +202,12 @@
"editBookmarks": {
"name": "Рэдагаваць закладкі",
"subtitle": "Дадаць, рэдагаваць, імпартаваць, выдаліць і выняць закладкі PDF.",
"autoExtractExisting": "Аўтаматычна выманне існуючых закладак",
"autoExtractExisting": "Аўтаматычнае выманне наяўных закладак",
"importSectionTitle": "Або імпартаваць закладкі",
"csvFormat": "Фармат CSV: загаловак,старонка,узровень",
"jsonFormat": "Фармат JSON",
"uploadCsvAction": "Націсніце, каб загрузіць CSV",
"uploadJsonAction": "Націсніце, каб загрузіць JSON",
"uploadCsvAction": "Націсніце, каб запампаваць CSV",
"uploadJsonAction": "Націсніце, каб запампаваць JSON",
"orDragHere": "або перацягніце сюды"
},
"tableOfContents": {
@@ -213,15 +216,15 @@
"titleLabel": "Загаловак зместу",
"fontSize": "Памер шрыфта",
"fontFamily": "Сямейства шрыфтоў",
"addBookmark": "Додати закладку для сторінки змісту",
"addBookmark": "Дадаць закладку для старонкі зместу",
"generateButton": "Стварыць змест",
"selectPdfFirst": "Спачатку выберыце PDF-файл.",
"statusReadingFileMainThread": "Читання файлу (головний потік)...",
"statusReadingFileMainThread": "Чытанне файла (галоўны паток)...",
"statusGenerating": "Стварэнне зместу...",
"errorReadingFileWithMessage": "Помилка читання файлу: {{message}}",
"errorReadingFileWithMessage": "Памылка чытання файла: {{message}}",
"successGeneratedDownloadStarted": "Змест паспяхова створаны! Спампоўванне распачалося.",
"workerErrorWithMessage": "Помилка: {{message}}",
"workerErrorOccurred": "Адбылася памылка працаўніка. Падрабязнасці ў кансолі."
"workerErrorWithMessage": "Памылка: {{message}}",
"workerErrorOccurred": "Адбылася памылка апрацоўшчыка. Падрабязнасці ў кансолі."
},
"pageNumbers": {
"name": "Нумары старонак",
@@ -238,18 +241,18 @@
"howLabelsWorkStep4": "Уключыце працяг нумарацыі, калі адно правіла выкарыстоўвае разарваны дыяпазон, напрыклад 1-9,30-40 або няцотныя старонкі.",
"labelRulesTitle": "Правілы пазнак",
"addRule": "Дадаць правіла",
"removeExistingLabels": "Выдаліць існуючыя пазнакі старонак перад прымяненнем гэтых правіл",
"removeExistingLabels": "Выдаліць наяўныя пазнакі старонак перад прымяненнем гэтых правіл",
"cpdfNote": "Гэты інструмент выкарыстоўвае CoherentPDF у вашым браўзеры. Калі CoherentPDF не наладжаны, вам будзе прапанавана наладзіць яго ў наладах WASM.",
"processButton": "Дадаць пазнакі старонак",
"howItWorksUploadTitle": "Запампаваць файл",
"howItWorksUploadDescription": "Выберыце PDF, які хочаце перапазначыць.",
"howItWorksDefineTitle": "Вызначыць правілы",
"howItWorksUploadTitle": "Запампуйце файл",
"howItWorksUploadDescription": "Выберыце PDF, у якім хочаце змяніць пазнакі.",
"howItWorksDefineTitle": "Вызначце правілы",
"howItWorksDefineDescription": "Наладзьце адно або некалькі правіл пазнак старонак з дыяпазонамі, стылямі, прэфіксамі і пачатковымі значэннямі.",
"howItWorksDownloadTitle": "Спампаваць",
"howItWorksDownloadTitle": "Спампуйце",
"howItWorksDownloadDescription": "Захавайце абноўлены PDF з новымі пазнакамі старонак.",
"relatedToolsTitle": "Звязаныя інструменты PDF",
"faqWhatIsQuestion": "Што такое пазнака старонкі?",
"faqWhatIsAnswer": "Пазнака старонкі - гэта нумарацыя, якую чытальнікі PDF паказваюць у мініяцюрах, навігацыі па старонках і дыялогах друку. Яна не друкуе новы тэкст на самой старонцы.",
"faqWhatIsAnswer": "Пазнака старонкі — гэта нумарацыя, якую чытальнікі PDF паказваюць у мініяцюрах, навігацыі па старонках і дыялогах друку. Яна не друкуе новы тэкст на самой старонцы.",
"faqMixQuestion": "Ці можна спалучаць рымскія і звычайныя лічбы?",
"faqMixAnswer": "Так. Дадайце некалькі правіл, напрыклад 1-4 з LowercaseRoman і 5-20 з DecimalArabic.",
"faqPrivacyQuestion": "Ці застаюцца мае файлы прыватнымі?",
@@ -301,12 +304,12 @@
},
"invertColors": {
"name": "Інвертаваць колеры",
"subtitle": "Стварыць версію PDF у \"цёмнай тэме\"."
"subtitle": "Стварыць версію PDF у «цёмнай тэме»."
},
"scannerEffect": {
"name": "Эфект сканера",
"subtitle": "Зрабіць PDF падобным да адсканаванага дакумента.",
"scanSettings": "Налады сканіравання",
"scanSettings": "Налады сканавання",
"colorspace": "Каляровая прастора",
"gray": "Градацыі шэрага",
"border": "Рамка",
@@ -331,7 +334,7 @@
"temperature": "Тэмпература",
"tint": "Адценне",
"gamma": "Гама",
"sepia": "Сэпія",
"sepia": "Сепія",
"processButton": "Ужыць рэгуліроўкі колеру"
},
"backgroundColor": {
@@ -348,7 +351,7 @@
"usernameLabel": "Імя для штампа",
"usernamePlaceholder": "Увядзіце сваё імя (для штампаў)",
"usernameHint": "Гэта імя з'явіцца на створаных вамі штампах.",
"saveButton": "Захаваць PDF з пячаткай"
"saveButton": "Захаваць PDF са штампамі"
},
"removeAnnotations": {
"name": "Выдаліць анатацыі",
@@ -357,9 +360,9 @@
"pdfFormFiller": {
"name": "Запоўніць форму PDF",
"subtitle": "Запоўніць форму непасрэдна ў браўзеры. Таксама падтрымліваюцца формы XFA.",
"uploadHint": "Завантажте PDF з полями форми. Заповніть їх безпосередньо у переглядачі нижче, потім натисніть кнопку, щоб зберегти та завантажити заповнену форму. Також підтримуються форми XFA.",
"uploadHint": "Запампуйце PDF з палямі формы. Запоўніце іх непасрэдна ў праглядальніку ніжэй, а затым націсніце кнопку, каб захаваць і спампаваць запоўненую форму. Таксама падтрымліваюцца формы XFA.",
"xfaNoteTitle": "Заўвага па формах XFA:",
"xfaNoteDescription": "XFA (XML Forms Architecture) — застарілий формат, який підтримується лише певними PDF-переглядачами, такими як BentoPDF та Firefox. Якщо ви відкриваєте XFA PDF в іншому ПЗ і бачите порожні сторінки або відсутність полів форми, це означає, що цей переглядач не підтримує XFA. Щоб правильно переглядати та заповнювати форми XFA, використовуйте Firefox або заповнювач форм BentoPDF."
"xfaNoteDescription": "XFA (XML Forms Architecture) — састарэлы фармат, што падтрымліваецца толькі некаторымі праглядальнікамі PDF, напрыклад BentoPDF і Firefox. Калі адкрыць PDF XFA ў іншай праграме і ўбачыць пустыя старонкі або адсутнасць палёў формы, гэта азначае, што праглядальнік не падтрымлівае XFA. Для правільнага прагляду і запаўнення XFA выкарыстоўвайце Firefox або праграму запаўнення формаў BentoPDF."
},
"createPdfForm": {
"name": "Стварыць форму PDF",
@@ -403,33 +406,33 @@
"textToPdf": {
"name": "Тэкст у PDF",
"subtitle": "Канвертаваць звычайны тэкставы файл у PDF.",
"uploadFiles": "Загрузіць файлы",
"uploadFiles": "Запампаваць файлы",
"typeText": "Увесці тэкст",
"acceptedFormats": "Текстові файли (.txt)",
"acceptedFormats": "Тэкставыя файлы (.txt)",
"fontFamily": "Сямейства шрыфтоў",
"fontSize": "Памер шрыфта",
"textColor": "Колер тэксту",
"pageSize": "Памер старонкі",
"rtlAutoDetectNote": "Мови RTL (арабська, урду, перська тощо) автоматично визначаються, і напрямок тексту регулюється.",
"rtlAutoDetectNote": "Мовы з напрамкам справа налева (арабская, урду, персідская і інш.) вызначаюцца аўтаматычна, і кірунак тэксту карэктуецца.",
"createButton": "Стварыць PDF"
},
"jsonToPdf": {
"name": "JSON у PDF",
"subtitle": "Канвертаваць файлы JSON у фармат PDF.",
"noteLabel": "Примітка:",
"noteText": "Підтримуються лише JSON-файли, створені інструментом PDF→JSON. Стандартні JSON-файли від інших інструментів не працюють.",
"acceptedFormats": "Кілька JSON-файлів",
"noteLabel": "Нататка:",
"noteText": "Падтрымліваюцца толькі файлы JSON, створаныя інструментам канвертавання PDF у JSON. Стандартныя файлы JSON з іншых інструментаў не будуць працаваць.",
"acceptedFormats": "Некалькі файлаў JSON",
"status": {
"selectAtLeastOne": "Виберіть принаймні 1 JSON-файл",
"selectedReady": "Вибрано {{count}} файл(ів). Готово до конвертації!",
"readingFiles": "Читання файлів (головний потік)...",
"converting": "Конвертація JSON-файлів у PDF...",
"readError": "Помилка читання файлів: {{message}}",
"creatingZip": "Створення ZIP-файлу...",
"success": "JSON-файли успішно конвертовано в PDF! Завантаження ZIP розпочато.",
"zipError": "Помилка створення ZIP: {{message}}",
"workerError": "Помилка Worker: {{message}}",
"getStarted": "Виберіть JSON-файли, щоб почати"
"selectAtLeastOne": "Выберыце хаця б 1 файл JSON",
"selectedReady": "Выбрана файлаў: {{count}}. Гатова да канвертавання!",
"readingFiles": "Чытанне файлаў (галоўны паток)...",
"converting": "Пераўтварэнне файлаў JSON у PDF...",
"readError": "Памылка чытання файлаў: {{message}}",
"creatingZip": "Стварэнне ZIP-файла...",
"success": "Файлы JSON паспяхова пераўтвораны ў PDF! Пачалося спампоўванне ZIP.",
"zipError": "Памылка стварэння ZIP: {{message}}",
"workerError": "Памылка апрацоўшчыка: {{message}}",
"getStarted": "Выберыце файлы JSON, каб пачаць"
}
},
"pdfToJpg": {
@@ -515,7 +518,8 @@
"noFile": "Няма файла",
"noFileExplanation": "Спачатку запампуйце файл PDF.",
"conversionSuccess": "PDF паспяхова канвертаваны ў TIFFs!",
"conversionError": "Не ўдалося канвертаваць PDF у TIFF. Файл можа быць пашкоджаны."
"conversionError": "Не ўдалося канвертаваць PDF у TIFF. Файл можа быць пашкоджаны.",
"conversionOutOfMemory": "У браўзеры скончылася памяць падчас канвертавання. Паспрабуйце знізіць DPI або адключыць параметр шматстаронкавага TIFF, каб канвертаваць старонкі па адной."
}
},
"pdfToCbz": {
@@ -555,19 +559,19 @@
"pdfToJson": {
"name": "PDF у JSON",
"subtitle": "Канвертаваць файлы PDF у фармат JSON.",
"convertButton": "Конвертувати у JSON",
"convertButton": "Пераўтварыць у JSON",
"status": {
"selectAtLeastOne": "Виберіть принаймні 1 PDF-файл",
"selectedReady": "Вибрано {{count}} файл(ів). Готово до конвертації!",
"checkingEncrypted": "Перевірка зашифрованих PDF...",
"readingFiles": "Читання файлів (головний потік)...",
"converting": "Конвертація PDF у JSON...",
"readError": "Помилка читання файлів: {{message}}",
"creatingZip": "Створення ZIP-файлу...",
"success": "PDF успішно конвертовано у JSON! Завантаження ZIP розпочато.",
"zipError": "Помилка створення ZIP: {{message}}",
"workerError": "Помилка Worker: {{message}}",
"getStarted": "Виберіть PDF-файли, щоб почати"
"selectAtLeastOne": "Выберыце хаця б 1 файл PDF",
"selectedReady": "Выбрана файлаў: {{count}}. Гатова да канвертавання!",
"checkingEncrypted": "Праверка зашыфраваных PDF...",
"readingFiles": "Чытанне файлаў (галоўны паток)...",
"converting": "Пераўтварэнне PDF у JSON...",
"readError": "Памылка чытання файлаў: {{message}}",
"creatingZip": "Стварэнне ZIP-файла...",
"success": "PDF паспяхова пераўтвораны ў JSON! Пачалося спампоўванне ZIP.",
"zipError": "Памылка стварэння ZIP: {{message}}",
"workerError": "Памылка апрацоўшчыка: {{message}}",
"getStarted": "Выберыце файлы PDF, каб пачаць"
}
},
"ocrPdf": {
@@ -577,62 +581,62 @@
"searchLanguagesPlaceholder": "Пошук моў...",
"selectedLabel": "Выбрана:",
"none": "Няма",
"advancedSettingsSummary": "Додаткові налаштування (рекомендовано для покращення точності)",
"advancedSettingsSummary": "Пашыраныя налады (рэкамендуецца для павышэння дакладнасці)",
"resolutionLabel": "Раздзяляльная здольнасць",
"resolutionStandard": "Стандартная (192 DPI)",
"resolutionHigh": "Высокая (288 DPI)",
"resolutionUltra": "Ультра (384 DPI)",
"binarizeLabel": "Бінаризувати зображення (покращити контраст для чистих сканів)",
"embedFullFontsLabel": "Вбудувати повні шрифти (більший файл, краща сумісність)",
"whitelistPresetLabel": "Передустановка білого списку символів",
"whitelistNone": "Немає (усі символи)",
"whitelistAlphanumeric": "Літери та цифри + базова пунктуація",
"whitelistNumbersCurrency": "Числа + Символи валют",
"whitelistLettersOnly": "Лише літери (A-Z, a-z)",
"whitelistNumbersOnly": "Лише числа (0-9)",
"whitelistInvoice": "Рахунок/Чек (числа, $, ., -, /)",
"whitelistForms": "Форми (літери та цифри + загальні символи)",
"whitelistCustom": "Користувацький...",
"whitelistHelp": "Будуть розпізнані лише ці символи. Залиште порожнім для всіх символів.",
"whitelistInputLabel": "Білий список символів (необов'язково)",
"binarizeLabel": "Бінарызаваць відарыс (павысіць кантраст для чыстых сканаў)",
"embedFullFontsLabel": "Убудаваць поўныя шрыфты (большы файл, лепшая сумяшчальнасць)",
"whitelistPresetLabel": "Перадвызначаная налада спісу дазволеных сімвалаў",
"whitelistNone": "Няма (усе сімвалы)",
"whitelistAlphanumeric": "Лічбавыя і літарныя сімвалы + асноўныя знакі прыпынку",
"whitelistNumbersCurrency": "Лічбы + сімвалы валют",
"whitelistLettersOnly": "Толькі літары (A-Z, a-z)",
"whitelistNumbersOnly": "Толькі лічбы (0-9)",
"whitelistInvoice": "Рахунак/квітанцыя (лічбы, $, ., -, /)",
"whitelistForms": "Формы (літары і лічбы + агульнаўжывальныя сімвалы)",
"whitelistCustom": "Уласны…",
"whitelistHelp": "Распазнаюцца толькі гэтыя сімвалы. Пакіньце поле пустым, каб дазволіць усе сімвалы.",
"whitelistInputLabel": "Спіс дазволеных сімвалаў (неабавязкова)",
"whitelistInputPlaceholder": "напр., abcdefghijklmnopqrstuvwxyz0123456789$.,",
"startButton": "Запусціць OCR",
"progressInitializing": "Ініцыялізацыя...",
"resultsTitle": "OCR завершаны",
"resultsDescription": "Ваш PDF з пошуком готовий. Ви також можете скопіювати або завантажити витягнутий текст нижче.",
"copyToClipboard": "Капіяваць у буфер абмену",
"resultsDescription": "PDF з магчымасцю пошуку гатовы. Ніжэй можна скапіраваць або спампаваць выняты тэкст.",
"copyToClipboard": "Капіраваць у буфер абмену",
"downloadTxt": "Спампаваць як .txt",
"downloadSearchablePdf": "Спампаваць пошукавы PDF",
"statusPrefix": "Статус: {{status}}",
"availabilityInvalidConfig": "Цей реліз не надає дійсних мов OCR. Перебудуйте його з VITE_TESSERACT_AVAILABLE_LANGUAGES, встановленим на дійсні коди Tesseract.",
"availabilityBundles": "Цей реліз містить OCR для: {{languages}}.",
"availabilityInvalidConfig": "Гэта разгортванне не прапануе ніводнай дапушчальнай мовы OCR. Перазбярыце яго, задаўшы VITE_TESSERACT_AVAILABLE_LANGUAGES дапушчальнымі кодамі Tesseract.",
"availabilityBundles": "Гэта разгортванне ўключае OCR для: {{languages}}.",
"noLanguagesAvailable": "У гэтым выпуску няма даступных моў OCR.",
"noLanguagesTitle": "Мовы не выбраны",
"noLanguagesMessage": "Выберыце прынамсі адну мову для OCR.",
"noFileTitle": "Няма файла",
"noFileMessage": "Спачатку загрузіце PDF-файл.",
"noFileMessage": "Спачатку запампуйце PDF-файл.",
"languageUnavailableTitle": "Мова OCR недаступная",
"ocrErrorTitle": "Памылка OCR",
"ocrErrorMessage": "Падчас працэсу OCR адбылася памылка. Магчыма, працаўнік не загрузіўся. Паспрабуйце яшчэ раз.",
"ocrErrorMessage": "Падчас працэсу OCR адбылася памылка. Магчыма, апрацоўшчык не загрузіўся. Паспрабуйце яшчэ раз.",
"howItWorksTitle": "Як гэта працуе:",
"extractTextLabel": "Витягти текст:",
"extractTextDescription": "Використовує Tesseract OCR для розпізнавання тексту на сканованих зображеннях або PDF.",
"searchableOutputLabel": "Вивід з можливістю пошуку:",
"searchableOutputDescription": "Створює новий PDF з невидимим текстовим шаром, роблячи ваш документ повністю придатним для пошуку, зберігаючи оригінальний вигляд.",
"characterFilteringLabel": "Фільтрація символів:",
"characterFilteringDescription": "Використовуйте білі списки для фільтрації небажаних символів і покращення точності для конкретних типів документів (рахунки, форми тощо).",
"multiLanguageSupportLabel": "Багатомовна підтримка:",
"multiLanguageSupportDescription": "Виберіть кілька мов для документів зі змішаним мовним вмістом."
"extractTextLabel": "Выняць тэкст:",
"extractTextDescription": "Выкарыстоўвае OCR Tesseract для распазнавання тэксту са сканаваных відарысаў або PDF.",
"searchableOutputLabel": "Вынік з магчымасцю пошуку:",
"searchableOutputDescription": "Стварае новы PDF з нябачным тэкставым слоем, робячы дакумент цалкам даступным для пошуку і захоўваючы яго першапачатковы выгляд.",
"characterFilteringLabel": "Фільтраванне сімвалаў:",
"characterFilteringDescription": "Дазваляе адфільтроўваць непатрэбныя сімвалы праз спісы дазволеных і павышае дакладнасць для пэўных тыпаў дакументаў (рахункаў, формаў і інш.).",
"multiLanguageSupportLabel": "Падтрымка некалькіх моў:",
"multiLanguageSupportDescription": "Дазваляе выбраць некалькі моў для дакументаў з тэкстам на розных мовах."
},
"alternateMerge": {
"name": "Чаргаваць і змяшаць старонкі",
"subtitle": "Аб'яднаць PDF, чаргуючы старонкі з асобных PDF. Закладкі захоўваюцца.",
"retainPageLabels": "Захоўваць арыгінальныя пазнакі старонак з кожнага файла",
"retainPageLabelsHint": "Выключана (па змаўчанні): аб’яднаны PDF выкарыстоўвае натуральную нумарацыю 1–N. Уключана: арыгінальныя пазнакі старонак кожнага файла захоўваюцца (могуць узнікнуць паўторы)."
"retainPageLabelsHint": "Выключана (прадвызначана): аб'яднаны PDF выкарыстоўвае натуральную нумарацыю 1–N. Уключана: арыгінальныя пазнакі старонак кожнага файла захоўваюцца (могуць узнікнуць паўторы)."
},
"duplexCollate": {
"name": "Сартаванне двухбаковага сканавання",
"subtitle": "Упарадкоўвае PDF, адсканаваны двума блокамі (спачатку ўсе пярэднія бакі, потым усе адваротныя), у правільны парадак пярэдні/адваротны.",
"subtitle": "Упарадкаваць PDF, адсканаваны двума блокамі (спачатку ўсе пярэднія бакі, потым усе адваротныя), у правільны парадак пярэдні/адваротны.",
"totalPagesLabel": "Усяго старонак:",
"splitAfterPageLabel": "Падзяліць пасля старонкі",
"splitAfterPagePlaceholder": "напр. 50",
@@ -644,7 +648,7 @@
"pagesPerDocumentLabel": "Старонак у зыходным дакуменце",
"groupedHelp": "Калі ўключана, вынікам будзе ZIP-архіў з асобным PDF для кожнага згрупаванага дакумента.",
"collateButton": "Сабраць PDF",
"invalidFileTitle": "Няправільны файл",
"invalidFileTitle": "Памылковы файл",
"invalidFileMessage": "Выберыце файл PDF.",
"loadingPdf": "Загрузка PDF...",
"loadErrorMessage": "Не ўдалося загрузіць файл PDF.",
@@ -653,18 +657,18 @@
"previewSummary": "Блок пярэдніх бакоў: {{frontCount}} стар., блок адваротных: {{backCount}} стар. Вынік: {{outputCount}} стар. у парадку пярэдні/адваротны.",
"previewMismatchWarning": "Даўжыня блокаў пярэдніх і адваротных бакоў адрозніваецца ({{frontCount}} пярэдніх супраць {{backCount}} адваротных). Лішнія старонкі ({{extraCount}}) з даўжэйшага блока будуць дададзены без пары ў канец.",
"missingFileTitle": "Файл не выбраны",
"missingFileMessage": "Перад апрацоўкай загрузіце PDF прынамсі з 2 старонкамі.",
"invalidSplitTitle": "Няправільны пункт падзелу",
"missingFileMessage": "Перад апрацоўкай запампуйце PDF прынамсі з 2 старонкамі.",
"invalidSplitTitle": "Памылковы пункт падзелу",
"invalidSplitMessage": "Пункт падзелу павінен быць паміж старонкай 1 і старонкай {{maxSplit}}.",
"unevenConfirmTitle": "Няроўныя блокі",
"unevenConfirmMessage": "У блоку пярэдніх бакоў {{frontCount}} стар., у блоку адваротных — {{backCount}} стар.\nЗвычайна гэта азначае, што старонка адсканавана двойчы або яе не хапае.\n\nСтаронкі без пары ({{extraCount}}) будуць дададзены ў канец.\n\nУсё роўна працягнуць?",
"invalidGroupTitle": "Няправільны памер групы",
"invalidGroupTitle": "Памылковы памер групы",
"invalidGroupMessage": "Увядзіце правільную колькасць старонак у зыходным дакуменце.",
"collatingLoader": "Збор двухбаковага сканавання...",
"successMessage": "Сабраны PDF паспяхова створаны.",
"successGroupedMessage": "Збор завершаны. Створана файлаў: {{fileCount}}.",
"processErrorMessage": "Не ўдалося сабраць PDF.",
"howItWorksStep1Title": "Загрузіце скан",
"howItWorksStep1Title": "Запампуйце скан",
"howItWorksStep1": "Перацягніце адзін PDF, у якім спачатку ідуць усе пярэднія бакі, а потым усе адваротныя.",
"howItWorksStep2Title": "Задайце пункт падзелу",
"howItWorksStep2": "Пазначце, дзе заканчваецца блок пярэдніх бакоў, і выберыце, ці трэба перавярнуць блок адваротных.",
@@ -673,7 +677,7 @@
"faqOddPagesQuestion": "Што рабіць, калі ў скане няцотная колькасць старонак?",
"faqOddPagesAnswer": "Двухбаковае сканаванне павінна мець цотную колькасць старонак. Калі гэта не так, старонка, хутчэй за ўсё, адсканавана двойчы або прапушчана. Інструмент папярэдзіць вас перад апрацоўкай, а старонкі без пары будуць дададзены ў канец, каб нічога не згубілася.",
"faqBackOrderQuestion": "Навошта пакідаць блок адваротных бакоў без змен?",
"faqBackOrderAnswer": "Гэта залежыць ад таго, як стос падавалі на другім праходзе. Калі перавярнуць увесь стос, адваротныя бакі ідуць у адваротным парадку — гэта варыянт па змаўчанні. Калі сканер выдаў іх у тым самым парадку, што і пярэднія бакі, выберыце пакінуць блок без змен."
"faqBackOrderAnswer": "Гэта залежыць ад таго, як стос падавалі на другім праходзе. Калі перавярнуць увесь стос, адваротныя бакі ідуць у адваротным парадку — гэта прадвызначаны варыянт. Калі сканер выдаў іх у тым самым парадку, што і пярэднія бакі, выберыце пакінуць блок без змен."
},
"addAttachments": {
"name": "Дадаць далучэнні",
@@ -865,14 +869,14 @@
"btnSettings": "Налады",
"btnExportPdf": "Экспартаваць PDF",
"settingsTitle": "Налады Markdown",
"settingsPreset": "Набор налад",
"settingsPreset": "Перадвызначаная налада",
"presetDefault": "Прадвызначаны (як GFM)",
"presetCommonmark": "CommonMark (строгі)",
"presetZero": "Мінімальны (без функцый)",
"settingsOptions": "Параметры Markdown",
"optAllowHtml": "Дазволіць HTML-тэгі",
"optBreaks": "Пераўтвараць пераносы радкоў у <br>",
"optLinkify": "Аўтаматычна пераўтвараць URL-адрасы ў спасылкі",
"optLinkify": "Аўтаматычна канвертаваць URL-адрасы ў спасылкі",
"optTypographer": "Тыпограф (разумныя двукоссі і інш.)"
},
"pdfBooklet": {
@@ -1001,9 +1005,8 @@
"name": "PDF у тэкст",
"subtitle": "Выняць тэкст з файлаў PDF і захаваць як тэкставы файл (.txt). Падтрымлівае некалькі файлаў.",
"noteLabel": "Заўвага:",
"noteText": "Цей інструмент працює ТІЛЬКИ з PDF, створеними цифровим способом. Для сканованих документів або PDF на основі зображень використовуйте натомість наш інструмент OCR PDF.",
"convertButton": "Выняць тэкст",
"note": "Гэты інструмент працуе ТОЛЬКІ з PDF, створанымі лічбавым спосабам. Для сканіраваных дакументаў або PDF на аснове відарысаў выкарыстоўвайце інструмент OCR PDF."
"noteText": "Гэты інструмент працуе ТОЛЬКІ з PDF, створанымі лічбавым спосабам. Для сканаваных дакументаў або PDF на аснове відарысаў выкарыстоўвайце наш інструмент OCR PDF.",
"convertButton": "Выняць тэкст"
},
"digitalSignPdf": {
"name": "Лічбавы подпіс PDF",
@@ -1012,7 +1015,7 @@
"certificateSection": "Сертыфікат",
"uploadCert": "Запампаваць сертыфікат (.pfx, .p12, .pem)",
"certPassword": "Пароль сертыфіката",
"privateKeyPassword": "Пароль приватного ключа",
"privateKeyPassword": "Пароль прыватнага ключа",
"certPasswordPlaceholder": "Увядзіце пароль сертыфіката",
"certInfo": "Інфармацыя пра сертыфікат",
"certSubject": "Суб'ект",
@@ -1025,71 +1028,71 @@
"locationPlaceholder": "напрыклад, Мінск, Беларусь",
"contactInfo": "Кантактная інфармацыя",
"contactPlaceholder": "напрыклад, [email protected]",
"visibleSignature": "Видимий підпис",
"visibleSignatureDescription": "Якщо увімкнено, у PDF з'являється видиме поле підпису. Можна завантажити зображення/логотип або додати текст. Якщо не вказано жодного, ім'я підписанта автоматично відображається з сертифіката.",
"signatureImage": "Зображення/логотип підпису (необов'язково)",
"uploadSignatureImage": "Завантажити зображення (PNG, JPG, WebP)",
"signaturePreviewAlt": "Попередній перегляд підпису",
"remove": "Видалити",
"page": "Сторінка",
"firstPage": "Перша сторінка",
"lastPage": "Остання сторінка",
"allPages": "Усі сторінки",
"customPage": "Користувацька сторінка #",
"pageNumber": "Сторінка #",
"xPosition": "Позиція X (зліва)",
"yPosition": "Позиція Y (зверху)",
"width": "Ширина",
"height": "Висота",
"addTextOverlay": "Додати текстове накладання",
"text": "Текст",
"textPlaceholder": "напр., Підписано в цифровій формі Іваном Петренком",
"textColor": "Колір тексту",
"fontSize": "Розмір шрифту",
"invalidImageTitle": "Недійсне зображення",
"invalidImageMessage": "Виберіть зображення PNG, JPG або WebP.",
"invalidFileTitle": "Недійсний файл",
"invalidFileMessage": "Виберіть PDF-файл.",
"invalidCertificateTitle": "Недійсний сертифікат",
"invalidCertificateMessage": "Виберіть файл сертифіката .pfx, .p12 або .pem.",
"certificateLoaded": "Сертифікат завантажено",
"certificateUnlocked": "Сертифікат розблоковано",
"failedParsePem": "Не вдалося проаналізувати файл PEM",
"enterPasswordToUnlock": "Введіть пароль для розблокування",
"invalidPasswordOrCertificate": "Невірний пароль або сертифікат",
"incorrectPassword": "Невірний пароль",
"failedParseCertificate": "Не вдалося проаналізувати сертифікат",
"missingDataTitle": "Відсутні дані",
"missingDataMessage": "Завантажте і PDF, і дійсний сертифікат.",
"applyingSignature": "Застосування цифрового підпису...",
"signingFailedTitle": "Помилка підписання",
"chainFetchFailed": "Не вдалося отримати ланцюг сертифікатів. Можливо, проблема з мережею або проксі сертифікатів недоступний. Перевірте підключення до Інтернету та повторіть спробу. Якщо проблема не зникає, зверніться до підтримки.",
"failedToSignPdf": "Не вдалося підписати PDF: {{message}}",
"defaultSignatureText": "Підписано в цифровій формі {{signer}}\n{{date}}",
"pageCount": "{{count}} стор.",
"howToStep1Title": "Завантажити PDF",
"howToStep1Text": "Виберіть PDF-документ, який хочете підписати",
"howToStep2Title": "Завантажити сертифікат",
"howToStep2Text": "Надайте файл сертифіката .pfx або .p12 і пароль",
"howToStep3Title": "Підписати та завантажити",
"howToStep3Text": "Застосуйте цифровий підпис і завантажте підписаний PDF",
"relatedEncryptDesc": "Захистити PDF паролем",
"relatedDecryptDesc": "Видалити пароль PDF",
"relatedFlattenDesc": "Зробити анотації постійними",
"relatedSanitizeDesc": "Видалити приховані дані",
"relatedPermissionsDesc": "Встановити дозволи PDF",
"faqWhatIsQuestion": "Що таке цифровий підпис?",
"faqWhatIsAnswer": "Цифровий підпис — це криптографічний механізм, який перевіряє автентичність і цілісність документа. На відміну від намальованого підпису, він використовує криптографію відкритого ключа (сертифікати X.509) для підтвердження особи підписанта.",
"faqFormatsQuestion": "Які формати сертифікатів підтримуються?",
"faqFormatsAnswer": "Ми підтримуємо сертифікати у форматі PKCS#12 (.pfx, .p12), які містять і ваш сертифікат, і приватний ключ в одному зашифрованому файлі. Зазвичай вони видаються центрами сертифікації.",
"faqPrivateKeyQuestion": "Чи безпечний мій приватний ключ?",
"faqPrivateKeyAnswer": "Так! Уся обробка відбувається повністю у вашому браузері. Ваш сертифікат, приватний ключ і файли PDF ніколи не залишають ваш пристрій і не завантажуються на жоден сервер.",
"faqValidReadersQuestion": "Чи буде підпис дійсним у переглядачах PDF?",
"faqValidReadersAnswer": "Так, інструмент створює стандартні відокремлені підписи PKCS#7, які розпізнаються всіма основними програмами для перегляду PDF. Для повної перевірки використовуйте сертифікат від довіреного центру сертифікації.",
"visibleSignature": "Бачны подпіс",
"visibleSignatureDescription": "Калі ўключана, у PDF з'яўляецца бачнае поле подпісу. Можна запампаваць відарыс або лагатып альбо дадаць тэкст. Калі нічога не дадзена, аўтаматычна будзе паказана імя падпісанта з сертыфіката.",
"signatureImage": "Відарыс або лагатып подпісу (неабавязкова)",
"uploadSignatureImage": "Запампаваць відарыс (PNG, JPG, WebP)",
"signaturePreviewAlt": "Папярэдні прагляд подпісу",
"remove": "Выдаліць",
"page": "Старонка",
"firstPage": "Першая старонка",
"lastPage": "Апошняя старонка",
"allPages": "Усе старонкі",
"customPage": "Уласная старонка №",
"pageNumber": "Старонка №",
"xPosition": "Пазіцыя X (злева)",
"yPosition": "Пазіцыя Y (зверху)",
"width": "Шырыня",
"height": "Вышыня",
"addTextOverlay": "Дадаць накладзены тэкст",
"text": "Тэкст",
"textPlaceholder": "Напрыклад, падпісана лічбавым подпісам Джона Доу",
"textColor": "Колер тэксту",
"fontSize": "Памер шрыфта",
"invalidImageTitle": "Памылковы відарыс",
"invalidImageMessage": "Выберыце відарыс PNG, JPG або WebP.",
"invalidFileTitle": "Памылковы файл",
"invalidFileMessage": "Выберыце файл PDF.",
"invalidCertificateTitle": "Памылковы сертыфікат",
"invalidCertificateMessage": "Выберыце файл сертыфіката .pfx, .p12 або .pem.",
"certificateLoaded": "Сертыфікат загружаны",
"certificateUnlocked": "Сертыфікат разблакаваны",
"failedParsePem": "Не ўдалося разабраць файл PEM",
"enterPasswordToUnlock": "Увядзіце пароль, каб разблакаваць",
"invalidPasswordOrCertificate": "Памылковы пароль або сертыфікат",
"incorrectPassword": "Няправільны пароль",
"failedParseCertificate": "Не ўдалося разабраць сертыфікат",
"missingDataTitle": "Адсутнасць даных",
"missingDataMessage": "Дадайце PDF і сапраўдны сертыфікат.",
"applyingSignature": "Накладанне лічбавага подпісу...",
"signingFailedTitle": "Не ўдалося падпісаць",
"chainFetchFailed": "Не ўдалося атрымаць ланцужок сертыфікатаў. Гэта можа быць выклікана праблемамі з сеткай або недаступнасцю проксі-сервера сертыфікатаў. Праверце падлучэнне да інтэрнэту і паспрабуйце яшчэ раз. Калі праблема захоўваецца, звярніцеся ў службу падтрымкі.",
"failedToSignPdf": "Не ўдалося падпісаць PDF: {{message}}",
"defaultSignatureText": "Падпісана лічбавым подпісам {{signer}}\n{{date}}",
"pageCount": "{{count}} стар.",
"howToStep1Title": "Запампуйце PDF",
"howToStep1Text": "Выберыце дакумент PDF, які хочаце падпісаць",
"howToStep2Title": "Запампуйце сертыфікат",
"howToStep2Text": "Дадайце файл сертыфіката .pfx або .p12 і пароль",
"howToStep3Title": "Падпішыце і спампуйце",
"howToStep3Text": "Накладзіце лічбавы подпіс і спампуйце падпісаны PDF",
"relatedEncryptDesc": "Абараніць PDF паролем",
"relatedDecryptDesc": "Выдаліць пароль PDF",
"relatedFlattenDesc": "Зрабіць анатацыі сталымі",
"relatedSanitizeDesc": "Выдаліць схаваныя даныя",
"relatedPermissionsDesc": "Задаць дазволы PDF",
"faqWhatIsQuestion": "Што такое лічбавы подпіс?",
"faqWhatIsAnswer": "Лічбавы подпіс — гэта крыптаграфічны механізм, які правярае сапраўднасць і цэласнасць дакумента. У адрозненне ад намаляванага подпісу, ён выкарыстоўвае крыптаграфію з адкрытым ключом (сертыфікаты X.509), каб пацвердзіць асобу падпісанта.",
"faqFormatsQuestion": "Якія фарматы сертыфікатаў падтрымліваюцца?",
"faqFormatsAnswer": "Падтрымліваюцца сертыфікаты фармату PKCS#12 (.pfx, .p12), якія змяшчаюць сертыфікат і закрыты ключ карыстальніка ў адным зашыфраваным файле. Такія сертыфікаты звычайна выдаюцца цэнтрамі сертыфікацыі.",
"faqPrivateKeyQuestion": "Ці ў бяспецы мой закрыты ключ?",
"faqPrivateKeyAnswer": "Так! Уся апрацоўка адбываецца непасрэдна ў браўзеры. Сертыфікат, закрыты ключ і файлы PDF ніколі не пакідаюць прыладу карыстальніка і не запампоўваюцца на сервер.",
"faqValidReadersQuestion": "Ці будзе подпіс сапраўдным у праглядальніках PDF?",
"faqValidReadersAnswer": "Так, інструмент стварае стандартныя адасобленыя подпісы PKCS#7, якія распазнаюцца ўсімі асноўнымі праглядальнікамі PDF. Для поўнай праверкі выкарыстоўвайце сертыфікат ад даверанага цэнтра сертыфікацыі.",
"applySignature": "Ужыць лічбавы подпіс",
"successMessage": "PDF паспяхова падпісаны! Подпіс можна праверыць у любым PDF-чытальніку.",
"internetRequiredTitle": "Потрібне інтернет-з'єднання",
"internetRequiredDescription": "Для перевірки підпису може знадобитися отримати інформацію про ланцюг сертифікатів із сервера видавця сертифіката."
"internetRequiredTitle": "Патрабуецца падлучэнне да інтэрнэту",
"internetRequiredDescription": "Для падпісання можа спатрэбіцца атрымаць звесткі пра ланцужок сертыфікатаў з сервера выдаўца сертыфіката, каб праверыць подпіс."
},
"validateSignaturePdf": {
"name": "Праверыць подпіс PDF",
@@ -1113,11 +1116,11 @@
},
"fontToOutline": {
"name": "Шрыфт у контуры",
"subtitle": "Ператварыць усе шрыфты ў вектарныя контуры для стабільнага адлюстравання на ўсіх прыладах."
"subtitle": "Канвертаваць усе шрыфты ў вектарныя контуры для стабільнага адлюстравання на ўсіх прыладах."
},
"deskewPdf": {
"name": "Выпрастаць PDF",
"subtitle": "Аўтаматычна выраўняць нахіленыя адсканіраваныя старонкі з дапамогай OpenCV."
"subtitle": "Аўтаматычна выраўняць нахіленыя адсканаваныя старонкі з дапамогай OpenCV."
},
"pdfToWord": {
"name": "PDF у Word",
@@ -1167,22 +1170,22 @@
"cancel": "Скасаваць",
"loadTemplate": "Загрузіць шаблон",
"noTemplates": "Пакуль няма захаваных шаблонаў.",
"ok": "OK",
"ok": "ОК",
"workflowCompleted": "Рабочы працэс завершаны",
"errorDuringExecution": "Памылка падчас выканання",
"addNodeError": "Дадайце хаця б адзін вузел для запуску рабочага працэсу.",
"needInputOutput": "Для працы рабочага працэсу патрэбен хаця б адзін вузел уводу і адзін вузел вываду.",
"needInputOutput": "Для працы рабочага працэсу патрэбны хаця б адзін вузел уводу і адзін вузел вываду.",
"enterName": "Увядзіце назву.",
"templateExists": "Шаблон з такой назвай ужо існуе.",
"templateSaved": "Шаблон \"{{name}}\" захаваны.",
"templateLoaded": "Шаблон \"{{name}}\" загружаны.",
"templateSaved": "Шаблон «{{name}}» захаваны.",
"templateLoaded": "Шаблон «{{name}}» загружаны.",
"failedLoadTemplate": "Не ўдалося загрузіць шаблон.",
"noSettings": "Няма налад для гэтага вузла.",
"advancedSettings": "Пашыраныя налады",
"specialNodes": {
"pdfInput": {
"name": "Увод PDF",
"description": "Загрузіце адзін ці некалькі файлаў PDF"
"description": "Запампуйце адзін ці некалькі файлаў PDF"
},
"download": {
"name": "Спампаваць",
@@ -1195,96 +1198,96 @@
"expectedPdfInput": "Чакаўся ўвод PDF",
"failedToRenderPage": "Не атрымалася адлюстраваць старонку {{page}}",
"failedToGetCanvasContext": "Не атрымалася атрымаць кантэкст палатна для старонкі {{page}}",
"failedToRenderPageToImage": "Не атрымалася адлюстраваць старонку {{page}} як выяву",
"failedToRenderPageToImage": "Не атрымалася адлюстраваць старонку {{page}} як відарыс",
"noPagesProcessed": "Ніводнай старонкі не апрацавана",
"cpdfNotConfigured": "CoherentPDF не настроены. Настройце яго ў пашыраных параметрах.",
"workerError": "Памылка воркера: {{message}}",
"alternateMergeWorkerError": "Памылка воркера паслядоўнага зліцця: {{message}}",
"noPdfFilesUploaded": "У вузел PDF Input не загружаны PDF-файлы",
"failedToLoadFile": "Не атрымалася загрузіць \"{{file}}\" — файл можа быць пашкоджаны",
"noImagesUploaded": "У вузел Image Input не загружаны выявы",
"noWordDocsUploaded": "У вузел Word Input не загружаны дакументы",
"noExcelUploaded": "У вузел Excel Input не загружаны табліцы",
"noPowerPointUploaded": "У вузел PowerPoint Input не загружаны прэзентацыі",
"noCbzUploaded": "У вузел CBZ Input не загружаны архівы коміксаў",
"noEmailUploaded": "У вузел Email Input не загружаны файлы пошты",
"noEpubUploaded": "У вузел EPUB Input не загружаны файлы EPUB",
"noFb2Uploaded": "У вузел FB2 Input не загружаны файлы FB2",
"noJsonUploaded": "У вузел JSON Input не загружаны файлы JSON",
"noMarkdownUploaded": "У вузел Markdown Input не загружаны файлы Markdown",
"noMobiUploaded": "У вузел MOBI Input не загружаны файлы MOBI",
"noOdgUploaded": "У вузел ODG Input не загружаны файлы ODG",
"noPagesUploaded": "У вузел Pages Input не загружаны файлы Pages",
"noPubUploaded": "У вузел PUB Input не загружаны файлы PUB",
"noSvgUploaded": "У вузел SVG Input не загружаны файлы SVG",
"noTextUploaded": "У вузел Text Input не загружаны тэкставыя файлы",
"noVsdUploaded": "У вузел VSD Input не загружаны файлы Visio",
"noWpdUploaded": "У вузел WPD Input не загружаны файлы WPD",
"noWpsUploaded": "У вузел WPS Input не загружаны файлы WPS",
"noXmlUploaded": "У вузел XML Input не загружаны файлы XML",
"noXpsUploaded": "У вузел XPS Input не загружаны файлы XPS",
"cpdfNotConfigured": "CoherentPDF не сканфігураваны. Сканфігуруйце яго ў пашыраных наладах.",
"workerError": "Памылка апрацоўшчыка: {{message}}",
"alternateMergeWorkerError": "Памылка апрацоўшчыка паслядоўнага зліцця: {{message}}",
"noPdfFilesUploaded": "У вузел «Увод PDF» не запампаваны PDF-файлы",
"failedToLoadFile": "Не атрымалася загрузіць «{{file}}» — файл можа быць пашкоджаны",
"noImagesUploaded": "У вузел уводу відарысаў не запампаваны відарысы",
"noWordDocsUploaded": "У вузел уводу Word не запампаваны дакументы",
"noExcelUploaded": "У вузел уводу Excel не запампаваны табліцы",
"noPowerPointUploaded": "У вузел уводу PowerPoint не запампаваны прэзентацыі",
"noCbzUploaded": "У вузел уводу CBZ не запампаваны архівы коміксаў",
"noEmailUploaded": "У вузел уводу Email не запампаваны файлы пошты",
"noEpubUploaded": "У вузел уводу EPUB не запампаваны файлы EPUB",
"noFb2Uploaded": "У вузел уводу FB2 не запампаваны файлы FB2",
"noJsonUploaded": "У вузел уводу JSON не запампаваны файлы JSON",
"noMarkdownUploaded": "У вузел уводу Markdown не запампаваны файлы Markdown",
"noMobiUploaded": "У вузел уводу MOBI не запампаваны файлы MOBI",
"noOdgUploaded": "У вузел уводу ODG не запампаваны файлы ODG",
"noPagesUploaded": "У вузел уводу Pages не запампаваны файлы Pages",
"noPubUploaded": "У вузел уводу PUB не запампаваны файлы PUB",
"noSvgUploaded": "У вузел уводу SVG не запампаваны файлы SVG",
"noTextUploaded": "У вузел уводу тэксту не запампаваны тэкставыя файлы",
"noVsdUploaded": "У вузел уводу VSD не запампаваны файлы Visio",
"noWpdUploaded": "У вузел уводу WPD не запампаваны файлы WPD",
"noWpsUploaded": "У вузел уводу WPS не запампаваны файлы WPS",
"noXmlUploaded": "У вузел уводу XML не запампаваны файлы XML",
"noXpsUploaded": "У вузел уводу XPS не запампаваны файлы XPS",
"alternateMergeNeedsTwo": "Паслядоўнаму зліццю патрэбна як мінімум два PDF, падключаныя да ўваходу",
"cropMarginsExceed": "Палі абрэзкі перавышаюць памеры старонкі. Паменшыце значэнні.",
"digitalSignNoCertificate": "У вузле лічбавага подпісу не загружаны сертыфікат",
"encryptUserPasswordRequired": "Для шыфравання патрэбны карыстальніцкі пароль",
"extractImagesNoneFound": "У падключаных PDF не знойдзена выяў",
"invertColorsFailedReadImage": "Не атрымалася прачытаць даныя выявы",
"extractImagesNoneFound": "У падключаных PDF не знойдзена відарысаў",
"invertColorsFailedReadImage": "Не атрымалася прачытаць даныя відарыса",
"overlayRequiresPdf": "Вузел накладання патрабуе ўвод PDF для накладання.",
"pdfToCsvNoTables": "У PDF не знойдзена табліц",
"pdfToXlsxNoTables": "У {{file}} не знойдзена табліц",
"posterizeFailedTileCanvas": "Не атрымалася атрымаць кантэкст палатна пліткі",
"redactNoText": "Рэдагаванне: не вызначаны тэкст для рэдагавання",
"redactNoText": "Зацямненне: не вызначаны тэкст для зацямнення",
"removeBlankPagesAllBlank": "Усе старонкі пустыя",
"svgFailedToConvert": "Не атрымалася канвертаваць SVG",
"svgFailedToLoad": "Не атрымалася загрузіць SVG",
"timestampFailed": "Не атрымалася паставіць метку часу праз TSA {{tsa}}: {{message}}",
"noOutputNodes": "Не знойдзена вузлоў вываду. Дадайце вузел Download, каб завяршыць ваш працоўны працэс.",
"circularDependency": "У працоўным працэсе выяўлена кругавая залежнасць. Выдаліце ўсе цыклы паміж вузламі.",
"encryptOrdering": "Вузел шыфравання падае даныя ў \"{{target}}\", што можа збой на зашыфраваных даных. Перамясціце шыфраванне непасрэдна перад вузлом вываду.",
"invalidWorkflowFile": "Несапраўдны файл працоўнага працэсу: адсутнічае масіў вузлоў або злучэнняў.",
"storageQuotaExceeded": "Не атрымалася захаваць працоўны працэс: перавышана квота сховішча. Паспрабуйце выдаліць старыя шаблоны.",
"failedToImport": "Не атрымалася імпартаваць працоўны працэс: {{message}}"
"timestampFailed": "Не атрымалася паставіць пазнаку часу праз TSA {{tsa}}: {{message}}",
"noOutputNodes": "Не знойдзена вузлоў вываду. Дадайце вузел «Спампаваць», каб завяршыць ваш рабочы працэс.",
"circularDependency": "У рабочым працэсе выяўлена кругавая залежнасць. Выдаліце ўсе цыклы паміж вузламі.",
"encryptOrdering": "Вузел шыфравання падае даныя ў «{{target}}», што можа даць збой на зашыфраваных даных. Перамясціце шыфраванне непасрэдна перад вузлом вываду.",
"invalidWorkflowFile": "Памылковы файл рабочага працэсу: адсутнічае масіў вузлоў або злучэнняў.",
"storageQuotaExceeded": "Не атрымалася захаваць рабочы працэс: перавышана квота сховішча. Паспрабуйце выдаліць старыя шаблоны.",
"failedToImport": "Не атрымалася імпартаваць рабочы працэс: {{message}}"
}
},
"wasmSettings": {
"title": "Налады пашыраных функцый",
"description": "Налаштуйте зовнішні модулі обробки для увімкнення розширених функцій PDF. Ці модулі необов'язкові і ліцензуються окремо.",
"description": "Сканфігуруйце знешнія модулі апрацоўкі для ўключэння пашыраных магчымасцей PDF. Гэтыя модулі неабавязковыя і ліцэнзуюцца асобна.",
"status": {
"testing": "Перевірка...",
"customOverride": "Користувацьке перевизначення",
"preConfigured": "Попередньо налаштовано",
"notConfigured": "Не налаштовано"
"testing": "Праверка…",
"customOverride": "Уласная замена",
"preConfigured": "Папярэдне сканфігураваны",
"notConfigured": "Не сканфігураваны"
},
"preconfiguredTitle": "Попередньо налаштовано і готово до використання.",
"preconfiguredDescription": "Розширені модулі обробки автоматично завантажуються з CDN. Ви можете перевизначити URL нижче, якщо потрібно використовувати власне джерело (наприклад, для air-gapped або самостійно розміщених розгортань).",
"usingDefault": "Використовується за замовчуванням: {{url}}",
"pymupdfSubtitle": "Рушій обробки документів",
"pymupdfFeatures": "Вмикає: PDF у текст, Markdown, SVG, DOCX, Excel • Витягти зображення/таблиці • Конвертацію формату",
"preconfiguredTitle": "Папярэдне сканфігураваны і гатовы да выкарыстання",
"preconfiguredDescription": "Пашыраныя модулі апрацоўкі аўтаматычна загружаюцца з CDN. Вы можаце перавызначыць URL ніжэй, калі вам трэба выкарыстоўваць уласную крыніцу (напрыклад, для разгортванняў у ізаляваным асяроддзі або з уласным хостынгам).",
"usingDefault": "Выкарыстоўваецца прадвызначанае значэнне: {{url}}",
"pymupdfSubtitle": "Рухавік апрацоўкі дакументаў",
"pymupdfFeatures": "Уключае: канвертаванне PDF у тэкст, Markdown, SVG, DOCX, Excel • выманне відарысаў і табліц • канвертаванне фарматаў",
"testButton": "Праверыць",
"recommendedLabel": "Рекомендовано:",
"copyTitle": "Копіювати в буфер обміну",
"ghostscriptSubtitle": "Рушій конвертації PDF/A",
"ghostscriptFeatures": "Вмикає: Конвертацію PDF/A-1b, PDF/A-2b, PDF/A-3b • Шрифт у контур",
"cpdfSubtitle": "Рушій закладок і метаданих",
"cpdfFeatures": "Вмикає: Розділити за закладками • Редагувати закладки • Метадані PDF",
"recommendedLabel": "Рэкамендавана:",
"copyTitle": "Капіраваць у буфер абмену",
"ghostscriptSubtitle": "Рухавік канвертавання PDF/A",
"ghostscriptFeatures": "Уключае: канвертаванне ў PDF/A-1b, PDF/A-2b, PDF/A-3b • канвертаванне шрыфтоў у контуры",
"cpdfSubtitle": "Рухавік закладак і метаданых",
"cpdfFeatures": "Уключае: раздзяленне паводле закладак • рэдагаванне закладак • метаданыя PDF",
"saveConfiguration": "Захаваць канфігурацыю",
"savingConfiguration": "Збереження конфігурації...",
"savingConfiguration": "Захаванне канфігурацыі...",
"savedTitle": "Захавана",
"savedMessage": "Канфігурацыя паспяхова захавана!",
"errorTitle": "Памылка",
"failedSave": "Не вдалося зберегти конфігурацію: {{message}}",
"emptyUrlTitle": "Порожній URL",
"emptyUrlMessage": "Введіть URL для перевірки.",
"testSuccessTitle": "Успіх",
"connectionSuccess": "Підключення до {{package}} успішне!",
"connectionFailedTitle": "Збій підключення",
"connectionFailedMessage": "Не вдалося підключитися до URL.",
"failedSave": "Не ўдалося захаваць канфігурацыю: {{message}}",
"emptyUrlTitle": "Пусты URL",
"emptyUrlMessage": "Увядзіце URL для праверкі.",
"testSuccessTitle": "Поспех",
"connectionSuccess": "Злучэнне з {{package}} паспяховае!",
"connectionFailedTitle": "Не ўдалося ўсталяваць злучэнне",
"connectionFailedMessage": "Не ўдалося злучыцца з URL.",
"resetDefaults": "Скінуць да стандартных",
"resetTitle": "Скід",
"resetWithDefaults": "Користувацькі перевизначення очищено. Активні попередньо налаштовані значення за замовчуванням.",
"resetNoDefaults": "Усі конфігурації та кешовані модулі очищено.",
"licenseTitle": "Повідомлення про ліцензію:",
"licenseDescription": "Зовнішні модулі (PyMuPDF, Ghostscript, CoherentPDF) ліцензовані під AGPL-3.0 або подібними copyleft-ліцензіями. Налаштовуючи та використовуючи ці модулі, ви погоджуєтеся з їхніми відповідними умовами ліцензії. BentoPDF сумісний з будь-якою реалізацією Ghostscript WASM і PyMuPDF WASM, що дотримується очікуваного інтерфейсу."
"resetWithDefaults": "Уласныя перавызначэнні ачышчаныя. Актываваныя прадвызначаныя значэнні канфігурацыі.",
"resetNoDefaults": "Усе канфігурацыі і кэшаваныя модулі ачышчаныя.",
"licenseTitle": "Звесткі пра ліцэнзію:",
"licenseDescription": "Знешнія модулі (PyMuPDF, Ghostscript, CoherentPDF) распаўсюджваюцца паводле AGPL-3.0 або падобных ліцэнзій з копілефтам. Канфігуруючы і выкарыстоўваючы гэтыя модулі, вы згаджаецеся з умовамі адпаведных ліцэнзій. BentoPDF сумяшчальны з любой рэалізацыяй Ghostscript WASM і PyMuPDF WASM, якая адпавядае чаканаму інтэрфейсу."
},
"pdfOverlay": {
"name": "Накладанне PDF",
@@ -1297,7 +1300,7 @@
"overlayOption": "Накладанне (зверху старонак)",
"underlayOption": "Падкладанне (за старонкамі)",
"pageRangeLabel": "Прымяніць да старонак (неабавязкова)",
"pageRangeHint": "Выкарыстоўвайце \"z\" для апошняй старонкі. Пакіньце пустым, каб прымяніць да ўсіх старонак.",
"pageRangeHint": "Выкарыстоўвайце «z» для апошняй старонкі. Пакіньце пустым, каб прымяніць да ўсіх старонак.",
"repeatLabel": "Паўтараць накладанне/падкладанне, калі базавы PDF даўжэйшы",
"processButton": "Прымяніць накладанне / падкладанне",
"howItWorksUploadTitle": "Запампуйце два PDF",
@@ -1309,8 +1312,16 @@
"faqDifferenceQuestion": "У чым розніца паміж накладаннем і падкладаннем?",
"faqDifferenceAnswer": "Накладанне размяшчае старонкі зверху базавага PDF (як вадзяны знак). Падкладанне размяшчае старонкі за базавым PDF (як фірмовы бланк або фон).",
"faqSinglePageQuestion": "Ці магу я выкарыстоўваць аднастаронкавы PDF як накладанне для ўсіх старонак?",
"faqSinglePageAnswer": "Так! Уключыце опцыю \"Паўтараць\" і старонкі накладання будуць паўтарацца на ўсіх старонках базавага файла. Аднастаронкавы вадзяны знак будзе прымяняцца да кожнай старонкі.",
"faqSinglePageAnswer": "Так! Уключыце опцыю «Паўтараць» і старонкі накладання будуць паўтарацца на ўсіх старонках базавага файла. Аднастаронкавы вадзяны знак будзе прымяняцца да кожнай старонкі.",
"faqPrivacyQuestion": "Ці з'яўляюцца мае файлы прыватнымі і бяспечнымі?",
"faqPrivacyAnswer": "Безумоўна! Уся апрацоўка адбываецца ў вашым браўзеры. Вашы файлы ніколі не пакідаюць вашу прыладу, забяспечваючы поўную прыватнасць."
},
"unlockPdf": {
"name": "Расшыфраваць PDF",
"subtitle": "Разблакіраваць PDF, выдаліўшы пароль."
},
"protectPdf": {
"name": "Зашыфраваць PDF",
"subtitle": "Заблакіраваць PDF, дадаўшы пароль."
}
}
+5 -2
View File
@@ -239,7 +239,9 @@
"legal": "Juridisk",
"termsAndConditions": "Terms and Conditions",
"privacyPolicy": "Privacy Policy",
"followUs": "Følg os"
"followUs": "Følg os",
"privacyShort": "Privatliv",
"termsShort": "Vilkår"
},
"merge": {
"title": "Flet PDF'er",
@@ -286,7 +288,8 @@
"noCompromises": "Ingen kompromiser."
},
"mission": {
"title": "Vores mission",
"title": "Vores",
"titleDim": "mission",
"description": "At give den mest komplette PDF-værktøjskasse uden betaling og med fuldt fokus på privatliv."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Klik på et hvilket som helst afsnit, og redigér det direkte med live-ombrydning, skrifttyper og formatering.",
"saved": "PDF blev gemt! ({{size}} KB)",
"failedToLoad": "PDF-teksteditoren kunne ikke indlæses.",
"loadingFonts": "Indlæser skrifttyper...",
"fontsUnavailable": "En skrifttype, der er nødvendig for nogle tegn, kunne ikke downloades. Tjek din forbindelse, og prøv igen, ellers vises disse tegn muligvis ikke korrekt i den gemte PDF.",
"howToUpload": "Upload PDF",
"howToClick": "Klik på et afsnit",
"howToRestyle": "Giv alt ny stil",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Ja! Aktivér \"Gentag\"-indstillingen, og dine overlejringssider vil gentage sig på alle basis-sider. Et enkeltsidigt vandmærke vil blive anvendt på hver side.",
"faqPrivacyQuestion": "Er mine filer private og sikre?",
"faqPrivacyAnswer": "Absolut! Al behandling sker i din browser. Dine filer forlader aldrig din enhed, hvilket sikrer fuldstændig privatliv."
},
"unlockPdf": {
"name": "Dekryptér PDF",
"subtitle": "Fjern adgangskodebeskyttelse."
},
"protectPdf": {
"name": "Kryptér PDF",
"subtitle": "Lås din PDF med en adgangskode."
}
}
+5 -2
View File
@@ -239,7 +239,9 @@
"legal": "Rechtliches",
"termsAndConditions": "Nutzungsbedingungen",
"privacyPolicy": "Datenschutzrichtlinie",
"followUs": "Folge uns"
"followUs": "Folge uns",
"privacyShort": "Datenschutz",
"termsShort": "AGB"
},
"merge": {
"title": "PDFs zusammenführen",
@@ -286,7 +288,8 @@
"noCompromises": "Ohne Kompromisse."
},
"mission": {
"title": "Unsere Mission",
"title": "Unsere",
"titleDim": "Mission",
"description": "Die umfassendste PDF-Toolbox bereitzustellen, die deine Privatsphäre respektiert und niemals Geld kostet. Wir glauben, dass wichtige Dokumentenwerkzeuge für jede*n, überall und ohne Barrieren zugänglich sein sollten."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Auf einen beliebigen Absatz klicken und ihn direkt bearbeiten – mit Live-Umbruch, Schriftarten und Formatierung.",
"saved": "PDF erfolgreich gespeichert! ({{size}} KB)",
"failedToLoad": "Der PDF-Texteditor konnte nicht geladen werden.",
"loadingFonts": "Schriftarten werden geladen...",
"fontsUnavailable": "Eine für einige Zeichen benötigte Schriftart konnte nicht heruntergeladen werden. Prüfen Sie Ihre Verbindung und versuchen Sie es erneut, sonst werden diese Zeichen im gespeicherten PDF möglicherweise nicht korrekt angezeigt.",
"howToUpload": "PDF hochladen",
"howToClick": "Absatz anklicken",
"howToRestyle": "Alles umgestalten",
@@ -1311,5 +1313,13 @@
"faqSinglePageAnswer": "Ja! Aktivieren Sie die Option \"Wiederholen\" und Ihre Überlagerungsseiten werden auf allen Basisseiten wiederholt. Ein einseitiges Wasserzeichen wird auf jeder Seite angewendet.",
"faqPrivacyQuestion": "Sind meine Dateien privat und sicher?",
"faqPrivacyAnswer": "Absolut! Die gesamte Verarbeitung findet in Ihrem Browser statt. Ihre Dateien verlassen niemals Ihr Gerät, was vollständige Privatsphäre gewährleistet."
},
"unlockPdf": {
"name": "PDF entschlüsseln",
"subtitle": "PDF durch Entfernen des Passwortschutzes entsperren."
},
"protectPdf": {
"name": "PDF verschlüsseln",
"subtitle": "Ihre PDF durch Hinzufügen eines Passworts sperren."
}
}
+15 -12
View File
@@ -212,7 +212,7 @@
},
"browserBased": {
"question": "How does browser-based processing keep me safe?",
"answer": "By running entirely inside your browser, BentoPDF ensures that your files never leave your device. This eliminates the risks of server hacks, data breaches, or unauthorized access. Your files remain yours—always."
"answer": "By running entirely inside your browser, BentoPDF ensures that your files never leave your device. This eliminates the risks of server hacks, data breaches, or unauthorized access. Your files remain yours, always."
},
"analytics": {
"question": "Do you use cookies or analytics to track me?",
@@ -239,7 +239,9 @@
"legal": "Legal",
"termsAndConditions": "Terms and Conditions",
"privacyPolicy": "Privacy Policy",
"followUs": "Follow Us"
"followUs": "Follow Us",
"privacyShort": "Privacy",
"termsShort": "Terms"
},
"merge": {
"title": "Merge PDFs",
@@ -281,41 +283,42 @@
},
"about": {
"hero": {
"title": "We believe PDF tools should be",
"title": "PDF tools should be",
"subtitle": "fast, private, and free.",
"noCompromises": "No compromises."
},
"mission": {
"title": "Our Mission",
"title": "Our",
"titleDim": "Mission",
"description": "To provide the most comprehensive PDF toolbox that respects your privacy and never asks for payment. We believe essential document tools should be accessible to everyone, everywhere, without barriers."
},
"philosophy": {
"label": "Our Core Philosophy",
"title": "Privacy First. Always.",
"description": "In an era where data is a commodity, we take a different approach. All processing for Bentopdf tools happens locally in your browser. This means your files never touch our servers, we never see your documents, and we don't track what you do. Your documents remain completely and unequivocally private. It's not just a feature; it's our foundation."
"description": "Every BentoPDF tool runs locally in your browser. Your files are never uploaded, nobody else sees your documents, and nothing tracks what you do."
},
"whyBentopdf": {
"title": "Why",
"speed": {
"title": "Built for Speed",
"description": "No waiting for uploads or downloads to a server. By processing files directly in your browser using modern web technologies like WebAssembly, we offer unparalleled speed for all our tools."
"description": "There's no upload or download step. Files are processed right in your browser using WebAssembly, so you're never waiting on a server."
},
"free": {
"title": "Completely Free",
"description": "No trials, no subscriptions, no hidden fees, and no \"premium\" features held hostage. We believe powerful PDF tools should be a public utility, not a profit center."
"title": "Free to Use",
"description": "Every tool is free, with no trials, no subscriptions and no watermarks. Development is funded by commercial licenses."
},
"noAccount": {
"title": "No Account Required",
"description": "Start using any tool immediately. We don't need your email, a password, or any personal information. Your workflow should be frictionless and anonymous."
"description": "Open any tool and start right away. No email, no password, no personal information."
},
"openSource": {
"title": "Open Source Spirit",
"description": "Built with transparency in mind. We leverage incredible open-source libraries like PDF-lib and PDF.js, and believe in the community-driven effort to make powerful tools accessible to everyone."
"title": "Open Source",
"description": "The code is public on GitHub under AGPL-3.0, so you can check exactly how your files are handled. It builds on open-source projects like PDF.js, pdf-lib, qpdf and LibreOffice."
}
},
"cta": {
"title": "Ready to get started?",
"description": "Join thousands of users who trust Bentopdf for their daily document needs. Experience the difference that privacy and performance can make.",
"description": "Join thousands of users who trust BentoPDF for their daily document needs. Experience the difference that privacy and performance can make.",
"button": "Explore All Tools"
}
},
+10
View File
@@ -61,6 +61,8 @@
"subtitle": "Click any paragraph and edit it in place with live reflow, fonts, and styling.",
"saved": "PDF saved successfully! ({{size}} KB)",
"failedToLoad": "Failed to load the PDF Text Editor.",
"loadingFonts": "Loading fonts...",
"fontsUnavailable": "A font needed for some characters could not be downloaded. Check your connection and try again, or those characters may not appear correctly in the saved PDF.",
"howToUpload": "Upload PDF",
"howToClick": "Click a Paragraph",
"howToRestyle": "Restyle Anything",
@@ -1313,5 +1315,13 @@
"faqSinglePageAnswer": "Yes! Enable the \"Loop\" option and your overlay PDF pages will repeat across all base pages. A single-page watermark will apply to every page.",
"faqPrivacyQuestion": "Are my files private and secure?",
"faqPrivacyAnswer": "Absolutely! All processing happens in your browser. Your files never leave your device, ensuring complete privacy."
},
"unlockPdf": {
"name": "Unlock PDF",
"subtitle": "Remove the password from a PDF so it opens freely. Requires the current password."
},
"protectPdf": {
"name": "Protect PDF",
"subtitle": "Password protect a PDF with strong AES encryption."
}
}
+7 -4
View File
@@ -239,7 +239,9 @@
"legal": "Legal",
"termsAndConditions": "Términos y Condiciones",
"privacyPolicy": "Política de Privacidad",
"followUs": "Síguenos"
"followUs": "Síguenos",
"privacyShort": "Privacidad",
"termsShort": "Términos"
},
"merge": {
"title": "Fusionar PDFs",
@@ -286,13 +288,14 @@
"noCompromises": "Sin compromisos."
},
"mission": {
"title": "Nuestra Misión",
"title": "Nuestra",
"titleDim": "Misión",
"description": "Proporcionar la caja de herramientas PDF más completa que respete tu privacidad y nunca pida pago. Creemos que las herramientas de documentos esenciales deben ser accesibles para todos, en todas partes, sin barreras."
},
"philosophy": {
"label": "Nuestra Filosofía Central",
"title": "Privacidad Primero. Siempre.",
"description": "En una era donde los datos son una mercancía, adoptamos un enfoque diferente. Todo el procesamiento de las herramientas de Bentopdf ocurre localmente en tu navegador. Esto significa que tus archivos nunca tocan nuestros servidores, nunca vemos tus documentos y no rastreamos lo que haces. Tus documentos permanecen completa e inequívocamente privados. No es solo una característica; es nuestra base."
"description": "En una era donde los datos son una mercancía, adoptamos un enfoque diferente. Todo el procesamiento de las herramientas de BentoPDF ocurre localmente en tu navegador. Esto significa que tus archivos nunca tocan nuestros servidores, nunca vemos tus documentos y no rastreamos lo que haces. Tus documentos permanecen completa e inequívocamente privados. No es solo una característica; es nuestra base."
},
"whyBentopdf": {
"title": "Por qué",
@@ -315,7 +318,7 @@
},
"cta": {
"title": "¿Listo para comenzar?",
"description": "Únete a miles de usuarios que confían en Bentopdf para sus necesidades diarias de documentos. Experimenta la diferencia que la privacidad y el rendimiento pueden hacer.",
"description": "Únete a miles de usuarios que confían en BentoPDF para sus necesidades diarias de documentos. Experimenta la diferencia que la privacidad y el rendimiento pueden hacer.",
"button": "Explorar Todas las Herramientas"
}
},
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Haz clic en cualquier párrafo y edítalo directamente con reajuste de texto en vivo, fuentes y estilos.",
"saved": "¡PDF guardado correctamente! ({{size}} KB)",
"failedToLoad": "No se pudo cargar el editor de texto PDF.",
"loadingFonts": "Cargando fuentes...",
"fontsUnavailable": "No se pudo descargar una fuente necesaria para algunos caracteres. Comprueba tu conexión e inténtalo de nuevo; de lo contrario, es posible que esos caracteres no se vean correctamente en el PDF guardado.",
"howToUpload": "Subir PDF",
"howToClick": "Haz clic en un párrafo",
"howToRestyle": "Cambia el estilo de todo",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "¡Sí! Active la opción \"Repetir\" y las páginas de superposición se repetirán en todas las páginas base. Una marca de agua de una página se aplicará a cada página.",
"faqPrivacyQuestion": "¿Mis archivos son privados y seguros?",
"faqPrivacyAnswer": "¡Por supuesto! Todo el procesamiento ocurre en su navegador. Sus archivos nunca abandonan su dispositivo, garantizando total privacidad."
},
"unlockPdf": {
"name": "Descifrar PDF",
"subtitle": "Desbloquea PDF eliminando la protección por contraseña."
},
"protectPdf": {
"name": "Cifrar PDF",
"subtitle": "Bloquea tu PDF agregando una contraseña."
}
}
+6 -3
View File
@@ -222,7 +222,7 @@
"testimonials": {
"title": "Ce que disent",
"users": "nos utilisateurs",
"say": ""
"say": " "
},
"support": {
"title": "Vous aimez ce projet ?",
@@ -239,7 +239,9 @@
"legal": "Mentions légales",
"termsAndConditions": "Conditions générales",
"privacyPolicy": "Politique de confidentialité",
"followUs": "Nous suivre"
"followUs": "Nous suivre",
"privacyShort": "Confidentialité",
"termsShort": "Conditions"
},
"merge": {
"title": "Fusionner des PDF",
@@ -286,7 +288,8 @@
"noCompromises": "Sans compromis."
},
"mission": {
"title": "Notre mission",
"title": "Notre",
"titleDim": "mission",
"description": "Proposer la palette d’outils PDF la plus complète, tout en respectant votre vie privée et sans jamais demander de paiement. Les outils essentiels doivent être accessibles à tous, partout, sans barrières."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Cliquer sur un paragraphe et le modifier directement, avec remise en page instantanée, polices et styles.",
"saved": "PDF enregistré avec succès ! ({{size}} Ko)",
"failedToLoad": "Impossible de charger l'éditeur de texte PDF.",
"loadingFonts": "Chargement des polices...",
"fontsUnavailable": "Impossible de télécharger une police nécessaire à certains caractères. Vérifiez votre connexion et réessayez, sinon ces caractères risquent de ne pas s'afficher correctement dans le PDF enregistré.",
"howToUpload": "Importer un PDF",
"howToClick": "Cliquer sur un paragraphe",
"howToRestyle": "Tout restyler",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Oui ! Activez l'option \"Répéter\" et vos pages de superposition se répéteront sur toutes les pages de base. Un filigrane d'une seule page s'appliquera à chaque page.",
"faqPrivacyQuestion": "Mes fichiers sont-ils privés et sécurisés ?",
"faqPrivacyAnswer": "Absolument ! Tout le traitement se fait dans votre navigateur. Vos fichiers ne quittent jamais votre appareil, garantissant une confidentialité totale."
},
"unlockPdf": {
"name": "Déverrouiller un PDF",
"subtitle": "Supprimer la protection par mot de passe."
},
"protectPdf": {
"name": "Chiffrer un PDF",
"subtitle": "Protéger le PDF en ajoutant un mot de passe."
}
}
+8 -5
View File
@@ -212,7 +212,7 @@
},
"browserBased": {
"question": "Bagaimana pemrosesan berbasis browser menjaga keamanan saya?",
"answer": "Dengan berjalan sepenuhnya di dalam browser Anda, BentoPDF memastikan file Anda tidak pernah meninggalkan perangkat Anda. Ini menghilangkan risiko peretasan server, pelanggaran data, atau akses tidak sah. File Anda tetap milik Anda—selalu."
"answer": "Dengan berjalan sepenuhnya di dalam browser Anda, BentoPDF memastikan file Anda tidak pernah meninggalkan perangkat Anda. Ini menghilangkan risiko peretasan server, pelanggaran data, atau akses tidak sah. File Anda tetap milik Anda, selalu."
},
"analytics": {
"question": "Apakah Anda menggunakan cookie atau analitik untuk melacak saya?",
@@ -239,7 +239,9 @@
"legal": "Hukum",
"termsAndConditions": "Syarat dan Ketentuan",
"privacyPolicy": "Kebijakan Privasi",
"followUs": "Ikuti Kami"
"followUs": "Ikuti Kami",
"privacyShort": "Privasi",
"termsShort": "Ketentuan"
},
"merge": {
"title": "Gabung PDF",
@@ -286,13 +288,14 @@
"noCompromises": "Tidak ada kompromi."
},
"mission": {
"title": "Misi Kami",
"title": "Misi",
"titleDim": "Kami",
"description": "Untuk menyediakan toolbox PDF paling komprehensif yang menghormati privasi Anda dan tidak pernah meminta pembayaran. Kami percaya alat dokumen penting harus dapat diakses oleh semua orang, di mana saja, tanpa hambatan."
},
"philosophy": {
"label": "Filosofi Inti Kami",
"title": "Privasi Yang Utama. Selalu.",
"description": "Di era di mana data adalah komoditas, kami mengambil pendekatan berbeda. Semua pemrosesan untuk alat Bentopdf terjadi secara lokal di browser Anda. Ini berarti file Anda tidak pernah menyentuh server kami, kami tidak pernah melihat dokumen Anda, dan kami tidak melacak apa yang Anda lakukan. Dokumen Anda tetap utuh dan privat secara tegas. Ini bukan hanya fitur; ini adalah fondasi kami."
"description": "Di era di mana data adalah komoditas, kami mengambil pendekatan berbeda. Semua pemrosesan untuk alat BentoPDF terjadi secara lokal di browser Anda. Ini berarti file Anda tidak pernah menyentuh server kami, kami tidak pernah melihat dokumen Anda, dan kami tidak melacak apa yang Anda lakukan. Dokumen Anda tetap utuh dan privat secara tegas. Ini bukan hanya fitur; ini adalah fondasi kami."
},
"whyBentopdf": {
"title": "Mengapa",
@@ -315,7 +318,7 @@
},
"cta": {
"title": "Siap untuk memulai?",
"description": "Bergabunglah dengan ribuan pengguna yang percaya Bentopdf untuk kebutuhan dokumen harian mereka. Rasakan bedanya privasi dan performa yang ditawarkan.",
"description": "Bergabunglah dengan ribuan pengguna yang percaya BentoPDF untuk kebutuhan dokumen harian mereka. Rasakan bedanya privasi dan performa yang ditawarkan.",
"button": "Jelajahi Semua Alat"
}
},
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Klik paragraf mana pun dan edit langsung di tempat dengan penyusunan ulang teks secara langsung, font, dan gaya.",
"saved": "PDF berhasil disimpan! ({{size}} KB)",
"failedToLoad": "Gagal memuat Editor Teks PDF.",
"loadingFonts": "Memuat font...",
"fontsUnavailable": "Font yang diperlukan untuk beberapa karakter tidak dapat diunduh. Periksa koneksi Anda dan coba lagi, atau karakter tersebut mungkin tidak tampil dengan benar di PDF yang disimpan.",
"howToUpload": "Unggah PDF",
"howToClick": "Klik sebuah paragraf",
"howToRestyle": "Ubah gaya apa pun",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Ya! Aktifkan opsi \"Ulangi\" dan halaman overlay Anda akan berulang di semua halaman dasar. Watermark satu halaman akan diterapkan ke setiap halaman.",
"faqPrivacyQuestion": "Apakah file saya pribadi dan aman?",
"faqPrivacyAnswer": "Tentu saja! Semua pemrosesan terjadi di browser Anda. File Anda tidak pernah meninggalkan perangkat Anda, memastikan privasi penuh."
},
"unlockPdf": {
"name": "Dekripsi PDF",
"subtitle": "Buka kunci PDF dengan menghapus perlindungan kata sandi."
},
"protectPdf": {
"name": "Enkripsi PDF",
"subtitle": "Kunci PDF Anda dengan menambahkan kata sandi."
}
}
+5 -2
View File
@@ -239,7 +239,9 @@
"legal": "Legale",
"termsAndConditions": "Termini e condizioni",
"privacyPolicy": "Informativa sulla privacy",
"followUs": "Seguici"
"followUs": "Seguici",
"privacyShort": "Privacy",
"termsShort": "Termini"
},
"merge": {
"title": "Unisci PDF",
@@ -286,7 +288,8 @@
"noCompromises": "Nessun compromesso."
},
"mission": {
"title": "La nostra missione",
"title": "La nostra",
"titleDim": "missione",
"description": "Fornire la cassetta degli attrezzi per PDF più completa che rispetti la tua privacy e non richieda mai pagamenti. Crediamo che gli strumenti essenziali per i documenti debbano essere accessibili a tutti, ovunque, senza barriere."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Clicca su un paragrafo qualsiasi e modificalo direttamente con ricomposizione del testo in tempo reale, caratteri e stili.",
"saved": "PDF salvato correttamente! ({{size}} KB)",
"failedToLoad": "Impossibile caricare l'editor di testo PDF.",
"loadingFonts": "Caricamento dei font...",
"fontsUnavailable": "Impossibile scaricare un font necessario per alcuni caratteri. Controlla la connessione e riprova, altrimenti questi caratteri potrebbero non essere visualizzati correttamente nel PDF salvato.",
"howToUpload": "Carica PDF",
"howToClick": "Fai clic su un paragrafo",
"howToRestyle": "Ridefinisci lo stile",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Sì! Attiva l'opzione \"Ripeti\" e le pagine di sovrapposizione si ripeteranno su tutte le pagine base. Una filigrana di una pagina verrà applicata a ogni pagina.",
"faqPrivacyQuestion": "I miei file sono privati e sicuri?",
"faqPrivacyAnswer": "Assolutamente! Tutta l'elaborazione avviene nel tuo browser. I tuoi file non lasciano mai il tuo dispositivo, garantendo la massima privacy."
},
"unlockPdf": {
"name": "Decrittografa PDF",
"subtitle": "Sblocca il PDF rimuovendo la protezione tramite password."
},
"protectPdf": {
"name": "Cripta PDF",
"subtitle": "Proteggi il tuo PDF aggiungendo una password."
}
}
+4 -1
View File
@@ -239,7 +239,9 @@
"legal": "法的情報",
"termsAndConditions": "利用規約",
"privacyPolicy": "プライバシーポリシー",
"followUs": "フォローする"
"followUs": "フォローする",
"privacyShort": "プライバシー",
"termsShort": "利用規約"
},
"merge": {
"title": "PDFの結合",
@@ -287,6 +289,7 @@
},
"mission": {
"title": "私たちの使命",
"titleDim": " ",
"description": "あなたのプライバシーを尊重し、決して支払いを要求しない、最も包括的なPDFツールボックスを提供すること。私たちは必須のドキュメントツールは誰でも、どこでも、障壁なくアクセスできるべきだと考えています。"
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "段落をクリックしてその場で編集。テキストは自動で再配置され、フォントやスタイルも変更できます。",
"saved": "PDF を保存しました!({{size}} KB)",
"failedToLoad": "PDF テキストエディタを読み込めませんでした。",
"loadingFonts": "フォントを読み込み中...",
"fontsUnavailable": "一部の文字に必要なフォントをダウンロードできませんでした。接続を確認してもう一度お試しください。このままでは、保存した PDF でそれらの文字が正しく表示されない可能性があります。",
"howToUpload": "PDF をアップロード",
"howToClick": "段落をクリック",
"howToRestyle": "自由にスタイル変更",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "はい! 「ループ」オプションを有効にすると、オーバーレイPDFページがすべてのベース ページにわたって繰り返されます。単一ページのウォーターマークはすべてのページに適用されます。",
"faqPrivacyQuestion": "私のファイルは非公開で安全ですか?",
"faqPrivacyAnswer": "絶対に!すべての処理はブラウザ内で行われます。ファイルがデバイスの外に出ることはなく、完全なプライバシーが確保されます。"
},
"unlockPdf": {
"name": "PDFの復号化",
"subtitle": "パスワード保護を解除してPDFのロックを解除します。"
},
"protectPdf": {
"name": "PDFの暗号化",
"subtitle": "パスワードを追加してPDFをロックします。"
}
}
+6 -3
View File
@@ -222,7 +222,7 @@
"testimonials": {
"title": "사용자",
"users": "후기",
"say": ""
"say": " "
},
"support": {
"title": "도움이 되셨나요?",
@@ -239,7 +239,9 @@
"legal": "법적 고지",
"termsAndConditions": "이용약관",
"privacyPolicy": "개인정보처리방침",
"followUs": "팔로우"
"followUs": "팔로우",
"privacyShort": "개인정보",
"termsShort": "이용약관"
},
"merge": {
"title": "PDF 병합",
@@ -286,7 +288,8 @@
"noCompromises": "타협 없이."
},
"mission": {
"title": "우리의 목표",
"title": "우리의",
"titleDim": "목표",
"description": "프라이버시를 지키면서도 비용 부담 없는, 가장 완벽한 PDF 도구를 만드는 것입니다. 꼭 필요한 문서 도구는 누구나, 어디서든 자유롭게 쓸 수 있어야 합니다."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "아무 단락이나 클릭해 실시간 리플로우, 글꼴, 스타일과 함께 바로 편집하세요.",
"saved": "PDF를 저장했습니다! ({{size}} KB)",
"failedToLoad": "PDF 텍스트 편집기를 불러오지 못했습니다.",
"loadingFonts": "글꼴을 불러오는 중...",
"fontsUnavailable": "일부 문자에 필요한 글꼴을 다운로드하지 못했습니다. 연결을 확인하고 다시 시도하세요. 그렇지 않으면 저장된 PDF에서 해당 문자가 올바르게 표시되지 않을 수 있습니다.",
"howToUpload": "PDF 업로드",
"howToClick": "문단 클릭",
"howToRestyle": "무엇이든 스타일 변경",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "네! \"반복\" 옵션을 활성화하면 오버레이 페이지가 모든 기본 페이지에 반복됩니다. 단일 페이지 워터마크가 모든 페이지에 적용됩니다.",
"faqPrivacyQuestion": "내 파일은 비공개이고 안전한가요?",
"faqPrivacyAnswer": "물론입니다! 모든 처리는 브라우저에서 이루어집니다. 파일이 기기를 떠나지 않아 완전한 개인정보 보호가 보장됩니다."
},
"unlockPdf": {
"name": "PDF 복호화",
"subtitle": "비밀번호를 제거하여 PDF 잠금을 해제합니다."
},
"protectPdf": {
"name": "PDF 암호화",
"subtitle": "비밀번호를 설정하여 PDF를 보호합니다."
}
}
+7 -4
View File
@@ -1,6 +1,6 @@
{
"nav": {
"home": "Thuis",
"home": "Startpagina",
"about": "Over",
"contact": "Contact",
"licensing": "Licentie",
@@ -239,7 +239,9 @@
"legal": "Juridisch",
"termsAndConditions": "Algemene voorwaarden",
"privacyPolicy": "Privacybeleid",
"followUs": "Volgen"
"followUs": "Volgen",
"privacyShort": "Privacy",
"termsShort": "Voorwaarden"
},
"merge": {
"title": "PDF's samenvoegen",
@@ -286,7 +288,8 @@
"noCompromises": "Geen compromissen."
},
"mission": {
"title": "Onze missie",
"title": "Onze",
"titleDim": "missie",
"description": "Ons doel is om de meest complete PDF-toolbox te bieden die je privacy respecteert en nooit om betaling vraagt. Wij geloven dat essentiële documententools voor iedereen, overal en zonder obstakels toegankelijk moeten zijn."
},
"philosophy": {
@@ -382,6 +385,6 @@
"title": "Tool niet beschikbaar",
"heading": "Deze tool is uitgeschakeld",
"message": "Deze tool is niet beschikbaar in deze implementatie. Neem contact op met de beheerder voor meer informatie.",
"backHome": "Terug naar Thuis"
"backHome": "Terug naar Startpagina"
}
}
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Klik op een alinea en bewerk deze direct, met live tekstomloop, lettertypen en opmaak.",
"saved": "PDF is opgeslagen! ({{size}} KB)",
"failedToLoad": "Kan de PDF-teksteditor niet laden.",
"loadingFonts": "Lettertypen laden…",
"fontsUnavailable": "Een lettertype dat nodig is voor sommige tekens kon niet worden gedownload. Controleer de verbinding en probeer het opnieuw, anders worden deze tekens mogelijk niet correct weergegeven in de opgeslagen PDF.",
"howToUpload": "PDF uploaden",
"howToClick": "Klik op een alinea",
"howToRestyle": "Alles opnieuw vormgeven",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Ja! Schakel de optie \"Herhalen\" in en de overlay-pagina's worden herhaald over alle basispagina's. Een watermerk van één pagina wordt op elke pagina toegepast.",
"faqPrivacyQuestion": "Zijn mijn bestanden privé en veilig?",
"faqPrivacyAnswer": "Absoluut! Alle verwerking vindt plaats in jouw browser. Jouw bestanden verlaten nooit jouw apparaat, wat volledige privacy garandeert."
},
"unlockPdf": {
"name": "PDF Ontgrendelen",
"subtitle": "Een PDF ontgrendelen door het verwijderen van de wachtwoordbeveiliging."
},
"protectPdf": {
"name": "PDF Versleutelen",
"subtitle": "Een PDF vergrendelen door toevoeging van een toegangswachtwoord."
}
}
+387
View File
@@ -0,0 +1,387 @@
{
"nav": {
"home": "Strona główna",
"about": "O nas",
"contact": "Kontakt",
"licensing": "Licencjonowanie",
"allTools": "Wszystkie narzędzia",
"docs": "Dokumentacja",
"openMainMenu": "Otwórz menu główne",
"language": "Język",
"searchLanguage": "Szukaj języka…",
"noLanguagesFound": "Nie znaleziono języków"
},
"donation": {
"message": "Uwielbiasz BentoPDF? Pomóż nam utrzymać go jako darmowe i otwarte oprogramowanie!",
"button": "Wesprzyj"
},
"hero": {
"title": "Twój",
"pdfToolkit": "zestaw narzędzi PDF",
"builtForPrivacy": "stworzony z myślą o prywatności",
"noSignups": "Brak rejestracji",
"unlimitedUse": "Nielimitowane korzystanie",
"worksOffline": "Działa offline",
"startUsing": "Zacznij używać teraz"
},
"usedBy": {
"title": "Używane przez firmy i osoby pracujące w"
},
"features": {
"title": "Dlaczego warto wybrać",
"bentoPdf": "BentoPDF?",
"noSignup": {
"title": "Bez rejestracji",
"description": "Zacznij od razu, bez kont i e-maili."
},
"noUploads": {
"title": "Bez wysyłania na serwer",
"description": "W 100% po stronie klienta, Twoje pliki nigdy nie opuszczają urządzenia."
},
"foreverFree": {
"title": "Zawsze darmowe",
"description": "Wszystkie narzędzia, bez okresów próbnych i ukrytych opłat."
},
"noLimits": {
"title": "Bez limitów",
"description": "Używaj bez ograniczeń, brak ukrytych limitów."
},
"batchProcessing": {
"title": "Przetwarzanie wsadowe",
"description": "Obsługuj nieograniczoną liczbę plików PDF za jednym razem."
},
"lightningFast": {
"title": "Błyskawicznie",
"description": "Przetwarzaj pliki PDF natychmiast, bez czekania i opóźnień."
}
},
"tools": {
"title": "Rozpocznij z",
"toolsLabel": "Narzędzia",
"subtitle": "Kliknij narzędzie, aby otworzyć przesyłanie plików",
"searchPlaceholder": "Szukaj narzędzia (np. 'podziel', 'organizuj'...)",
"backToTools": "Wróć do narzędzi",
"firstLoadNotice": "Pierwsze wczytywanie potrwa chwilę, ponieważ pobieramy nasz silnik konwersji. Potem wszystkie ładowania będą natychmiastowe."
},
"upload": {
"clickToSelect": "Kliknij, aby wybrać plik",
"orDragAndDrop": "lub przeciągnij i upuść",
"pdfOrImages": "Pliki PDF lub obrazy",
"filesNeverLeave": "Twoje pliki nigdy nie opuszczają Twojego urządzenia.",
"addMore": "Dodaj więcej plików",
"clearAll": "Wyczyść wszystko",
"clearFiles": "Wyczyść pliki",
"hints": {
"singlePdf": "Pojedynczy plik PDF",
"pdfFile": "Plik PDF",
"multiplePdfs2": "Wiele plików PDF (co najmniej 2)",
"bmpImages": "Obrazy BMP",
"oneOrMorePdfs": "Jeden lub więcej plików PDF",
"pdfDocuments": "Dokumenty PDF",
"oneOrMoreCsv": "Jeden lub więcej plików CSV",
"multiplePdfsSupported": "Obsługiwane wiele plików PDF",
"singleOrMultiplePdfs": "Obsługiwane pojedyncze lub wielokrotne pliki PDF",
"singlePdfFile": "Pojedynczy plik PDF",
"pdfWithForms": "Plik PDF z polami formularza",
"heicImages": "Obrazy HEIC/HEIF",
"jpgImages": "Obrazy JPG, JPEG, JP2, JPX",
"pdfsOrImages": "Pliki PDF lub obrazy",
"oneOrMoreOdt": "Jeden lub więcej plików ODT",
"singlePdfOnly": "Tylko pojedynczy plik PDF",
"pdfFiles": "Pliki PDF",
"multiplePdfs": "Wiele plików PDF",
"pngImages": "Obrazy PNG",
"pdfFilesOneOrMore": "Pliki PDF (jeden lub więcej)",
"oneOrMoreRtf": "Jeden lub więcej plików RTF",
"svgGraphics": "Grafika SVG",
"tiffImages": "Obrazy TIFF",
"webpImages": "Obrazy WebP"
}
},
"howItWorks": {
"title": "Jak to działa",
"step1Title": "Prześlij plik",
"step1": "Kliknij lub przeciągnij i upuść plik, aby rozpocząć",
"step2Title": "Przetwarzaj",
"step2": "Kliknij przycisk przetwarzania, aby rozpocząć",
"step3Title": "Pobierz",
"step3": "Natychmiast zapisz przetworzony plik"
},
"relatedTools": {
"title": "Powiązane narzędzia PDF"
},
"loader": {
"processing": "Przetwarzanie..."
},
"alert": {
"title": "Uwaga",
"ok": "OK"
},
"preview": {
"title": "Podgląd dokumentu",
"downloadAsPdf": "Pobierz jako PDF",
"close": "Zamknij"
},
"settings": {
"title": "Ustawienia",
"shortcuts": "Skróty",
"preferences": "Preferencje",
"displayPreferences": "Preferencje wyświetlania",
"searchShortcuts": "Szukaj skrótów...",
"shortcutsInfo": "Naciśnij i przytrzymaj klawisze, aby ustawić skrót. Zmiany są zapisywane automatycznie.",
"shortcutsWarning": "⚠️ Unikaj popularnych skrótów przeglądarki (Cmd/Ctrl+W, Cmd/Ctrl+T, Cmd/Ctrl+N itp.), ponieważ mogą nie działać prawidłowo.",
"import": "Importuj",
"export": "Eksportuj",
"resetToDefaults": "Przywróć domyślne",
"fullWidthMode": "Tryb pełnej szerokości",
"fullWidthDescription": "Używaj pełnej szerokości ekranu dla wszystkich narzędzi zamiast wyśrodkowanego kontenera",
"compactMode": "Tryb kompaktowy",
"compactModeDescription": "Wyświetlaj narzędzia jako kompaktową listę zamiast kart",
"advancedSettings": "Ustawienia zaawansowane",
"advancedSettingsDescription": "Skonfiguruj zewnętrzne moduły przetwarzania (PyMuPDF, Ghostscript, CoherentPDF)",
"settingsAutoSaved": "Ustawienia są zapisywane automatycznie",
"clickToSet": "Kliknij, aby ustawić",
"pressKeys": "Naciśnij klawisze...",
"warnings": {
"alreadyInUse": "Skrót jest już w użyciu",
"assignedTo": "jest już przypisany do:",
"chooseDifferent": "Proszę wybrać inny skrót.",
"reserved": "Ostrzeżenie o zarezerwowanym skrócie",
"commonlyUsed": "jest powszechnie używany do:",
"unreliable": "Ten skrót może nie działać niezawodnie lub może kolidować z działaniem przeglądarki/systemu.",
"useAnyway": "Czy mimo to chcesz go użyć?",
"resetTitle": "Zresetuj skróty",
"resetMessage": "Czy na pewno chcesz zresetować wszystkie skróty do wartości domyślnych?<br><br>Tej akcji nie można cofnąć.",
"importSuccessTitle": "Import zakończony sukcesem",
"importSuccessMessage": "Skróty zostały pomyślnie zaimportowane!",
"importFailTitle": "Import nie powiódł się",
"importFailMessage": "Nie udało się zaimportować skrótów. Nieprawidłowy format pliku."
}
},
"warning": {
"title": "Ostrzeżenie",
"cancel": "Anuluj",
"proceed": "Kontynuuj"
},
"compliance": {
"title": "Twoje dane nigdy nie opuszczają Twojego urządzenia",
"weKeep": "Dbamy o",
"yourInfoSafe": "bezpieczeństwo Twoich informacji",
"byFollowingStandards": "przestrzegając globalnych standardów bezpieczeństwa.",
"processingLocal": "Całe przetwarzanie odbywa się lokalnie na Twoim urządzeniu.",
"gdpr": {
"title": "Zgodność z RODO",
"description": "Chroni dane osobowe i prywatność osób w Unii Europejskiej."
},
"ccpa": {
"title": "Zgodność z CCPA",
"description": "Daje mieszkańcom Kalifornii prawa do kontrolowania sposobu gromadzenia, wykorzystywania i udostępniania ich danych osobowych."
},
"hipaa": {
"title": "Zgodność z HIPAA",
"description": "Ustanawia zabezpieczenia w celu ochrony wrażliwych informacji zdrowotnych w systemie opieki zdrowotnej Stanów Zjednoczonych."
}
},
"faq": {
"title": "Często Zadawane",
"questions": "Pytania",
"sectionTitle": "Często Zadawane Pytania",
"isFree": {
"question": "Czy BentoPDF jest naprawdę darmowy?",
"answer": "Tak, absolutnie. Wszystkie narzędzia w BentoPDF są w 100% darmowe do użytku, bez limitów plików, bez rejestracji i bez znaków wodnych. Wierzymy, że każdy zasługuje na dostęp do prostych, potężnych narzędzi PDF bez barier płatnych."
},
"areFilesSecure": {
"question": "Czy moje pliki są bezpieczne? Gdzie są przetwarzane?",
"answer": "Twoje pliki są maksymalnie bezpieczne, ponieważ nigdy nie opuszczają Twojego komputera. Całe przetwarzanie odbywa się bezpośrednio w Twojej przeglądarce internetowej (po stronie klienta). Nigdy nie wysyłamy Twoich plików na serwer, dzięki czemu zachowujesz pełną prywatność i kontrolę nad swoimi dokumentami."
},
"platforms": {
"question": "Czy to działa na Macu, Windowsie i urządzeniach mobilnych?",
"answer": "Tak! Ponieważ BentoPDF działa całkowicie w Twojej przeglądarce, obsługuje dowolny system operacyjny z nowoczesną przeglądarką internetową, w tym Windows, macOS, Linux, iOS oraz Android."
},
"gdprCompliant": {
"question": "Czy BentoPDF jest zgodny z RODO?",
"answer": "Tak. BentoPDF jest w pełni zgodny z RODO. Ponieważ całe przetwarzanie plików odbywa się lokalnie w Twojej przeglądarce, a my nigdy nie zbieramy ani nie wysyłamy Twoich plików na żaden serwer, nie mamy dostępu do Twoich danych. Gwarantuje to, że zawsze sprawujesz pełną kontrolę nad swoimi dokumentami."
},
"dataStorage": {
"question": "Czy przechowujecie lub śledzicie jakiekolwiek moje pliki?",
"answer": "Nie. Nigdy nie przechowujemy, nie śledzimy ani nie logujemy Twoich plików. Wszystko, co robisz w BentoPDF, odbywa się w pamięci Twojej przeglądarki i znika po zamknięciu strony. Nie ma żadnych transferów, logów historii ani serwerów."
},
"different": {
"question": "Czym różni się BentoPDF od innych narzędzi PDF?",
"answer": "Większość narzędzi PDF wysyła Twoje pliki na serwer w celu ich przetworzenia. BentoPDF nigdy tego nie robi. Wykorzystujemy bezpieczną, nowoczesną technologię internetową, aby przetwarzać Twoje pliki bezpośrednio w przeglądarce. Oznacza to większą wydajność, silniejszą prywatność i pełen spokój ducha."
},
"browserBased": {
"question": "W jaki sposób przetwarzanie w oparciu o przeglądarkę zapewnia mi bezpieczeństwo?",
"answer": "Działając całkowicie wewnątrz Twojej przeglądarki, BentoPDF gwarantuje, że Twoje pliki nigdy nie opuszczą Twojego urządzenia. Eliminuje to ryzyko ataków hakerskich na serwery, naruszeń bezpieczeństwa danych czy nieautoryzowanego dostępu. Twoje pliki pozostają Twoje — zawsze."
},
"analytics": {
"question": "Czy używacie plików cookie lub analityki do mojego śledzenia?",
"answer": "Dbamy o Twoją prywatność. BentoPDF nie śledzi danych osobowych. Używamy Simple Analytics wyłącznie w celu sprawdzenia anonimowej liczby wizyt. Oznacza to, że wiemy, ilu użytkowników odwiedza naszą stronę, ale nigdy nie wiemy, kim jesteś. Simple Analytics jest w pełni zgodne z RODO i szanuje Twoją prywatność."
}
},
"testimonials": {
"title": "Co Nasi",
"users": "Użytkownicy",
"say": "Mówią"
},
"support": {
"title": "Podoba Ci się moja praca?",
"description": "BentoPDF to projekt z pasji, stworzony po to, aby udostępnić darmowy, prywatny i potężny zestaw narzędzi PDF dla każdego. Jeśli uznasz go za przydatny, rozważ wsparcie jego rozwoju. Każda kawa pomaga!",
"buyMeCoffee": "Postaw mi kawę"
},
"footer": {
"copyright": "© 2026 BentoPDF. Wszelkie prawa zastrzeżone.",
"version": "Wersja",
"company": "Firma",
"aboutUs": "O nas",
"faqLink": "FAQ",
"contactUs": "Kontakt",
"legal": "Kwestie prawne",
"termsAndConditions": "Zasady i warunki",
"privacyPolicy": "Polityka prywatności",
"followUs": "Śledź nas"
},
"merge": {
"title": "Połącz pliki PDF",
"description": "Połącz całe pliki lub wybierz konkretne strony do scalenia w nowy dokument.",
"fileMode": "Tryb pliku",
"pageMode": "Tryb strony",
"howItWorks": "Jak to działa:",
"fileModeInstructions": [
"Kliknij i przeciągnij ikonę, aby zmienić kolejność plików.",
"W polu \"Strony\" dla każdego pliku możesz określić zakresy (np. \"1-3, 5\"), aby połączyć tylko te strony.",
"Pozostaw pole \"Strony\" puste, aby dołączyć wszystkie strony z tego pliku."
],
"pageModeInstructions": [
"Poniżej widoczne są wszystkie strony z przesłanych plików PDF.",
"Po prostu przeciągnij i upuść poszczególne miniatury stron, aby ułożyć je w dokładnej kolejności dla nowego pliku."
],
"mergePdfs": "Połącz PDF-y"
},
"common": {
"page": "Strona",
"pages": "Strony",
"of": "z",
"download": "Pobierz",
"cancel": "Anuluj",
"save": "Zapisz",
"delete": "Usuń",
"edit": "Edytuj",
"add": "Dodaj",
"remove": "Usuń",
"loading": "Ładowanie...",
"loadingPageCount": "Wczytywanie stron...",
"error": "Błąd",
"success": "Sukces",
"file": "Plik",
"files": "Pliki",
"close": "Zamknij",
"convert": "Konwertuj",
"unknownError": "Nieznany błąd"
},
"about": {
"hero": {
"title": "Wierzymy, że narzędzia PDF powinny być",
"subtitle": "szybkie, prywatne i darmowe.",
"noCompromises": "Bez kompromisów."
},
"mission": {
"title": "Nasza misja",
"description": "Zapewnienie najbardziej wszechstronnego zestawu narzędzi PDF, który szanuje Twoją prywatność i nigdy nie prosi o płatność. Wierzymy, że podstawowe narzędzia do dokumentów powinny być dostępne dla każdego, wszędzie i bez barier."
},
"philosophy": {
"label": "Nasza główna filozofia",
"title": "Prywatność na pierwszym miejscu. Zawsze.",
"description": "W czasach, gdy dane są towarem, my przyjmujemy inne podejście. Całe przetwarzanie w narzędziach BentoPDF odbywa się lokalnie w Twojej przeglądarce. Oznacza to, że Twoje pliki nigdy nie stykają się z naszymi serwerami, nigdy nie widzimy Twoich dokumentów i nie śledzimy tego, co robisz. Twoje dokumenty pozostają całkowicie i bezsprzecznie prywatne. To nie tylko funkcja; to nasz fundament."
},
"whyBentopdf": {
"title": "Dlaczego",
"speed": {
"title": "Zbudowane dla szybkości",
"description": "Bez czekania na wysłanie lub pobranie z serwera. Przetwarzając pliki bezpośrednio w Twojej przeglądarce przy użyciu nowoczesnych technologii internetowych, takich jak WebAssembly, oferujemy niezrównaną prędkość dla wszystkich naszych narzędzi."
},
"free": {
"title": "Całkowicie darmowe",
"description": "Bez wersji próbnych, bez subskrypcji, bez ukrytych opłat i bez „funkcji premium” wziętych jako zakładników. Wierzymy, że potężne narzędzia PDF powinny być dobrem publicznym, a nie centrum zysków."
},
"noAccount": {
"title": "Konto nie jest wymagane",
"description": "Zacznij natychmiast używać dowolnego narzędzia. Nie potrzebujemy Twojego e-maila, hasła ani żadnych danych osobowych. Twój przepływ pracy powinien być bezproblemowy i anonimowy."
},
"openSource": {
"title": "Duch Open Source",
"description": "Stworzone z myślą o przejrzystości. Korzystamy z niesamowitych bibliotek open-source, takich jak PDF-lib i PDF.js, oraz wierzymy w społeczny wysiłek, dzięki któremu potężne narzędzia są dostępne dla wszystkich."
}
},
"cta": {
"title": "Gotowy, aby zacząć?",
"description": "Dołącz do tysięcy użytkowników, którzy ufają BentoPDF w codziennych zadaniach z dokumentami. Poczuj różnicę, jaką potrafią zrobić prywatność i wydajność.",
"button": "Odkryj wszystkie narzędzia"
}
},
"contact": {
"title": "Bądźmy w kontakcie",
"subtitle": "Z przyjemnością Cię wysłuchamy. Niezależnie od tego, czy masz pytanie, opinię, czy prośbę o nową funkcję, nie wahaj się do nas napisać.",
"email": "Możesz się z nami skontaktować bezpośrednio poprzez e-mail na adres:"
},
"licensing": {
"title": "Licencjonowanie dla",
"subtitle": "Wybierz licencję, która odpowiada Twoim potrzebom."
},
"multiTool": {
"uploadPdfs": "Prześlij pliki PDF",
"upload": "Prześlij",
"addBlankPage": "Dodaj pustą stronę",
"edit": "Edytuj:",
"undo": "Cofnij",
"redo": "Ponów",
"reset": "Zresetuj",
"selection": "Wybór:",
"selectAll": "Zaznacz wszystko",
"deselectAll": "Odznacz wszystko",
"rotate": "Obróć:",
"rotateLeft": "W lewo",
"rotateRight": "W prawo",
"transform": "Przekształć:",
"duplicate": "Powiel",
"split": "Podziel",
"clear": "Wyczyść:",
"delete": "Usuń",
"download": "Pobierz:",
"downloadSelected": "Pobierz wybrane",
"exportPdf": "Eksportuj PDF",
"uploadPdfFiles": "Wybierz pliki PDF lub obrazy",
"dragAndDrop": "Przeciągnij i upuść pliki PDF lub obrazy tutaj, albo kliknij, by wybrać",
"selectFiles": "Wybierz pliki",
"dropToAdd": "Upuść pliki PDF lub obrazy, aby dodać",
"convertingImages": "Konwertowanie obrazów do formatu PDF...",
"failedToConvertImages": "Nie udało się przekonwertować obrazów do pliku PDF.",
"renderingPages": "Renderowanie stron...",
"actions": {
"duplicatePage": "Powiel tę stronę",
"deletePage": "Usuń tę stronę",
"insertPdf": "Wstaw PDF po tej stronie",
"toggleSplit": "Przełącz podział po tej stronie"
},
"pleaseWait": "Proszę czekać",
"pagesRendering": "Strony są nadal renderowane. Proszę czekać...",
"noPagesSelected": "Nie wybrano stron",
"selectOnePage": "Wybierz co najmniej jedną stronę do pobrania.",
"noPages": "Brak stron",
"noPagesToExport": "Nie ma stron do wyeksportowania.",
"renderingTitle": "Renderowanie podglądów stron",
"errorRendering": "Nie udało się wyrenderować miniatur stron",
"error": "Błąd",
"failedToLoad": "Nie udało się załadować"
},
"simpleMode": {
"title": "Narzędzia PDF",
"subtitle": "Wybierz narzędzie, aby rozpocząć"
},
"disabledTool": {
"title": "Narzędzie niedostępne",
"heading": "To narzędzie zostało wyłączone",
"message": "To narzędzie nie jest dostępne w Twoim środowisku. Skontaktuj się z administratorem, aby uzyskać więcej informacji.",
"backHome": "Powrót do strony głównej"
}
}
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -239,7 +239,9 @@
"legal": "Jurídico",
"termsAndConditions": "Termos e Condições",
"privacyPolicy": "Política de Privacidade",
"followUs": "Siga-nos"
"followUs": "Siga-nos",
"privacyShort": "Privacidade",
"termsShort": "Termos"
},
"merge": {
"title": "Mesclar PDFs",
@@ -286,7 +288,8 @@
"noCompromises": "Sem concessões."
},
"mission": {
"title": "Nossa Missão",
"title": "Nossa",
"titleDim": "Missão",
"description": "Fornecer o kit de ferramentas PDF mais completo, respeitando sua privacidade e sem cobrar por isso. Ferramentas essenciais devem ser acessíveis a todos, sem barreiras."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Clique em qualquer parágrafo e edite-o no local com reorganização do texto em tempo real, fontes e estilos.",
"saved": "PDF salvo com sucesso! ({{size}} KB)",
"failedToLoad": "Não foi possível carregar o editor de texto PDF.",
"loadingFonts": "Carregando fontes...",
"fontsUnavailable": "Não foi possível baixar uma fonte necessária para alguns caracteres. Verifique sua conexão e tente novamente; caso contrário, esses caracteres podem não aparecer corretamente no PDF salvo.",
"howToUpload": "Enviar PDF",
"howToClick": "Clique em um parágrafo",
"howToRestyle": "Reestilize tudo",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Sim! Ative a opção \"Repetir\" e as páginas de sobreposição se repetirão em todas as páginas base. Uma marca d'água de uma página será aplicada a cada página.",
"faqPrivacyQuestion": "Os meus ficheiros são privados e seguros?",
"faqPrivacyAnswer": "Com certeza! Todo o processamento acontece no seu navegador. Os seus ficheiros nunca saem do seu dispositivo, garantindo total privacidade."
},
"unlockPdf": {
"name": "Descriptografar PDF",
"subtitle": "Desbloqueie o PDF removendo a proteção por senha."
},
"protectPdf": {
"name": "Criptografar PDF",
"subtitle": "Bloqueie seu PDF adicionando uma senha."
}
}
+9 -6
View File
@@ -212,11 +212,11 @@
},
"browserBased": {
"question": "Почему обработка в браузере - это безопасно?",
"answer": "Работая целиком в браузере, BentoPDF гарантирует, что ваши файлы никогда не покидают ваше устройство. Это исключает риски взлома серверов, утечек данных или несанкционированного доступа. Ваши файлы остаются вашими — всегда."
"answer": "Работая целиком в браузере, BentoPDF гарантирует, что ваши файлы никогда не покидают ваше устройство. Это исключает риски взлома серверов, утечек данных или несанкционированного доступа. Ваши файлы остаются вашими, всегда."
},
"analytics": {
"question": "Вы используете cookies или аналитику для слежки за мной?",
"answer": "Нет. BentoPDF вас никак не отслеживает. Мы не используем файлы cookie, аналитику или трекинговые скрипты — даже на действующем сайте bentopdf.com. Мы никогда не знаем, кто вы и что вы делаете с инструментами."
"answer": "Нет. BentoPDF вас никак не отслеживает. Мы не используем файлы cookie, аналитику или трекинговые скрипты, даже на действующем сайте bentopdf.com. Мы никогда не знаем, кто вы и что вы делаете с инструментами."
}
},
"testimonials": {
@@ -239,7 +239,9 @@
"legal": "Правовая информация",
"termsAndConditions": "Условия предоставления услуг",
"privacyPolicy": "Политика приватности",
"followUs": "Подпишитесь"
"followUs": "Подпишитесь",
"privacyShort": "Конфиденциальность",
"termsShort": "Условия"
},
"merge": {
"title": "Объединить PDF",
@@ -286,13 +288,14 @@
"noCompromises": "Без компромиссов."
},
"mission": {
"title": "Наша миссия",
"title": "Наша",
"titleDim": "миссия",
"description": "Создать самый полный набор инструментов для работы с PDF, который соблюдает вашу приватность и не просит от вас денег. Мы верим, что основные инструменты для работы с документами должны быть доступны всем, везде, без ограничений."
},
"philosophy": {
"label": "Наша основная философия",
"title": "Приватность на первом месте. Всегда.",
"description": "В современном мире данные превратились в товар, но у нас иной подход. Вся обработка инструментами Bentopdf происходит локально, в вашем браузере. То есть ваши файлы никак не взаимодействуют с нашими серверами, мы не видим ваши документы и не отслеживаем ваши действия. Приватность ваших документов — полная и безоговорочная. Это не какая-то одна из наших фич, это — основа."
"description": "В современном мире данные превратились в товар, но у нас иной подход. Вся обработка инструментами BentoPDF происходит локально, в вашем браузере. То есть ваши файлы никак не взаимодействуют с нашими серверами, мы не видим ваши документы и не отслеживаем ваши действия. Приватность ваших документов полная и безоговорочная. Это не какая-то одна из наших фич, это основа."
},
"whyBentopdf": {
"title": "Почему",
@@ -321,7 +324,7 @@
},
"contact": {
"title": "Связаться с нами",
"subtitle": "Мы с радостью прочитаем ваши сообщения. Неважно, хотите ли вы задать вопрос, оставить обратную связь или попросить добавить новую функцию — не стесняйтесь, напишите нам!",
"subtitle": "Мы с радостью прочитаем ваши сообщения. Неважно, хотите ли вы задать вопрос, оставить обратную связь или попросить добавить новую функцию, не стесняйтесь, напишите нам!",
"email": "Вы можете написать нам на электронную почту:"
},
"licensing": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Нажать на любой абзац и отредактировать его на месте — с мгновенной перекомпоновкой текста, шрифтами и стилями.",
"saved": "PDF успешно сохранён! ({{size}} КБ)",
"failedToLoad": "Не удалось загрузить редактор текста PDF.",
"loadingFonts": "Загрузка шрифтов...",
"fontsUnavailable": "Не удалось загрузить шрифт, необходимый для некоторых символов. Проверьте подключение и повторите попытку, иначе эти символы могут отображаться неправильно в сохранённом PDF.",
"howToUpload": "Загрузить PDF",
"howToClick": "Нажмите на абзац",
"howToRestyle": "Измените стиль",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Да! Включите опцию \"Повтор\" и страницы наложения будут повторяться на всех страницах базового файла. Одностраничный водяной знак будет применён к каждой странице.",
"faqPrivacyQuestion": "Мои файлы конфиденциальны и защищены?",
"faqPrivacyAnswer": "Безусловно! Вся обработка происходит в вашем браузере. Ваши файлы никогда не покидают ваше устройство, обеспечивая полную конфиденциальность."
},
"unlockPdf": {
"name": "Расшифровка документа",
"subtitle": "Снять защиту документа, удалив пароль."
},
"protectPdf": {
"name": "Шифрование документа",
"subtitle": "Защитить документ с помощью пароля."
}
}
+5 -2
View File
@@ -239,7 +239,9 @@
"legal": "Právne informácie",
"termsAndConditions": "Obchodné podmienky",
"privacyPolicy": "Zásady ochrany osobných údajov",
"followUs": "Sledujte nás"
"followUs": "Sledujte nás",
"privacyShort": "Súkromie",
"termsShort": "Podmienky"
},
"merge": {
"title": "Zlúčiť PDF",
@@ -286,7 +288,8 @@
"noCompromises": "Bez kompromisov."
},
"mission": {
"title": "Naša misia",
"title": "Naša",
"titleDim": "misia",
"description": "Poskytnúť najkomplexnejšiu sadu PDF nástrojov, ktorá rešpektuje vaše súkromie a nikdy nepožaduje platbu. Veríme, že základné nástroje pre prácu s dokumentmi by mali byť dostupné pre každého, všade a bez bariér."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Kliknite na ľubovoľný odsek a upravte ho priamo na mieste s okamžitým preformátovaním textu, písmami a štýlmi.",
"saved": "PDF bolo úspešne uložené! ({{size}} KB)",
"failedToLoad": "Nepodarilo sa načítať textový editor PDF.",
"loadingFonts": "Načítavajú sa písma...",
"fontsUnavailable": "Písmo potrebné pre niektoré znaky sa nepodarilo stiahnuť. Skontrolujte pripojenie a skúste to znova, inak sa tieto znaky v uloženom PDF nemusia zobraziť správne.",
"howToUpload": "Nahrať PDF",
"howToClick": "Kliknite na odsek",
"howToRestyle": "Zmeňte štýl čohokoľvek",
@@ -1311,5 +1313,13 @@
"faqSinglePageAnswer": "Áno! Zapnite možnosť \"Opakovať\" a vaše PDF na prekrytie sa bude opakovať na všetkých stranách základu. Jednostranový vodoznak sa aplikuje na každú stranu.",
"faqPrivacyQuestion": "Sú moje súbory v súkromí a v bezpečí?",
"faqPrivacyAnswer": "Absolútne! Všetko spracovanie prebieha vo vašom prehliadači. Vaše súbory nikdy neopustia vaše zariadenie, čo zabezpečuje úplné súkromie."
},
"unlockPdf": {
"name": "Dešifrovať PDF",
"subtitle": "Odomknúť PDF odstránením ochrany heslom."
},
"protectPdf": {
"name": "Zašifrovať PDF",
"subtitle": "Uzamknúť vaše PDF pridaním hesla."
}
}
+7 -4
View File
@@ -216,7 +216,7 @@
},
"analytics": {
"question": "Använder ni cookies eller analys för att spåra mig?",
"answer": "Nej. BentoPDF spårar dig inte alls. Vi använder inga cookies, ingen analys och inga spårningsskript – inte ens på den publika webbplatsen bentopdf.com. Vi vet aldrig vem du är eller vad du gör med verktygen."
"answer": "Nej. BentoPDF spårar dig inte alls. Vi använder inga cookies, ingen analys och inga spårningsskript, inte ens på den publika webbplatsen bentopdf.com. Vi vet aldrig vem du är eller vad du gör med verktygen."
}
},
"testimonials": {
@@ -239,7 +239,9 @@
"legal": "Juridiskt",
"termsAndConditions": "Villkor",
"privacyPolicy": "Integritetspolicy",
"followUs": "Följ oss"
"followUs": "Följ oss",
"privacyShort": "Integritet",
"termsShort": "Villkor"
},
"merge": {
"title": "Sammanfoga PDF:er",
@@ -286,7 +288,8 @@
"noCompromises": "Inga kompromisser."
},
"mission": {
"title": "Vårt uppdrag",
"title": "Vårt",
"titleDim": "uppdrag",
"description": "Att tillhandahålla den mest omfattande PDF-verktygslådan som respekterar din integritet och aldrig ber om betalning. Vi tycker att viktiga dokumentverktyg ska vara tillgängliga för alla, överallt, utan hinder."
},
"philosophy": {
@@ -315,7 +318,7 @@
},
"cta": {
"title": "Redo att komma igång?",
"description": "Gå med i tusentals användare som litar på Bentopdf för sina dagliga dokumentbehov. Upplev skillnaden som integritet och prestanda kan göra.",
"description": "Gå med i tusentals användare som litar på BentoPDF för sina dagliga dokumentbehov. Upplev skillnaden som integritet och prestanda kan göra.",
"button": "Utforska alla verktyg"
}
},
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Klicka på valfritt stycke och redigera det på plats med direkt textomflöde, typsnitt och stilar.",
"saved": "PDF-filen sparades! ({{size}} KB)",
"failedToLoad": "Det gick inte att läsa in PDF-textredigeraren.",
"loadingFonts": "Läser in typsnitt...",
"fontsUnavailable": "Ett typsnitt som behövs för vissa tecken kunde inte laddas ned. Kontrollera anslutningen och försök igen, annars kanske tecknen inte visas korrekt i den sparade PDF-filen.",
"howToUpload": "Ladda upp PDF",
"howToClick": "Klicka på ett stycke",
"howToRestyle": "Ge allt ny stil",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Ja! Aktivera alternativet \"Upprepa\" och dina överläggsidor upprepas på alla bassidor. En ensidig vattenstämpel tillämpas på varje sida.",
"faqPrivacyQuestion": "Är mina filer privata och säkra?",
"faqPrivacyAnswer": "Absolut! All bearbetning sker i din webbläsare. Dina filer lämnar aldrig din enhet, vilket garanterar fullständig integritet."
},
"unlockPdf": {
"name": "Dekryptera PDF",
"subtitle": "Lås upp PDF genom att ta bort lösenordsskydd."
},
"protectPdf": {
"name": "Kryptera PDF",
"subtitle": "Lås din PDF genom att lägga till ett lösenord."
}
}
+6 -3
View File
@@ -222,7 +222,7 @@
"testimonials": {
"title": "Kullanıcılarımız",
"users": "Ne Diyor",
"say": ""
"say": " "
},
"support": {
"title": "Çalışmamı Beğendiniz mi?",
@@ -239,7 +239,9 @@
"legal": "Yasal",
"termsAndConditions": "Kullanım Koşulları",
"privacyPolicy": "Gizlilik Politikası",
"followUs": "Bizi Takip Edin"
"followUs": "Bizi Takip Edin",
"privacyShort": "Gizlilik",
"termsShort": "Koşullar"
},
"merge": {
"title": "PDF Birleştir",
@@ -287,12 +289,13 @@
},
"mission": {
"title": "Misyonumuz",
"titleDim": " ",
"description": "Gizliliğinize saygı duyan ve asla ödeme talep etmeyen en kapsamlı PDF araç setini sağlamak. Temel belge araçlarının her yerde, herkes için erişilebilir olması gerektiğine inanıyoruz."
},
"philosophy": {
"label": "Temel Felsefemiz",
"title": "Öncelik Her Zaman Gizlilik.",
"description": "Verinin bir meta olarak kabul edildiği bir çağda, farklı bir yaklaşım benimsiyoruz. Bentopdf araçları için tüm işlemler tarayıcınızda yerel olarak gerçekleşir. Bu, dosyalarınızın sunucularımıza asla dokunmadığı, belgelerinizi asla görmediğimiz ve ne yaptığınızı takip etmediğimiz anlamına gelir. Belgeleriniz tamamen ve kesinlikle özel kalır. Bu sadece bir özellik değil, temelimizdir."
"description": "Verinin bir meta olarak kabul edildiği bir çağda, farklı bir yaklaşım benimsiyoruz. BentoPDF araçları için tüm işlemler tarayıcınızda yerel olarak gerçekleşir. Bu, dosyalarınızın sunucularımıza asla dokunmadığı, belgelerinizi asla görmediğimiz ve ne yaptığınızı takip etmediğimiz anlamına gelir. Belgeleriniz tamamen ve kesinlikle özel kalır. Bu sadece bir özellik değil, temelimizdir."
},
"whyBentopdf": {
"title": "Neden",
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Herhangi bir paragrafa tıklayın ve canlı yeniden akış, yazı tipleri ve stillerle yerinde düzenleyin.",
"saved": "PDF başarıyla kaydedildi! ({{size}} KB)",
"failedToLoad": "PDF Metin Düzenleyici yüklenemedi.",
"loadingFonts": "Yazı tipleri yükleniyor...",
"fontsUnavailable": "Bazı karakterler için gereken bir yazı tipi indirilemedi. Bağlantınızı kontrol edip tekrar deneyin, aksi takdirde bu karakterler kaydedilen PDF'de doğru görünmeyebilir.",
"howToUpload": "PDF yükle",
"howToClick": "Bir paragrafa tıklayın",
"howToRestyle": "Her şeyi yeniden biçimlendirin",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Evet! \"Tekrarla\" seçeneğini etkinleştirin ve üst katman sayfalarınız tüm temel sayfalarda tekrarlanır. Tek sayfalık bir filigran her sayfaya uygulanır.",
"faqPrivacyQuestion": "Dosyalarım gizli ve güvende mi?",
"faqPrivacyAnswer": "Kesinlikle! Tüm işleme tarayıcınızda gerçekleşir. Dosyalarınız cihazınızı asla terk etmez, tam gizlilik sağlanır."
},
"unlockPdf": {
"name": "PDF'nin Şifresini Çöz",
"subtitle": "Şifre korumasını kaldırarak PDF'nin kilidini açın."
},
"protectPdf": {
"name": "PDF'yi Şifrele",
"subtitle": "PDF'nizi şifre ekleyerek koruyun."
}
}
+6 -3
View File
@@ -16,7 +16,7 @@
"button": "Підтримати"
},
"hero": {
"title": "",
"title": " ",
"pdfToolkit": "Набір PDF-інструментів",
"builtForPrivacy": "створений з урахуванням конфіденційності",
"noSignups": "Без реєстрації",
@@ -239,7 +239,9 @@
"legal": "Правова інформація",
"termsAndConditions": "Умови використання",
"privacyPolicy": "Політика конфіденційності",
"followUs": "Слідкуйте за нами"
"followUs": "Слідкуйте за нами",
"privacyShort": "Конфіденційність",
"termsShort": "Умови"
},
"merge": {
"title": "Об’єднання PDF",
@@ -286,7 +288,8 @@
"noCompromises": "Без компромісів."
},
"mission": {
"title": "Наша місія",
"title": "Наша",
"titleDim": "місія",
"description": "Надавати найповніший набір PDF-інструментів із повагою до приватності та без оплати. Ми віримо, що необхідні інструменти для роботи з документами мають бути доступні кожному."
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Натисніть на будь-який абзац і редагуйте його на місці з миттєвим перекомпонуванням тексту, шрифтами та стилями.",
"saved": "PDF успішно збережено! ({{size}} КБ)",
"failedToLoad": "Не вдалося завантажити редактор тексту PDF.",
"loadingFonts": "Завантаження шрифтів...",
"fontsUnavailable": "Не вдалося завантажити шрифт, потрібний для деяких символів. Перевірте з'єднання та спробуйте ще раз, інакше ці символи можуть відображатися неправильно у збереженому PDF.",
"howToUpload": "Завантажити PDF",
"howToClick": "Натисніть на абзац",
"howToRestyle": "Змініть стиль",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Так! Увімкніть опцію «Повторювати», і сторінки накладання будуть застосовані до всіх сторінок. Один водяний знак — на всі сторінки.",
"faqPrivacyQuestion": "Чи безпечні мої файли?",
"faqPrivacyAnswer": "Так! Уся обробка відбувається у вашому браузері. Файли не покидають ваш пристрій."
},
"unlockPdf": {
"name": "Розблокувати PDF",
"subtitle": "Видалити пароль і зняти захист PDF."
},
"protectPdf": {
"name": "Зашифрувати PDF",
"subtitle": "Захистити PDF паролем."
}
}
+8 -5
View File
@@ -212,7 +212,7 @@
},
"browserBased": {
"question": "Xử lý dựa trên trình duyệt giữ tôi an toàn như thế nào?",
"answer": "Bằng cách chạy hoàn toàn bên trong trình duyệt của bạn, BentoPDF đảm bảo rằng tệp của bạn không bao giờ rời khỏi thiết bị. Điều này loại bỏ các rủi ro về hack máy chủ, vi phạm dữ liệu hoặc truy cập trái phép. Tệp của bạn vẫn thuộc về bạn—luôn luôn."
"answer": "Bằng cách chạy hoàn toàn bên trong trình duyệt của bạn, BentoPDF đảm bảo rằng tệp của bạn không bao giờ rời khỏi thiết bị. Điều này loại bỏ các rủi ro về hack máy chủ, vi phạm dữ liệu hoặc truy cập trái phép. Tệp của bạn vẫn thuộc về bạn, luôn luôn."
},
"analytics": {
"question": "Bạn có sử dụng cookie hoặc phân tích để theo dõi tôi không?",
@@ -239,7 +239,9 @@
"legal": "Pháp lý",
"termsAndConditions": "Điều khoản và Điều kiện",
"privacyPolicy": "Chính sách Bảo mật",
"followUs": "Theo dõi chúng tôi"
"followUs": "Theo dõi chúng tôi",
"privacyShort": "Quyền riêng tư",
"termsShort": "Điều khoản"
},
"merge": {
"title": "Gộp PDF",
@@ -286,13 +288,14 @@
"noCompromises": "Không thỏa hiệp."
},
"mission": {
"title": "Sứ mệnh của chúng tôi",
"title": "Sứ mệnh",
"titleDim": "của chúng tôi",
"description": "Cung cấp bộ công cụ PDF toàn diện nhất tôn trọng quyền riêng tư của bạn và không bao giờ yêu cầu thanh toán. Chúng tôi tin rằng các công cụ tài liệu thiết yếu nên có thể truy cập được cho mọi người, ở mọi nơi, không có rào cản."
},
"philosophy": {
"label": "Triết lý cốt lõi của chúng tôi",
"title": "Quyền riêng tư trước tiên. Luôn luôn.",
"description": "Trong thời đại mà dữ liệu là hàng hóa, chúng tôi có cách tiếp cận khác. Tất cả quá trình xử lý cho các công cụ Bentopdf diễn ra cục bộ trong trình duyệt của bạn. Điều này có nghĩa là tệp của bạn không bao giờ chạm vào máy chủ của chúng tôi, chúng tôi không bao giờ thấy tài liệu của bạn và chúng tôi không theo dõi những gì bạn làm. Tài liệu của bạn vẫn hoàn toàn và rõ ràng là riêng tư. Đó không chỉ là một tính năng; đó là nền tảng của chúng tôi."
"description": "Trong thời đại mà dữ liệu là hàng hóa, chúng tôi có cách tiếp cận khác. Tất cả quá trình xử lý cho các công cụ BentoPDF diễn ra cục bộ trong trình duyệt của bạn. Điều này có nghĩa là tệp của bạn không bao giờ chạm vào máy chủ của chúng tôi, chúng tôi không bao giờ thấy tài liệu của bạn và chúng tôi không theo dõi những gì bạn làm. Tài liệu của bạn vẫn hoàn toàn và rõ ràng là riêng tư. Đó không chỉ là một tính năng; đó là nền tảng của chúng tôi."
},
"whyBentopdf": {
"title": "Tại sao chọn",
@@ -315,7 +318,7 @@
},
"cta": {
"title": "Sẵn sàng bắt đầu?",
"description": "Tham gia cùng hàng nghìn người dùng tin tưởng Bentopdf cho nhu cầu tài liệu hàng ngày của họ. Trải nghiệm sự khác biệt mà quyền riêng tư và hiệu suất có thể tạo ra.",
"description": "Tham gia cùng hàng nghìn người dùng tin tưởng BentoPDF cho nhu cầu tài liệu hàng ngày của họ. Trải nghiệm sự khác biệt mà quyền riêng tư và hiệu suất có thể tạo ra.",
"button": "Khám phá tất cả công cụ"
}
},
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "Nhấp vào bất kỳ đoạn văn nào và chỉnh sửa ngay tại chỗ với tính năng tự động dàn lại văn bản, phông chữ và kiểu dáng.",
"saved": "Đã lưu PDF thành công! ({{size}} KB)",
"failedToLoad": "Không thể tải Trình chỉnh sửa văn bản PDF.",
"loadingFonts": "Đang tải phông chữ...",
"fontsUnavailable": "Không thể tải xuống phông chữ cần cho một số ký tự. Hãy kiểm tra kết nối và thử lại, nếu không các ký tự đó có thể không hiển thị đúng trong tệp PDF đã lưu.",
"howToUpload": "Tải PDF lên",
"howToClick": "Nhấp vào một đoạn văn",
"howToRestyle": "Đổi kiểu mọi thứ",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "Có! Bật tùy chọn \"Lặp lại\" và các trang chồng sẽ lặp lại trên tất cả các trang gốc. Hình mờ một trang sẽ được áp dụng cho mọi trang.",
"faqPrivacyQuestion": "Tệp của tôi có được bảo mật không?",
"faqPrivacyAnswer": "Chắc chắn! Toàn bộ quá trình xử lý diễn ra trong trình duyệt của bạn. Tệp của bạn không bao giờ rời khỏi thiết bị, đảm bảo quyền riêng tư hoàn toàn."
},
"unlockPdf": {
"name": "Giải mã PDF",
"subtitle": "Mở khóa PDF bằng cách xóa bảo vệ mật khẩu."
},
"protectPdf": {
"name": "Mã hóa PDF",
"subtitle": "Khóa PDF của bạn bằng cách thêm mật khẩu."
}
}
+4 -1
View File
@@ -239,7 +239,9 @@
"legal": "法律聲明",
"termsAndConditions": "服務條款",
"privacyPolicy": "隱私權政策",
"followUs": "追蹤我們"
"followUs": "追蹤我們",
"privacyShort": "隱私",
"termsShort": "條款"
},
"merge": {
"title": "合併 PDF",
@@ -287,6 +289,7 @@
},
"mission": {
"title": "我們的使命",
"titleDim": " ",
"description": "在尊重您的隱私且完全不收費的同時,提供最全面的 PDF 工具箱。我們相信人人都應該能隨時隨地、不受限制地使用必備的文件工具。"
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "點擊任意段落即可就地編輯,支援即時重排、字型與樣式設定。",
"saved": "PDF 儲存成功!({{size}} KB)",
"failedToLoad": "無法載入 PDF 文字編輯器。",
"loadingFonts": "正在載入字型…",
"fontsUnavailable": "無法下載部分字元所需的字型。請檢查網路連線後再試一次,否則這些字元在儲存的 PDF 中可能無法正確顯示。",
"howToUpload": "上傳 PDF",
"howToClick": "點擊段落",
"howToRestyle": "隨意變更樣式",
@@ -1311,5 +1313,13 @@
"faqSinglePageAnswer": "可以!啟用重複使用功能後,疊加 PDF 的頁面會在所有基礎頁面上重複套用。單頁浮水印會套用至每一頁。",
"faqPrivacyQuestion": "我的檔案是否私密安全?",
"faqPrivacyAnswer": "當然!所有處理都在您的瀏覽器中進行。您的檔案永遠不會離開您的裝置,確保完全隱私。"
},
"unlockPdf": {
"name": "解密 PDF",
"subtitle": "透過移除密碼保護解鎖 PDF。"
},
"protectPdf": {
"name": "加密 PDF",
"subtitle": "透過新增密碼為您的 PDF 上鎖。"
}
}
+4 -1
View File
@@ -239,7 +239,9 @@
"legal": "法律",
"termsAndConditions": "服务条款",
"privacyPolicy": "隐私政策",
"followUs": "关注我们"
"followUs": "关注我们",
"privacyShort": "隐私",
"termsShort": "条款"
},
"merge": {
"title": "合并 PDF",
@@ -287,6 +289,7 @@
},
"mission": {
"title": "我们的使命",
"titleDim": " ",
"description": "提供最全面的 PDF 工具箱,尊重您的隐私,且永不收费。我们相信基本的文档工具应该对所有人、在任何地方都触手可及,没有任何障碍。"
},
"philosophy": {
+10
View File
@@ -60,6 +60,8 @@
"subtitle": "点击任意段落即可就地编辑,支持实时重排、字体和样式设置。",
"saved": "PDF 保存成功!({{size}} KB)",
"failedToLoad": "无法加载 PDF 文本编辑器。",
"loadingFonts": "正在加载字体...",
"fontsUnavailable": "无法下载部分字符所需的字体。请检查网络连接后重试,否则这些字符在保存的 PDF 中可能无法正确显示。",
"howToUpload": "上传 PDF",
"howToClick": "点击段落",
"howToRestyle": "随意restyle",
@@ -1312,5 +1314,13 @@
"faqSinglePageAnswer": "可以!启用\"循环\"选项,叠加页面将在所有基础页面上重复。单页水印将应用到每一页。",
"faqPrivacyQuestion": "我的文件是否私密安全?",
"faqPrivacyAnswer": "当然!所有处理都在您的浏览器中进行。您的文件永远不会离开您的设备,确保完全隐私。"
},
"unlockPdf": {
"name": "解密 PDF",
"subtitle": "通过移除密码保护解锁 PDF。"
},
"protectPdf": {
"name": "加密 PDF",
"subtitle": "通过添加密码锁定您的 PDF。"
}
}
File diff suppressed because one or more lines are too long
@@ -13514,9 +13514,9 @@ initCom(PDFViewerApplication);
return;
}
const fileOrigin = new URL(file, window.location.href).origin;
// if (fileOrigin !== viewerOrigin) {
// throw new Error("file origin does not match viewer's");
// }
if (fileOrigin !== viewerOrigin) {
throw new Error("file origin does not match viewer's");
}
} catch (ex) {
PDFViewerApplication._documentError("pdfjs-loading-error", {
message: ex.message
+1 -12
View File
@@ -10,8 +10,7 @@ Sitemap: https://www.bentopdf.com/sitemap.xml
# Disallow internal/system paths
Disallow: /api/
Disallow: /_next/
Disallow: /assets/
Allow: /src/pages/
Disallow: /src/
Disallow: /*.wasm$
Disallow: /*.wasm.gz$
@@ -23,13 +22,3 @@ Disallow: /tmp/
Disallow: /temp/
Disallow: /uploads/
# Disallow docs internal files (but allow /docs/ pages)
Disallow: /docs/assets/
# Google-specific
User-agent: Googlebot
Allow: /
# Bing-specific
User-agent: Bingbot
Allow: /
+1 -1
View File
@@ -4,7 +4,7 @@
"description": "Free online PDF tools - Privacy-first PDF toolkit that works 100% in your browser",
"start_url": "/",
"display": "standalone",
"background_color": "#262d3b",
"background_color": "#222222",
"theme_color": "#4f46e5",
"orientation": "portrait-primary",
"icons": [
+25 -25
View File
@@ -5,7 +5,7 @@
* Version: 1.1.0
*/
const CACHE_VERSION = 'bentopdf-v11';
const CACHE_VERSION = 'bentopdf-v13';
const CACHE_NAME = `${CACHE_VERSION}-static`;
const trustedCdnOrigins = new Set(['https://cdn.jsdelivr.net']);
@@ -109,7 +109,7 @@ self.addEventListener('fetch', (event) => {
isLocal &&
(url.pathname.endsWith('.html') ||
url.pathname === '/' ||
/^\/(en|fr|es|de|zh|zh-TW|vi|tr|id|it|pt|ru|nl|be)(\/|$)/.test(
/^\/(en|ar|be|da|de|es|fr|id|it|ja|ko|nl|pl|pt|ru|sk|sv|tr|uk|vi|zh|zh-TW)(\/|$)/.test(
url.pathname
))
) {
@@ -126,7 +126,7 @@ async function cacheFirstStrategyWithDedup(request, isCDN) {
const fileName = url.pathname.split('/').pop();
try {
const cachedResponse = await findCachedFile(fileName, request.url);
const cachedResponse = await findCachedFile(request.url);
if (cachedResponse) {
// console.log('⚡ [Cache HIT] Instant load:', fileName);
return cachedResponse;
@@ -136,7 +136,11 @@ async function cacheFirstStrategyWithDedup(request, isCDN) {
const networkResponse = await fetch(request);
if (networkResponse && networkResponse.status === 200) {
if (
networkResponse &&
networkResponse.status === 200 &&
!networkResponse.redirected
) {
const clone = networkResponse.clone();
const buffer = await clone.arrayBuffer();
if (buffer.byteLength > 0) {
@@ -163,8 +167,18 @@ async function cacheFirstStrategyWithDedup(request, isCDN) {
if (localPath) {
const localUrl = `${basePath}${localPath}${fileName}`;
try {
const cachedLocal = await findCachedFile(
new URL(localUrl, location.origin).href
);
if (cachedLocal) {
return cachedLocal;
}
const fallbackResponse = await fetch(localUrl);
if (fallbackResponse && fallbackResponse.status === 200) {
if (
fallbackResponse &&
fallbackResponse.status === 200 &&
!fallbackResponse.redirected
) {
const fbClone = fallbackResponse.clone();
const fbBuffer = await fbClone.arrayBuffer();
if (fbBuffer.byteLength > 0) {
@@ -192,7 +206,7 @@ async function cacheFirstStrategyWithDedup(request, isCDN) {
}
}
async function findCachedFile(fileName, requestUrl) {
async function findCachedFile(requestUrl) {
const cache = await caches.open(CACHE_NAME);
const exactMatch = await cache.match(requestUrl);
@@ -204,24 +218,6 @@ async function findCachedFile(fileName, requestUrl) {
}
await cache.delete(requestUrl);
}
const requests = await cache.keys();
for (const req of requests) {
const reqUrl = new URL(req.url);
const trustedOrigin =
reqUrl.origin === location.origin || trustedCdnOrigins.has(reqUrl.origin);
if (trustedOrigin && reqUrl.pathname.split('/').pop() === fileName) {
const response = await cache.match(req);
if (response) {
const clone = response.clone();
const buffer = await clone.arrayBuffer();
if (buffer.byteLength > 0) {
return response;
}
await cache.delete(req);
}
}
}
return null;
}
@@ -247,7 +243,11 @@ async function networkFirstStrategy(request) {
try {
const networkResponse = await fetch(request);
if (networkResponse && networkResponse.status === 200) {
if (
networkResponse &&
networkResponse.status === 200 &&
!networkResponse.redirected
) {
const clone = networkResponse.clone();
const buffer = await clone.arrayBuffer();
if (buffer.byteLength > 0) {

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