Compare commits

..
Author SHA1 Message Date
alam00000 f638f8e4db Release v2.8.11 2026-10-31 16:50:27 +05:30
Alam 24b060a134 Merge pull request #919 from kelseyjmw/fix-crop-scroll
Fix crop scroll
2026-10-31 16:38:58 +05:30
alam00000 6dca41aeb4 revert ICLA.md changes 2026-10-31 16:26:50 +05:30
alam00000 2a8ce12b6e add support for GFM inline math delimiters 2026-10-31 16:16:23 +05:30
Alam d03594a09d Merge pull request #964 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 3f6b6114b166
2026-10-31 16:03:14 +05:30
alam00000 d4e270a061 build(deps): bump PDF engine and viewer to 3f6b6114b166 2026-10-31 10:24:04 +00:00
Alam f0dd9b7153 Merge pull request #953 from alam00000/dependabot/npm_and_yarn/follow-redirects-1.16.2
build(deps): bump follow-redirects from 1.16.1 to 1.16.2
2026-10-31 15:26:30 +05:30
Alam af0d1caaf7 Merge pull request #950 from PeterDaveHello/zh-TW
Improve Traditional Chinese (zh-TW) translations
2026-10-31 15:26:14 +05:30
alam00000 d79f875ac3 Merge branch 'main' into zh-TW 2026-10-31 15:18:32 +05:30
Alam 3426da5c10 Merge pull request #961 from alam00000/ads-checkout
Ads checkout
2026-10-31 14:36:18 +05:30
alam00000 ba5821e43f feat(ads): update ad review timeline 2026-10-31 14:25:09 +05:30
alam00000 fac51527c8 feat(ads): collect ad details at Dodo checkout 2026-10-31 13:44:04 +05:30
Alam 8b80a616a7 Merge pull request #960 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 1b5d842415eb
2026-10-31 00:00:12 +05:30
alam00000 29d5a3d75e build(deps): bump PDF engine and viewer to 1b5d842415eb 2026-10-30 18:00:58 +00:00
alam00000 cbf7be541b docs(i18n): translate the new Multi Tool FAQ and docs 2026-10-30 19:34:50 +05:30
alam00000 6ac0599ce3 feat(multi-tool): replace the page grid with the pdfium organizer 2026-10-30 16:11:50 +05:30
alam00000 3ce02c9ef7 feat(editor): match the viewer theme to the site colors 2026-10-30 16:11:49 +05:30
alam00000 4e7bf6ec49 docs(docker): list the measurement feature IDs 2026-10-30 16:11:47 +05:30
Alam b0b670d58a Merge pull request #959 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 938c717a91e3
2026-10-30 16:11:06 +05:30
alam00000 b0e78f4435 build(deps): bump PDF engine and viewer to 938c717a91e3 2026-10-30 10:31:55 +00:00
alam00000 8c99f3ab5f - Added NVIDIA Inception branding.
- Updated the blogs
2026-10-28 14:48:33 +05:30
alam00000 27dfe79636 fix(tests): update WasmProvider tests to handle unversioned CDN URLs from older releases 2026-10-28 12:27:28 +05:30
alam00000 d8210be3c1 fix(docker): send ROBOTS_NOINDEX as a header, make COMPRESSION_MODE work and fix the Docker guide example 2026-10-27 18:07:29 +05:30
alam00000 1a6b38c077 fix(docs): clarify Hyper Licensing 2026-10-27 13:23:08 +05:30
alam00000 7abb219565 i18n: translate the drag to reorder label in all languages 2026-10-26 15:04:53 +05:30
dependabot[bot] 1e663cbe6c build(deps): bump follow-redirects from 1.16.1 to 1.16.2
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.16.1 to 1.16.2.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.16.1...v1.16.2)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-version: 1.16.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-26 09:32:01 +00:00
Alam efb8c4fe47 Merge pull request #951 from AB527/feature/drag-and-drop-arrangement-for-multiple-file-conversions
(Feature) Add drag-and-drop arrangement for multi-file to PDF conversions
2026-10-26 15:00:46 +05:30
alam00000 9c796a873c feat(markdown): add LaTeX math support 2026-10-26 15:00:18 +05:30
Atharva Bedekar 2f1178ddd0 refactor: use Phosphor icon for file list drag handle
Replace the Lucide grip-vertical icon with Phosphor's dots-six-vertical, in line with the project-wide move to Phosphor.
2026-10-25 22:24:06 +05:30
Atharva Bedekar 49ab2ef17f feat: drag-and-drop reordering for multi-file to PDF conversions
Tools that combine several files into a single PDF used the upload
order as the page order, with no way to change it short of clearing
and re-adding files. Each file row now has a drag handle, and the
new order is used when the PDF is built.

Applies to the JPG, PNG, WebP, BMP, HEIC, SVG, TIFF, Image and TXT
to PDF tools. The shared logic lives in utils/sortable-file-list.ts
(built on the existing sortablejs dependency) instead of being
duplicated per page.
2026-10-25 15:34:16 +05:30
alam00000 f7a8a60440 fix(xps): repair scanner XPS packages that MuPDF fails to parse 2026-10-25 13:19:57 +05:30
alam00000 4edb1718cc feat: translate all pages, UI messages and docs and fix SEO redirects and indexing 2026-10-25 12:55:21 +05:30
Alam 5e019de5ae Merge pull request #944 from CumpsD/fix/933-site-url-blog-canonicals
fix(seo): honour SITE_URL for blog canonicals (#933)
2026-10-24 12:19:37 +05:30
Peter Dave Hello 57b6fe8b15 Improve Taiwanese Chinese translations
Align zh-TW strings with the English sources and use natural Taiwanese
terminology throughout the website and PDF viewer locale resources.
Add missing merge-tool messages and clarify signing, annotations,
accessibility descriptions, and page controls.
2026-10-24 01:16:02 +08:00
David Cumps 4d3468c06f fix(seo): accept official blog canonicals under a custom SITE_URL (#933)
The blog is BentoPDF's own content, so generate-blog.mjs and the
hand-written blog pages keep their canonical on www.bentopdf.com in
self-hosted builds too. seo-audit.mjs now expects that official canonical
(and host) for blog/ pages instead of failing every custom-SITE_URL build.
2026-10-23 13:58:14 +00:00
David Cumps af92a591b9 Merge remote-tracking branch 'origin/main' into fix/933-site-url-blog-canonicals 2026-10-23 13:54:39 +00:00
David Cumps cd59d087d3 revert(seo): drop the dist/blog origin rebase
Per maintainer review: the blog is BentoPDF's own content, so self-hosted
builds keep its canonicals on www.bentopdf.com.
2026-10-23 13:54:39 +00:00
alam00000 dafb6f8e18 fix: update commercial license purchase link and invoicing details 2026-10-23 17:22:40 +05:30
alam00000 6f42d75b73 fix: update commercial license link in contributing guide 2026-10-23 17:22:33 +05:30
alam00000 6e8e012d3d fix: serve canonical, hreflang and sitemap URLs and restore Export in the PDF editor 2026-10-23 15:01:31 +05:30
alam00000 7eec9a0d64 feat: add favorites functionality to tools 2026-10-22 15:04:42 +05:30
alam00000 4d3e8b964f fix: fit wide tables when printing, keep editor panes from collapsing, rename Upload to Select in Markdown to PDF 2026-10-22 13:34:35 +05:30
Alam 5a5e155cc2 Merge pull request #813 from KourosZanbouri/add-farsi-translation
Add Farsi (Persian) translation
2026-10-22 12:51:02 +05:30
alam00000 5992cae40b Sync Farsi translation with main 2026-10-22 12:47:54 +05:30
alam00000 538e940525 Merge main into add-farsi-translation 2026-10-22 12:47:54 +05:30
Alam 853182d6a3 Merge pull request #916 from sergitost10/feat/catalan-translation
feat(i18n): add Catalan language support
2026-10-22 12:38:34 +05:30
David Cumps 2b56c45177 fix(seo): rebase only the exact default authority, insert SITE_URL literally
Review follow-up: the origin regex also matched a port
(https://www.bentopdf.com:8443) and userinfo
(https://[email protected]), which are different origins;
the lookahead now excludes ':' and '@'. The replacement is a callback,
so `$&`/`$1` in SITE_URL stay literal. Tests cover both.
2026-10-21 22:09:07 +00:00
David Cumps 3c605eef56 fix(seo): honour SITE_URL for blog canonicals (#933)
A build with a custom SITE_URL failed seo-audit on the blog pages:
generate-blog.mjs hard-coded https://www.bentopdf.com, and the
hand-written blog/author-alam.html carries that origin literally while
generate-i18n-pages.mjs only rewrites top-level pages.

generate-blog.mjs now reads SITE_URL like its sibling scripts, and
enhance-seo-pages.mjs rebases the default origin in dist/blog/*.html
to SITE_URL (dist only, no-op for the default URL) through a small
side-effect-free helper, scripts/site-origin.mjs, covered by
src/tests/site-origin.test.ts.
2026-10-21 19:02:45 +00:00
Alam 4a7dc7675b Merge pull request #913 from alam00000/dependabot/npm_and_yarn/i18next-http-backend-4.0.2
build(deps): bump i18next-http-backend from 3.0.6 to 4.0.2
2026-10-21 13:02:41 +05:30
Alam e9b34ec957 Merge pull request #911 from alam00000/dependabot/npm_and_yarn/brace-expansion-2.1.7
build(deps-dev): bump brace-expansion from 2.1.4 to 2.1.7
2026-10-21 13:01:56 +05:30
Alam c62187ee95 Merge pull request #910 from alam00000/dependabot/npm_and_yarn/dompurify-3.4.17
build(deps): bump dompurify from 3.4.12 to 3.4.17
2026-10-21 13:01:41 +05:30
Alam 594fa11677 Merge pull request #922 from alam00000/dependabot/npm_and_yarn/undici-7.30.1
build(deps-dev): bump undici from 7.29.0 to 7.30.1
2026-10-21 13:01:28 +05:30
Alam e26b5f6a28 Merge pull request #923 from alam00000/dependabot/npm_and_yarn/markdown-it-14.3.3
build(deps): bump markdown-it from 14.2.0 to 14.3.3
2026-10-21 13:01:12 +05:30
Alam 463750037c Merge pull request #939 from alam00000/dependabot/docker/library/node-26-alpine
build(deps): bump library/node from 20-alpine to 26-alpine
2026-10-21 13:00:53 +05:30
Alam fc43b112d8 Merge pull request #757 from ynlamy/main
(Feature) Add extraVolumes and extraVolumeMounts in chart Helm
2026-10-21 12:42:11 +05:30
Alam 33d15b9890 Merge pull request #886 from adrienboulle/fix-825-untranslated-notifications
fix(merge-pdf): route result notifications through i18n
2026-10-21 12:33:35 +05:30
Alam 8cfd91ccb3 Merge pull request #853 from nipunrajk/fix/navigation-base-url
fix(navigation): respect BASE_URL in tool pages and navbar brand (Fixes #850)
2026-10-21 12:28:21 +05:30
Alam 5222f6c0bf Merge pull request #902 from mvanhorn/fix/647-sign-pdf-flatten-text-position
fix: keep flattened Sign PDF text at its placed position
2026-10-21 12:24:30 +05:30
Alam 6314db7b88 Merge pull request #885 from adrienboulle/fix-831-validate-signature
fix(validate-signature): detect signature dictionaries without /Type
2026-10-21 12:18:10 +05:30
Alam 02113e2579 Merge pull request #894 from nipunrajk/fix/markdown-task-list-links
fix(markdown): prevent task lists with links from corrupting DOM
2026-10-21 12:00:48 +05:30
dependabot[bot] 7e2576e3df build(deps): bump library/node from 20-alpine to 26-alpine
Bumps library/node from 20-alpine to 26-alpine.

---
updated-dependencies:
- dependency-name: library/node
  dependency-version: 26-alpine
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-20 21:43:22 +00:00
dependabot[bot] c595c8f12a build(deps): bump i18next-http-backend from 3.0.6 to 4.0.2
Bumps [i18next-http-backend](https://github.com/i18next/i18next-http-backend) from 3.0.6 to 4.0.2.
- [Changelog](https://github.com/i18next/i18next-http-backend/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-http-backend/compare/v3.0.6...v4.0.2)

---
updated-dependencies:
- dependency-name: i18next-http-backend
  dependency-version: 4.0.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-20 16:39:18 +00:00
alam00000 0d430027df feat: replace compression with Hyper Compress, fix PDF to Word color pass and stale engine URLs 2026-10-20 22:06:30 +05:30
Alam d6537217e6 Merge pull request #934 from alam00000/chore/update-sponsors
docs: update sponsors
2026-10-19 18:17:09 +05:30
alam00000 2dd3dd2d4b docs: update sponsors 2026-10-19 12:46:23 +00:00
alam00000 2f96455896 chore: stop tracking generated build files, fix sponsors workflow and refresh README hero 2026-10-19 18:14:45 +05:30
Alam eb6813108a Merge pull request #925 from alam00000/dependabot/npm_and_yarn/qs-6.16.1
build(deps-dev): bump qs from 6.15.0 to 6.16.1
2026-10-19 17:33:55 +05:30
Adrien Boullé 448035b77b fix(merge-pdf): keep worker errors out of the alert, add missing fr key 2026-10-19 12:30:29 +02:00
Adrien Boullé ab8f4c20a8 fix(merge-pdf): route result notifications through i18n
Fixes #825
2026-10-19 12:30:29 +02:00
Adrien BoulléandClaude Opus 5.5 d86de593ca fix(validate-signature): detect signature dictionaries without /Type
/Type is optional in a signature dictionary (PDF 32000-1, 12.8.1) and some
signers leave it out, so those documents still reported "No Signatures
Found". A dictionary without /Type that carries both /ByteRange and
/Contents is now read as a signature; document timestamps
(/Type /DocTimeStamp, /SubFilter /ETSI.RFC3161) stay out because they hold
an RFC 3161 token, not a CMS signature over the document.

Also covers a /Contents placeholder of 74,506 hex characters, the largest
seen in real signed documents, which the former fixed scan window dropped.

Fixes #831

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 12:27:34 +02:00
alam00000 9aae81e73c Release v2.8.10 2026-10-19 15:33:11 +05:30
dependabot[bot] 007095a6a6 build(deps-dev): bump qs from 6.15.0 to 6.16.1
Bumps [qs](https://github.com/ljharb/qs) from 6.15.0 to 6.16.1.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.15.0...v6.16.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.16.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-19 09:57:52 +00:00
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
dependabot[bot] 4bd4ef9a7b build(deps): bump markdown-it from 14.2.0 to 14.3.3
Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 14.2.0 to 14.3.3.
- [Changelog](https://github.com/markdown-it/markdown-it/blob/14.3.3/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/markdown-it/compare/14.2.0...14.3.3)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-version: 14.3.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-17 12:11:07 +00:00
dependabot[bot] 12885ed914 build(deps-dev): bump undici from 7.29.0 to 7.30.1
Bumps [undici](https://github.com/nodejs/undici) from 7.29.0 to 7.30.1.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.29.0...v7.30.1)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 7.30.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-17 12:10:59 +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
Kelsey White a25c6511ce Signed ICLA.md 2026-10-16 13:19:17 -03:00
Kelsey White 6d8ef7d694 Fix for issue 903: Crop tool now moves page focus to top after use 2026-10-16 13:09:32 -03: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
sergitost10 5a6d6bc411 feat(i18n): add Catalan language support 2026-10-15 09:49:50 +02: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
dependabot[bot] 94351926ba build(deps-dev): bump brace-expansion from 2.1.4 to 2.1.7
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 2.1.4 to 2.1.7.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.1.4...v2.1.7)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.1.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-13 02:04:17 +00:00
dependabot[bot] b90d074820 build(deps): bump dompurify from 3.4.12 to 3.4.17
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to 3.4.17.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.17)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.17
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-13 00:58:34 +00:00
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
Matt Van Horn 4fd0b1d3e6 fix: keep flattened Sign PDF text at its placed position
readFormMatrix loads the appearance Matrix and uses the identity when
that entry is missing or is not six numbers. alignAppearanceToRect maps
the four BBox corners through that matrix and returns the scale and
translation that fit the transformed box to the annotation rectangle.
Those values are the cm concatenated before Do, and the original Matrix
stays on the form XObject so Do applies it once. A transformed box whose
width or height is under 0.001 is left unpainted, and that annotation is
still removed.

Fixes #647
2026-10-02 22:16:51 -07:00
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
nipunrajk 15c0435dde fix(markdown): prevent task lists with links from corrupting DOM
Disables label wrapping in markdown-it-task-lists plugin configuration.
When enabled, markdown-it-task-lists wraps task list content in <label>
tags, which malforms HTML structure when items contain links on the
same line and swallows subsequent DOM elements.

Fixes #715
2026-09-26 16:10:32 +05:30
nipunrajk daacdd2a2e test(navigation): constrain brand anchor regex to individual elements 2026-09-26 09:23:44 +05:30
nipunrajk 060d57639e test(navigation): tighten BASE_URL assertions per code review 2026-09-26 09:22:15 +05:30
nipunrajk 90fe106664 fix(navigation): respect BASE_URL in tool pages and navbar brand (Fixes #850) 2026-09-26 09:22:15 +05:30
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
Kouros Zanbouri 89bde584ec Sync Farsi translation with upstream and list it in the docs
Translate the 159 tools.json keys added upstream after this branch
was opened:

- editPdfText (114) - the PDF text editor
- duplexCollate (43) - the duplex collate tool
- mergePdf.removeDuplicateFonts
- pdfToTiff.alert.conversionOutOfMemory

fa/tools.json is now at full parity with en/tools.json (1039 keys).

Also register Farsi in the README language table and in the
TRANSLATION.md supported-language list and coverage table, matching
what the Korean and Slovak additions did.
2026-08-30 22:51:14 +01:00
Kouros Zanbouri a36e2d6ae6 Merge branch 'main' into add-farsi-translation 2026-08-30 22:50:46 +01:00
alam00000 f96cd4e516 Release v2.8.8 2026-08-29 14:47:41 +05:30
alam00000 a453313ff3 fix: update last updated date in privacy policy and terms and conditions 2026-08-29 12:44:53 +05:30
alam00000 9132dd42b5 fix: update privacy statements to clarify no tracking or analytics used 2026-08-28 19:07:12 +05:30
alam00000 f35224f16f fix: add cache parameter to Docker Downloads badge URL in README 2026-08-28 01:45:46 +05:30
alam00000 62041f4677 feat: add GitHub Actions workflow for updating Docker downloads badge and update README with new badge URL 2026-08-28 01:41:56 +05:30
alam00000 4f57cb076f fix: improve touch event handling for paragraph selection and editing for mobile devices 2026-08-26 18:23:56 +05:30
github-actions[bot] 627288ca13 @nipunrajk has signed the CLA in alam00000/bentopdf#845 2026-08-26 12:51:25 +00:00
Alam 480acfdf44 Merge pull request #844 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 8ff5002c6cd5
2026-08-25 16:46:58 +05:30
alam00000 7888fca6fa build(deps): bump PDF engine and viewer to 8ff5002c6cd5 2026-08-25 11:14:37 +00:00
Alam 921a5b4249 Merge pull request #843 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to f48637921bf4
2026-08-25 15:58:14 +05:30
alam00000 4bb43fda08 build(deps): bump PDF engine and viewer to f48637921bf4 2026-08-25 04:38:09 +00:00
alam00000 acdca59f18 add:trasnlations to duplex collate 2026-08-24 23:19:16 +05:30
Alam 829b13f8ff Merge pull request #752 from r0ckarong/duplex-pr-clean
(Feature) Add Duplex sort / collate documents (Fixes #220)
2026-08-24 22:46:36 +05:30
Alam 4339d21d41 Merge pull request #841 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to b9854c1098fc
2026-08-24 19:19:15 +05:30
alam00000 1d78b8ec72 build(deps): bump PDF engine and viewer to b9854c1098fc 2026-08-24 12:09:21 +00:00
alam00000 bf513bbcb9 fix: performance fixes and duplicate text bug 2026-08-24 16:45:30 +05:30
r0ckarong 7831571696 Add translation strings, remove local files 2026-08-24 08:57:32 +02:00
alam00000 c449a85745 fix: load the pdf.js worker with the Map upsert polyfill 2026-08-22 16:02:34 +05:30
Alam 8e606b652c Merge pull request #795 from mvanhorn/fix/662-map-upsert-polyfill
fix: polyfill Map.prototype.getOrInsertComputed to stop PDF.js render crash
2026-08-22 15:58:31 +05:30
Alam 3fa731aa6e Merge pull request #790 from PeterDaveHello/grammar-wording-branding-metadata-fixes
Correct grammar, wording, branding, and metadata inconsistencies
2026-08-22 14:34:31 +05:30
Alam 121c3d891a Merge branch 'main' into grammar-wording-branding-metadata-fixes 2026-08-22 14:32:56 +05:30
Alam 32db7cb173 Merge pull request #822 from alam00000/dependabot/npm_and_yarn/brace-expansion-2.1.4
build(deps-dev): bump brace-expansion from 2.1.2 to 2.1.4
2026-08-22 14:10:49 +05:30
Alam 1713fb0991 Merge pull request #821 from alam00000/dependabot/npm_and_yarn/mermaid-11.16.1
build(deps): bump mermaid from 11.16.0 to 11.16.1
2026-08-22 14:10:38 +05:30
Alam 47d6871bc5 Merge pull request #832 from alam00000/dependabot/npm_and_yarn/nanoid-3.3.18
build(deps): bump nanoid from 3.3.15 to 3.3.18
2026-08-22 14:10:20 +05:30
Alam be36588468 Merge pull request #823 from alam00000/dependabot/npm_and_yarn/postcss-8.5.26
build(deps): bump postcss from 8.5.16 to 8.5.26
2026-08-22 14:10:09 +05:30
Alam 532ba68f4f Merge pull request #824 from Stephan-P/patch-3
Update nl/tools.json
2026-08-22 14:03:50 +05:30
alam00000 5bcdd8deeb chore: add pdf text editor to popular tools 2026-08-22 14:00:44 +05:30
alam00000 7f6bebf21f feat: PDF text editor internationalization 2026-08-22 14:00:07 +05:30
Alam 0f65fdb2f4 Merge pull request #835 from OctoBored/fix/star-history-chart
Fix broken star history chart in README
2026-08-22 13:43:32 +05:30
Alam 09d1860396 Merge pull request #838 from alam00000/chore/update-pdf-engine
build(deps): bump PDF engine and viewer to 7ffa16f9c5cd
2026-08-21 16:13:13 +05:30
alam00000 5b4b40fe81 build(deps): bump PDF engine and viewer to 7ffa16f9c5cd 2026-08-21 10:39:10 +00:00
alam00000 6ac503efae fix: drop the static copy of the wasm the viewer no longer ships 2026-08-21 12:58:07 +05:30
alam00000 c72185ed0b ci: gate builds on the test suite and automate engine bumps
Runs typecheck and tests on every push and before publishing. A daily
job rebuilds both vendored tarballs from one commit of the engine fork,
verifies a single wasm ends up on disk, and opens a pull request.
2026-08-21 12:50:08 +05:30
alam00000 aee3e0a65a test: cover the text editor engine and FreeText flattening
Adds a node-side harness that drives the engine wasm directly, fixtures
that build PDFs in-memory, and cases for font fallback and flattening.
The engine loader now tolerates a runtime without import.meta.resolve so
the suite can load it outside a browser.
2026-08-21 12:50:07 +05:30
alam00000 5392c1be76 fix: text editor selection, styling, and script coverage
Clears the previous document before opening a new one, keeps the
selection when clicking the dock or rotating a box, refreshes the glass
overlay so style changes preview every time, adds double-click word
selection, and widens the Windows font stacks for Indic scripts. The
dock now publishes its own height so the swatches lay out correctly on
small screens.
2026-08-21 12:49:56 +05:30
alam00000 356128c60d feat: burn FreeText annotations into the page content stream
Exported annotations stayed as live FreeText objects, so viewers that
ignore appearance streams showed nothing and the text was not part of
the page. Flattening draws them into the content stream with an
embedded subset of the font, falling back to the old embed path for
anything the flattener cannot place.
2026-08-21 12:49:25 +05:30
alam00000 8dc7509ceb build: run the viewer and the text editor on one engine
Both vendored packages now come from a single build of the engine fork.
The viewer tarball ships without its own copy of pdfium.wasm and loads
the shared engine through EmbedPDF.init({ wasmUrl }), which drops it
from 7.1 MB to 2.1 MB and removes the second WebAssembly instance.
2026-08-21 12:49:03 +05:30
alam00000 cba16fe750 refactor: swap the lucide upload icon for phosphor 2026-08-21 12:48:48 +05:30
alam00000 a55614d5ab chore: ignore the sibling engine and pymupdf checkouts 2026-08-21 12:48:47 +05:30
alam00000 6b4e9f2a94 fix: trim whitespace from resource body 2026-08-18 20:54:41 +05:30
alam00000 75e76c9619 feat: add Edit PDF Text tool and related functionality 2026-08-18 20:04:25 +05:30
github-actions[bot] 6529b0e9b7 @OctoBored has signed the CLA in alam00000/bentopdf#835 2026-08-18 14:07:09 +00:00
alam00000 78cb827ec7 feat: update BentoPDF viewer to version 2.9.1 and add font embedding support 2026-08-17 13:42:56 +05:30
OctoBored dbcb9cc153 Fix broken star history chart in README
The star history chart in the README was broken due to GitHub stargazer API restrictions. Update the chart to use a working data source so it displays correctly again.
2026-08-17 06:28:34 +00:00
github-actions[bot] 1d2cd3f805 @mvanhorn has signed the CLA in alam00000/bentopdf#795 2026-08-16 22:01:46 +00:00
alam00000 053f22a87b chore: update .gitignore for helm chart 2026-08-16 13:46:36 +05:30
alam00000 e8f26c4a70 refactor: replace embedpdf-snippet with bentopdf-viewer 2026-08-16 13:10:16 +05:30
alam00000 9635c398d6 Add tiled watermark layout support with adjustable gaps and UI controls 2026-08-16 12:40:55 +05:30
alam00000 5bf54f1dad Implement decompression for GZIP files in LibreOfficeConverter initialization 2026-08-14 19:45:29 +05:30
alam00000 ee17fa8760 Add BASE_PATH handling to expectedCanonicalForFile function 2026-08-14 19:19:26 +05:30
alam00000 61fde80a90 Add dynamic brand name and local home URL generation for language support 2026-08-14 16:51:22 +05:30
alam00000 ca95925de9 Update JSON file caching to expire immediately 2026-08-14 15:20:43 +05:30
alam00000 706e74f084 Implement safe storage utility and update i18n handling to use it 2026-08-14 15:13:42 +05:30
alam00000 e1a4a31458 Add out of memory error handling for PDF to TIFF conversion 2026-08-14 14:56:23 +05:30
alam00000 866ecfed2d Add support for disabling GitHub star counter at build time 2026-08-14 14:41:44 +05:30
alam00000 10b63b5f89 Implement service worker precaching plugin and update asset handling 2026-08-14 14:32:27 +05:30
alam00000 af5b95e93c Add 'Remove duplicate fonts' option to PDF merge functionality 2026-08-14 13:41:06 +05:30
dependabot[bot] b8f3d4e582 build(deps): bump nanoid from 3.3.15 to 3.3.18
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.15 to 3.3.18.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/3.3.18/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.15...3.3.18)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-version: 3.3.18
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-08-12 02:03:07 +00:00
Stephan Paternotte 3672ecf91d Update nl/tools.json
Consistency: "successfullyl" = "met succes"
"succesvol" is an Angicism
2026-08-08 08:48:50 +02:00
dependabot[bot] 7c8c7600ae build(deps): bump postcss from 8.5.16 to 8.5.26
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.16 to 8.5.26.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.16...8.5.26)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.26
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-08-08 05:09:52 +00:00
dependabot[bot] 42b2615882 build(deps-dev): bump brace-expansion from 2.1.2 to 2.1.4
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 2.1.2 to 2.1.4.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.1.2...v2.1.4)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.1.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-08-08 05:09:35 +00:00
dependabot[bot] 02548b80b1 build(deps): bump mermaid from 11.16.0 to 11.16.1
Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 11.16.0 to 11.16.1.
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/[email protected]@11.16.1)

---
updated-dependencies:
- dependency-name: mermaid
  dependency-version: 11.16.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-08-08 05:09:20 +00:00
github-actions[bot] 2ed0575ca3 @florisporro has signed the CLA in alam00000/bentopdf#803 2026-08-07 12:29:42 +00:00
github-actions[bot] 54778a7e43 @junedkhatri31 has signed the CLA in alam00000/bentopdf#818 2026-08-07 11:50:18 +00:00
Kouros Zanbouri 612654e7d3 Fix BentoPDF casing in Farsi locale
Use canonical BentoPDF instead of Bentopdf in about.philosophy.description
and about.cta.description, per CodeRabbit review.
2026-07-31 13:17:06 +01:00
github-actions[bot] 59de529311 @KourosZanbouri has signed the CLA in alam00000/bentopdf#813 2026-07-31 12:08:24 +00:00
Kouros Zanbouri e5901f662f Add Farsi (Persian) translation
Add complete fa locale with 1146 translated keys (266 common, 880 tools).

Register 'fa' in supportedLanguages, languageNames, and SUPPORTED_LANGUAGES.
Also add 'fa' to the three hardcoded language regexes in i18n.ts
(getLanguageFromUrl, changeLanguage, rewriteLinks) — these are not mentioned
in TRANSLATION.md, but without them /fa/ silently falls back to English.
Persian is RTL, so extend the dir=rtl check from 'ar' to ['ar','fa'] in both
i18n.ts and generate-i18n-pages.mjs.
2026-07-31 12:51:54 +01:00
github-actions[bot] 5a4be8e7f2 @OBN3 has signed the CLA in alam00000/bentopdf#812 2026-07-30 15:14:01 +00:00
github-actions[bot] d9183028d5 @deployn has signed the CLA in alam00000/bentopdf#810 2026-07-29 10:06:03 +00:00
Alam fae0aa4c04 Merge pull request #805 from alam00000/dependabot/npm_and_yarn/dompurify-3.4.12
build(deps): bump dompurify from 3.4.11 to 3.4.12
2026-07-27 13:36:06 +05:30
alam00000 55915a2901 Release v2.8.7 2026-07-27 13:03:20 +05:30
dependabot[bot] f2a8b77733 build(deps): bump dompurify from 3.4.11 to 3.4.12
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.11 to 3.4.12.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.12
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-27 07:21:35 +00:00
Alam c8d04e51b9 Merge pull request #794 from alam00000/dependabot/npm_and_yarn/brace-expansion-2.1.2
build(deps-dev): bump brace-expansion from 2.0.3 to 2.1.2
2026-07-27 12:51:03 +05:30
Alam b003355a0c Merge pull request #801 from alam00000/dependabot/npm_and_yarn/undici-7.29.0
build(deps-dev): bump undici from 7.24.5 to 7.29.0
2026-07-27 12:50:45 +05:30
Alam 79ae42d73a Merge pull request #802 from alam00000/dependabot/npm_and_yarn/linkify-it-5.0.2
build(deps): bump linkify-it from 5.0.1 to 5.0.2
2026-07-27 12:50:28 +05:30
dependabot[bot] 2835e7e5f9 build(deps): bump linkify-it from 5.0.1 to 5.0.2
Bumps [linkify-it](https://github.com/markdown-it/linkify-it) from 5.0.1 to 5.0.2.
- [Changelog](https://github.com/markdown-it/linkify-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/linkify-it/compare/5.0.1...5.0.2)

---
updated-dependencies:
- dependency-name: linkify-it
  dependency-version: 5.0.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-24 18:35:18 +00:00
dependabot[bot] a59a1f41cd build(deps-dev): bump undici from 7.24.5 to 7.29.0
Bumps [undici](https://github.com/nodejs/undici) from 7.24.5 to 7.29.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.24.5...v7.29.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 7.29.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-24 12:58:58 +00:00
alam00000 0447cfc032 feat(port-validation): add validation for PORT variable to ensure it is a number and within the valid range 2026-07-23 18:24:46 +05:30
alam00000 7070bae927 feat(cache): enhance cache validation by checking trusted origins for cached files 2026-07-22 13:57:05 +05:30
alam00000 a3e64f6340 docs(cors-proxy): clarify DNS rebinding risks and egress filtering requirements for self-hosting 2026-07-22 12:56:36 +05:30
alam00000 45496fcd2e feat(security): add warnings for missing PROXY_SECRET and document DNS rebinding risks 2026-07-21 14:12:41 +05:30
Matt Van Horn 115bc70ad1 fix: polyfill Map.prototype.getOrInsertComputed to stop PDF.js render crash
Fixes #662
2026-07-21 00:42:50 -07:00
dependabot[bot] e59ce4feac build(deps-dev): bump brace-expansion from 2.0.3 to 2.1.2
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 2.0.3 to 2.1.2.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.0.3...v2.1.2)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.1.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-21 03:59:44 +00:00
Peter Dave Hello ea0a8755bf Correct grammar, wording, branding, and metadata inconsistencies
Standardize product and file-format names, remove duplicate SEO
keywords, align related-tool descriptions with their headings, and
restore incomplete phrases in search and social metadata.
2026-07-17 02:46:17 +08:00
Alam 21c924a3e6 Merge pull request #785 from PeterDaveHello/zh-TW
Update and improve zh-TW Traditional Chinese locale
2026-07-15 00:20:51 +05:30
alam00000 58cd1a8893 feat(security): enhance security policies and implement input validation across multiple files 2026-07-14 19:46:40 +05:30
Peter Dave Hello 57a6422e61 Update and improve zh-TW Traditional Chinese locale 2026-07-14 03:25:53 +08:00
github-actions[bot] 0ef279e0da @PeterDaveHello has signed the CLA in alam00000/bentopdf#785 2026-07-13 18:21:24 +00:00
alam00000 8dcd936873 fix(email): validate and escape unwrapped SafeLinks URLs before rendering 2026-07-13 10:07:58 +05:30
github-actions[bot] 5ef0b40dea @cevdetta has signed the CLA in alam00000/bentopdf#783 2026-07-10 13:13:04 +00:00
alam00000 6f02f2d2b7 chore: update dependencies and improve validation 2026-07-02 00:28:48 +05:30
alam00000 b21f602cca feat(timestamp): add TSA URL validation and sanitization methods 2026-07-01 23:23:37 +05:30
Alam b09fc21e66 Merge pull request #768 from alam00000/dependabot/npm_and_yarn/linkify-it-5.0.1
build(deps): bump linkify-it from 5.0.0 to 5.0.1
2026-06-30 11:35:35 +05:30
dependabot[bot] fa6355b98a build(deps): bump linkify-it from 5.0.0 to 5.0.1
Bumps [linkify-it](https://github.com/markdown-it/linkify-it) from 5.0.0 to 5.0.1.
- [Changelog](https://github.com/markdown-it/linkify-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/linkify-it/compare/5.0.0...5.0.1)

---
updated-dependencies:
- dependency-name: linkify-it
  dependency-version: 5.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-06-28 06:28:30 +00:00
alam00000 53bcf09566 Release v2.8.6 2026-06-28 11:55:59 +05:30
alam00000 d2dc459ba9 fix(split): extract pages with qpdf and decouple ZIP from output mode 2026-06-26 00:32:27 +05:30
alam00000 71ced499e7 fix(split): extract pages with qpdf and decouple ZIP from output mode 2026-06-26 00:32:27 +05:30
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
github-actions[bot] fc264f796a @nine-dev9 has signed the CLA in alam00000/bentopdf#761 2026-06-22 19:18:04 +00:00
nine-dev9 94c60f01c8 Add Polish translation 2026-06-22 20:46:53 +02:00
r0ckarongandCopilot ad5811efb0 Add JSDoc for duplex collate logic
Improve function-level documentation coverage for duplex collate page functions to satisfy documentation quality checks.

Co-authored-by: Copilot <[email protected]>
2026-06-18 10:02:14 +02:00
r0ckarongandcoderabbitai[bot] 1ada0cee13 Update docs/tools/duplex-collate.md
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-06-18 10:02:04 +02:00
r0ckarong d7c14f821a Fix handlebar template partials in page 2026-06-18 10:01:51 +02:00
r0ckarong 98371733a6 Add docs update for duplex sort 2026-06-18 10:01:42 +02:00
r0ckarong 6c53646e94 Add test for duplex sort 2026-06-18 10:01:32 +02:00
r0ckarong 4812d5b389 Feature: Add duplex sort / collate tool 2026-06-18 10:01:19 +02:00
ynlamy 45c941b664 (Feature) Add extraVolumes and extraVolumeMounts in chart Helm 2026-06-18 09:42:20 +02:00
github-actions[bot] e55c2ed405 @r0ckarong has signed the CLA in alam00000/bentopdf#752 2026-06-16 14:07:19 +00:00
github-actions[bot] 4b875a638c @upmcplanetracker has signed the CLA in alam00000/bentopdf#746 2026-06-09 14:25:52 +00:00
Alam b71d6c9b96 Merge pull request #730 from alam00000/dependabot/npm_and_yarn/vite-8.0.10
build(deps-dev): bump vite from 8.0.9 to 8.0.10
2026-06-04 23:46:56 +05:30
Alam d63d1683c7 Merge pull request #737 from marek-mraz/main
chore(i18n): add Slovak language
2026-06-04 23:45:38 +05:30
Alam 0347013df1 Merge pull request #739 from mondeep31/fix/issue-738
fix(md to pdf): restore mermaid flowchart node labels. Fixes #738
2026-06-04 23:43:57 +05:30
github-actions[bot] 412f2f1acb @mdevolde has signed the CLA in alam00000/bentopdf#740 2026-06-04 15:36:57 +00:00
github-actions[bot] a471bbcf4d @mondeep31 has signed the CLA in alam00000/bentopdf#739 2026-06-04 11:56:03 +00:00
Mondeep Chetry e1843e17b3 fix(md to pdf): restore mermaid flowchart node labels. Fixes #738 2026-06-04 17:18:51 +05:30
alam00000 ac3ad68b56 chore: remove FOSS demo section from README 2026-06-03 23:35:34 +05:30
marek-mraz 745698a5ba feat(i18n): add support for Arabic, Dutch, Danish, Swedish, and Japanese languages 2026-06-03 18:26:43 +02:00
github-actions[bot] dc1dbb036c @marek-mraz has signed the CLA in alam00000/bentopdf#736 2026-06-03 14:14:28 +00:00
marek-mraz 175c52bb1f chore(i18n): add Slovak language 2026-06-03 15:56:26 +02:00
alam00000 1d9b7c2a07 feat(multi-pdf): enhance PDF multi-tool functionality to allow drag n drop of PDF and images
fix(ocr): pin font CDN to rawcdn.githack.com with commit SHAs
2026-05-29 20:05:50 +05:30
alam00000 1534ce4d85 fix(ocr): change text layer color to black and set opacity to zero 2026-05-26 18:46:41 +05:30
alam00000 72e8c9f7b3 Release v2.8.5 2026-05-23 14:57:57 +05:30
dependabot[bot] 3cab1d37c7 build(deps-dev): bump vite from 8.0.9 to 8.0.10
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.9 to 8.0.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.10/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.10
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-23 07:33:47 +00:00
Alam 14e2c53030 Merge pull request #697 from alam00000/dependabot/npm_and_yarn/i18next-http-backend-3.0.6
build(deps): bump i18next-http-backend from 3.0.5 to 3.0.6
2026-05-23 13:02:09 +05:30
Alam 65335a2b88 Merge pull request #718 from Stephan-P/patch-2
Update tools.json
2026-05-23 13:01:38 +05:30
alam00000 0ce043c18e fix(ocr): Arabic+Latin font fix and added tests 2026-05-19 15:05:17 +05:30
alam00000 58a0053778 fix(nginx): tighten routing + add SEO redirects
fix(seo): canonical -> English for localized pages
docs: reframe Self-Hosted vs Commercial builds + Common Issues
2026-05-15 12:13:37 +05:30
Alam f24bf4ea98 Merge pull request #712 from alam00000/dependabot/npm_and_yarn/vite-8.0.9
build(deps-dev): bump vite from 8.0.8 to 8.0.9
2026-05-15 11:50:52 +05:30
Alam 1b76465b21 Merge pull request #713 from alam00000/dependabot/npm_and_yarn/mermaid-11.15.0
build(deps): bump mermaid from 11.13.0 to 11.15.0
2026-05-15 11:40:34 +05:30
Alam 741e4fa7bc Merge pull request #721 from alam00000/dependabot/npm_and_yarn/svelte-5.55.7
build(deps): bump svelte from 5.54.1 to 5.55.7
2026-05-15 11:08:35 +05:30
Alam 135027fb23 Merge pull request #720 from alam00000/dependabot/npm_and_yarn/devalue-5.8.1
build(deps): bump devalue from 5.6.4 to 5.8.1
2026-05-15 11:07:51 +05:30
dependabot[bot] 878c63d8ba build(deps): bump svelte from 5.54.1 to 5.55.7
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.54.1 to 5.55.7.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/[email protected]/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.55.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-14 21:46:10 +00:00
dependabot[bot] fb53fa0d7e build(deps): bump devalue from 5.6.4 to 5.8.1
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.4 to 5.8.1.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/devalue/compare/v5.6.4...v5.8.1)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-14 21:36:30 +00:00
Alam 661b66b765 Merge pull request #711 from alam00000/dependabot/npm_and_yarn/fast-xml-builder-1.2.0
build(deps): bump fast-xml-builder from 1.1.5 to 1.2.0
2026-05-15 01:33:53 +05:30
Stephan Paternotte 9215a5a943 Update tools.json
Peculiarly sloppy typo spotted and corrected.
I can't imagine me or any other human translator having made the same silly typo 4 times! 
Ergo; I am not at all happy with the fact that AI translation is now the default for BentoPDF
2026-05-14 08:17:06 +02:00
dependabot[bot] 6b119660b0 build(deps): bump mermaid from 11.13.0 to 11.15.0
Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 11.13.0 to 11.15.0.
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/[email protected]@11.15.0)

---
updated-dependencies:
- dependency-name: mermaid
  dependency-version: 11.15.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-11 22:46:45 +00:00
alam00000 c6ea2ca595 fix(build): rename .mjs assets to .js to avoid MIME errors on self-hosted setups 2026-05-09 16:28:17 +05:30
alam00000 7a6cd61286 feat(rotation): implement rotation utilities and enhance angle input handling 2026-05-09 14:21:07 +05:30
Alam bef12f1d23 Merge pull request #631 from quhxl/feature/improve-custom-rotate
Feature/improve custom rotate
2026-05-09 13:49:41 +05:30
Alam dd2ee5d5a1 Merge branch 'main' into feature/improve-custom-rotate 2026-05-09 13:44:38 +05:30
alam00000 3362b63350 fix(ui): adjust max-width for signature editor 2026-05-09 13:04:10 +05:30
dependabot[bot] 21bc0a50f0 build(deps-dev): bump vite from 8.0.8 to 8.0.9
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.8 to 8.0.9.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.9/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.9
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-08 19:52:09 +00:00
dependabot[bot] 947ae84da8 build(deps): bump fast-xml-builder from 1.1.5 to 1.2.0
Bumps [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) from 1.1.5 to 1.2.0.
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-builder/compare/v1.1.5...v1.2.0)

---
updated-dependencies:
- dependency-name: fast-xml-builder
  dependency-version: 1.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-08 19:51:49 +00:00
Alam f5d4bde317 Merge pull request #698 from alam00000/dependabot/npm_and_yarn/postcss-8.5.13
build(deps): bump postcss from 8.5.12 to 8.5.13
2026-05-09 00:02:21 +05:30
Alam 973c32e500 Merge pull request #705 from alam00000/dependabot/npm_and_yarn/vite-8.0.8
build(deps-dev): bump vite from 8.0.7 to 8.0.8
2026-05-09 00:02:11 +05:30
alam00000 f169308439 feat(tests): add unit tests for email parsing functionality and MsgReader interop fix 2026-05-08 22:09:46 +05:30
alam00000 8b6da83ba7 fix(workflow): fix heic images not being accepted in image to pdf 2026-05-08 21:56:51 +05:30
alam00000 fc941350b3 feat(i18n): fill missing translations across 19 locales after #658 + #664 2026-05-08 21:01:44 +05:30
Alam a45f7fb48e Merge pull request #664 from Skillkiller/translation
Localize status messages and UI elements across various tools
2026-05-08 19:44:24 +05:30
Alam 5f889bcc0a Merge pull request #658 from Skillkiller/translate-settings
Refactor modals into partials and add missing i18n keys for settings
2026-05-08 19:36:04 +05:30
Alam 3c668bddb1 Merge pull request #699 from Stephan-P/patch-2
Update common.json
2026-05-08 19:26:23 +05:30
Alam 4bde98f2e4 Merge branch 'main' into patch-2 2026-05-08 19:20:27 +05:30
dependabot[bot] 0957319e3d build(deps-dev): bump vite from 8.0.7 to 8.0.8
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.7 to 8.0.8.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.8/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.8
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-06 18:13:31 +00:00
Alam f41c51eb61 Merge pull request #696 from alam00000/dependabot/npm_and_yarn/vite-8.0.7
build(deps-dev): bump vite from 8.0.6 to 8.0.7
2026-05-06 23:42:06 +05:30
Alam 5e6af6c0d9 Merge pull request #700 from Stephan-P/patch-3
Update tools.json
2026-05-06 23:40:56 +05:30
Stephan Paternotte 249c8ccdfc Update tools.json 2026-05-03 14:19:36 +02:00
Stephan Paternotte e6c43d38ca Update common.json 2026-05-03 14:00:03 +02:00
Stephan Paternotte 0c53a4ace6 Update tools.json
Updates of (automated?) Dutch translations
2026-05-03 12:39:34 +02:00
Stephan Paternotte 815bd42229 Update common.json
Updated Ducth language
2026-05-03 12:29:44 +02:00
dependabot[bot] 4f66a6a41f build(deps): bump postcss from 8.5.12 to 8.5.13
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.12 to 8.5.13.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.12...8.5.13)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-03 09:07:00 +00:00
dependabot[bot] 7a248ba882 build(deps): bump i18next-http-backend from 3.0.5 to 3.0.6
Bumps [i18next-http-backend](https://github.com/i18next/i18next-http-backend) from 3.0.5 to 3.0.6.
- [Changelog](https://github.com/i18next/i18next-http-backend/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-http-backend/compare/v3.0.5...v3.0.6)

---
updated-dependencies:
- dependency-name: i18next-http-backend
  dependency-version: 3.0.6
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-03 09:06:54 +00:00
dependabot[bot] 078525171c build(deps-dev): bump vite from 8.0.6 to 8.0.7
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.6 to 8.0.7.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.7/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.7
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-05-03 09:06:42 +00:00
Alam bbffdad609 Merge pull request #692 from alam00000/dependabot/npm_and_yarn/postcss-8.5.12
build(deps): bump postcss from 8.5.8 to 8.5.12
2026-05-03 14:36:05 +05:30
Alam 9f11ffa325 Merge pull request #681 from alam00000/dependabot/npm_and_yarn/i18next-http-backend-3.0.5
build(deps): bump i18next-http-backend from 3.0.2 to 3.0.5
2026-05-03 14:35:40 +05:30
Alam 847ac79f05 Merge pull request #669 from alam00000/dependabot/npm_and_yarn/vite-8.0.6
build(deps-dev): bump vite from 8.0.5 to 8.0.6
2026-05-03 14:35:30 +05:30
alam00000 48c74de326 refactor(release): simplify Helm chart bump 2026-05-03 13:32:04 +05:30
alam00000 7e9e8f4afd fix(merge): page labels, retain-labels option, and workflow alignment with cpdf 2026-05-03 13:28:25 +05:30
alam00000 14557c123c fix(compare): Exported file always shows all types of changes 2026-05-03 12:57:02 +05:30
alam00000 668ea89a48 feat(release): update Helm chart version and appVersion in Chart.yaml and set it to auto update on subsequent releases 2026-05-03 12:14:51 +05:30
alam00000 ea53689bba fix: PDF Timestamp bug 2026-05-01 13:02:53 +05:30
alam00000 6f5c75b913 fix(airgap): pin Tesseract version in setup.sh tar to avoid glob collision with -core- tgz 2026-05-01 12:00:46 +05:30
alam00000 ef3dab5aeb feat(workflow): add altenate merge tool and translate workflow node and engine errors across locales 2026-04-30 13:16:48 +05:30
dependabot[bot] 1e9175b5e5 build(deps-dev): bump vite from 8.0.5 to 8.0.6
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.5 to 8.0.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-29 06:36:14 +00:00
dependabot[bot] 7f022ea35d build(deps): bump postcss from 8.5.8 to 8.5.12
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.8 to 8.5.12.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.8...8.5.12)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-29 06:36:00 +00:00
alam00000 0040317e48 feat(seo): canonicalize URLs, clean structured data, add audit gate
- Canonicals/hreflang/og point to www.bentopdf.com everywhere
- Drop fake aggregateRating; add Organization + breadcrumb JSON-LD
- Sitemap: filter 404/wasm-settings, mtime-based lastmod
- Rename locale ua → uk (correct ISO 639-1)
- Self-hoster: SITE_URL build arg, ROBOTS_NOINDEX runtime env
- Simple Mode indexable by default
- nginx: collapse .html and /index.html via 301
- SEO audit script + PR gate; runtime config noise fixed
- a11y contrast fix; language switcher gets search + scroll
- robots.txt: drop Crawl-delay
2026-04-29 12:04:34 +05:30
dependabot[bot] 0c19c0d9a3 build(deps): bump i18next-http-backend from 3.0.2 to 3.0.5
Bumps [i18next-http-backend](https://github.com/i18next/i18next-http-backend) from 3.0.2 to 3.0.5.
- [Changelog](https://github.com/i18next/i18next-http-backend/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-http-backend/compare/v3.0.2...v3.0.5)

---
updated-dependencies:
- dependency-name: i18next-http-backend
  dependency-version: 3.0.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-22 18:18:31 +00:00
alam00000 eff1548ebe Release v2.8.4 2026-04-21 19:34:58 +05:30
alam00000 18cdfac8cd fix(security): update script-src directive to include 'blob:' 2026-04-21 19:24:28 +05:30
alam00000 7587a5f94a feat(docs): add favicon SVG and update Nginx location directive for docs 2026-04-20 21:14:55 +05:30
alam00000 ac296cdb7f feat(security): add security headers documentation and update nginx configuration 2026-04-20 16:03:22 +05:30
alam00000 81e82918bf feat(security): enhance CSP directives and add documentation support 2026-04-20 15:31:50 +05:30
alam00000 e37d2d539e fix(security): add 'blob:' to connect-src directive in CSP 2026-04-20 12:42:11 +05:30
alam00000 54c6091e10 fix(security): remove 'upgrade-insecure-requests' directive from CSP 2026-04-19 14:30:53 +05:30
alam00000 b612548b78 fix(security): update Cross-Origin-Embedder-Policy to 'credentialless' 2026-04-19 12:21:08 +05:30
alam00000 28b4f3ebc4 Release v2.8.3 2026-04-18 21:21:52 +05:30
alam00000 7527187812 feat(Security): fixes 2026-04-18 16:58:55 +05:30
alam00000 b040aef729 chore(security): fixes 2026-04-18 15:21:59 +05:30
alam00000 121de29d80 feat(security): add CodeQL analysis workflow and ESLint security plugins 2026-04-18 14:46:51 +05:30
alam00000 df3567a61f fix(build): restore tsc compat after vitest bundler type drift 2026-04-18 13:53:02 +05:30
Alam af763d73c1 Merge pull request #643 from alam00000/dependabot/npm_and_yarn/vite-8.0.5
build(deps-dev): bump vite from 7.3.2 to 8.0.5
2026-04-18 12:52:19 +05:30
alam00000 b9f128f8c7 fix: update Content Security Policy 2026-04-18 00:29:33 +05:30
dependabot[bot] 478ccf3eda build(deps-dev): bump vite from 7.3.2 to 8.0.5
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.2 to 8.0.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-17 18:12:07 +00:00
alam00000 b4779bb49b feat: enhance sanitization 2026-04-17 23:40:39 +05:30
Sebastian Espei 4e1f8c5a24 fix: add localization for how it works section in bookmark tool 2026-04-17 15:52:53 +00:00
Sebastian Espei f4a583aa63 fix: refactor event listener initialization to wait for i18n for JSON to PDF conversion 2026-04-17 15:43:33 +00:00
Sebastian Espei 8c97768d74 fix: add localization for CSV and JSON format messages in bookmark tool 2026-04-17 15:40:50 +00:00
Sebastian Espei 9c3f652553 fix: replace hardcoded strings with localized messages for table of contents functionality 2026-04-17 15:39:13 +00:00
Sebastian Espei a3692db354 fix: initialize i18n on DOMContentLoaded 2026-04-17 15:35:37 +00:00
Sebastian Espei 33d7c6ba52 fix: remove unused i18n initialization import in table of contents logic 2026-04-17 15:30:50 +00:00
Sebastian Espei 4f9431b23e fix: remove dupplicate localization andupdate messages in multiple languages for upload certificate 2026-04-17 15:15:08 +00:00
Sebastian Espei 0b458ce8c8 fix: improve localization for JSON conversion messages in tools.json 2026-04-17 14:59:26 +00:00
Sebastian Espei 7f42080a38 fix: update localization for binarizeLabel in tools.json 2026-04-17 14:56:34 +00:00
Sebastian Espei a8b2b241d1 fix: update localization for addBookmark in table of contents 2026-04-17 14:56:28 +00:00
Sebastian Espei b9dacf5537 refactor(i18n): centralize unknownError and unify pdfToText note keys 2026-04-17 14:40:02 +00:00
Alam d92ee1a003 Merge pull request #666 from pavel-miniutka/main
Belarusian translation update
2026-04-17 18:21:57 +05:30
Alam 4663ae7834 Merge pull request #650 from tkymmm/main
Add Japanese translation
2026-04-17 18:21:14 +05:30
Alam 2311125d92 Merge branch 'main' into main 2026-04-17 18:21:03 +05:30
Alam 2807489f2b Merge pull request #628 from SerhiiZahuba/main
Added Ukrainian translation
2026-04-17 18:18:15 +05:30
Sebastian Espei 0ea7c69b25 fix: add missing localization to wasm settings 2026-04-17 11:39:50 +00:00
pavel-miniutka bb433b4afb more fixes 2026-04-17 14:32:18 +03:00
Sebastian Espei 84f13cdb93 fix: add missing localization to sign PDF tool 2026-04-17 11:21:05 +00:00
pavel-miniutka f4a01abffb Belarusian translation update 2026-04-17 14:20:46 +03:00
Sebastian Espei 9bc846249e fix: add missing localization to OCR PDF tool 2026-04-17 11:07:03 +00:00
Sebastian Espei cf8dd5ec2c fix: integrate localization for table of contents title 2026-04-17 10:56:22 +00:00
Sebastian Espei 2dd58cc894 feat(i18n): initialize i18n before showing status message 2026-04-16 21:54:31 +00:00
Sebastian Espei 5934430bfc feat(i18n): initialize i18n before showing status message 2026-04-16 21:51:50 +00:00
Sebastian Espei 2879557d6c feat(i18n): add RTL language detection note to localization files and update HTML 2026-04-16 21:32:24 +00:00
Alam c67e639dee Merge pull request #660 from alam00000/dependabot/npm_and_yarn/dompurify-3.4.0
build(deps): bump dompurify from 3.3.3 to 3.4.0
2026-04-17 02:57:18 +05:30
Sebastian Espei 7e61a543e7 feat(i18n): add auto-extract existing bookmarks localization for edit bookmarks 2026-04-16 19:58:49 +00:00
Sebastian Espei 9cec7fa459 feat(i18n): add unknown error messages to localization files and use it 2026-04-16 19:29:05 +00:00
alam00000 75dad6e75d fix: replace iframe PDF rendering with direct canvas in form creator 2026-04-16 22:40:00 +05:30
Sebastian Espei 0f9eb1bc0b fix(i18n): update label for table of contents title in German localization 2026-04-16 16:40:57 +00:00
Sebastian Espei 63707f0a18 feat(i18n): localize status messages and UI elements across various tools 2026-04-16 16:00:40 +00:00
dependabot[bot] 0ac37a87bc build(deps): bump dompurify from 3.3.3 to 3.4.0
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.3.3 to 3.4.0.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.3.3...3.4.0)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-16 03:43:04 +00:00
Sebastian Espei 5cc2ec3416 feat: add compact mode and advanced settings to localization 2026-04-14 19:52:42 +00:00
Sebastian Espei 412bfcd96b feat: update warning modal buttons for internationalization support 2026-04-14 19:41:47 +00:00
Sebastian Espei d408149720 feat: extract warning modal for use in simple and normal index page 2026-04-14 18:34:38 +00:00
Sebastian Espei f393962746 feat: extract settings modal for use in simple and normal index page 2026-04-14 18:26:20 +00:00
Sebastian Espei f4ab00e195 fix: add shortcuts modal from index.html 2026-04-14 18:17:45 +00:00
github-actions[bot] 651793bffa @tkymmm has signed the CLA in alam00000/bentopdf#650 2026-04-10 12:21:02 +00:00
tkymmm dc87af90ae Update tools.json 2026-04-10 18:13:08 +09:00
tkymmm e72df17c38 Add Japanese language support to Vite config 2026-04-10 17:33:54 +09:00
tkymmm 51fab1cbf8 Update i18n.ts 2026-04-10 17:33:09 +09:00
tkymmm 1b3df67c47 Add files via upload 2026-04-10 17:31:51 +09:00
github-actions[bot] 095d68df83 @SerhiiZahuba has signed the CLA in alam00000/bentopdf#628 2026-04-10 07:48:38 +00:00
Alam 5c956a5b15 Merge pull request #648 from ntfreak/static_pages
static.yml: fix static workflow regression from commit 1fc9620
2026-04-10 12:58:44 +05:30
github-actions[bot] d2e3dc1d89 @ntfreak has signed the CLA in alam00000/bentopdf#648 2026-04-08 21:13:23 +00:00
Spencer Oliver 934610522f static.yml: fix static workflow regression from commit 1fc96208
workflow deploy not running due to incorrect 'if' statement.
2026-04-08 22:02:18 +01:00
Spencer Oliver ad4cacd108 static.yml: normalise unix line endings
file contains mixed line endings - change to unix to match existing workflow files.
no code changes.
2026-04-08 21:56:20 +01:00
alam00000 a55a69487e fix: pdf rotation bug 2026-04-08 16:22:18 +05:30
Alam d17969a50d Merge pull request #642 from alam00000/dependabot/npm_and_yarn/vite-7.3.2
build(deps-dev): bump vite from 7.3.1 to 7.3.2
2026-04-07 13:13:28 +05:30
Alam ac20897e2a Merge pull request #641 from Stephan-P/patch-1
Update common.json - Dutch language
2026-04-07 13:13:05 +05:30
dependabot[bot] c745d55d32 build(deps-dev): bump vite from 7.3.1 to 7.3.2
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-06 22:12:25 +00:00
Stephan Paternotte 2ff4272133 Update common.json - Dutch language
Corrections of automated translations
2026-04-06 22:13:10 +02:00
alam00000 1ffe63f9ed feat: include simple mode distribution in GitHub release artifacts 2026-04-05 14:03:44 +05:30
alam00000 c80b5e24c6 Release v2.8.2 2026-04-05 13:50:09 +05:30
alam00000 a8c49e1cc4 fix: update lodash-es to version 4.18.1 in package.json and package-lock.json 2026-04-05 13:49:51 +05:30
alam00000 bfe4e5b663 feat: make Docker container port configurable via PORT env var
fix: preserve original filename when downloading processed files
2026-04-05 13:44:16 +05:30
alam00000 2f0d48c01b refactor: add simple mode to releases 2026-04-05 13:01:45 +05:30
Alam 816179edef Merge pull request #636 from alam00000/dependabot/npm_and_yarn/lodash-4.18.1
build(deps): bump lodash from 4.17.23 to 4.18.1
2026-04-04 13:35:45 +05:30
dependabot[bot] b1a9715c52 build(deps): bump lodash from 4.17.23 to 4.18.1
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.23...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-04-04 07:55:19 +00:00
Alam 23602bc8db Merge pull request #617 from Skillkiller/fix-version-inline
Embed static app version in HTML via Vite at build time
2026-04-04 13:24:07 +05:30
Alam 00aef19114 Merge pull request #625 from Stephan-P/patch-1
Update tools.json - Corrections to Dutch translation
2026-04-04 13:23:47 +05:30
alam00000 38c42fd197 fix: auto orientation in Fix Page Size now matches source page layout and add tests 2026-04-04 13:16:27 +05:30
alam00000 4efab56e48 fix: handle multi-channel TIFF formats and add compression options
Add PDF quality selector (high/medium/low) with JPEG compression.
2026-04-04 13:09:22 +05:30
alam00000 12677f1647 refactor: copy original pages in OCR instead of embedding rasterized PNGs 2026-04-04 12:51:55 +05:30
alam00000 ffddca2a7d fix: reverted nginx base image to use unprivileged version 2026-04-04 12:47:13 +05:30
Sebastian Espei 6920c999c8 Merge branch 'fix-version-inline' of github.com:Skillkiller/bentopdf into fix-version-inline 2026-04-03 18:34:14 +02:00
Sebastian Espei fa8bd1c525 refactor: remove version scripts from overlay html page 2026-04-03 18:33:59 +02:00
Sebastian Espei afa18931c6 Merge branch 'alam00000:main' into fix-version-inline 2026-04-03 18:24:39 +02:00
quhxl 0ed5e958b1 normalize angle inputs to 1 decimal and add finite-value validation 2026-04-03 15:39:46 +02:00
github-actions[bot] 5fb6b416f3 @quhxl has signed the CLA in alam00000/bentopdf#631 2026-04-03 13:34:27 +00:00
quhxl ec178bd6d9 feat: improve custom rotate UX with larger previews and float precision 2026-04-03 15:33:50 +02:00
Stephan Paternotte 5b2d764a10 Update tools.json - Dutch language updates
A few more updates to the Dutch translation
2026-04-03 10:23:08 +02:00
dedys e64595a42f Added Ukrainian translation 2026-04-03 10:21:58 +03:00
Sebastian Espei bd8ebfebcb Merge branch 'main' into fix-version-inline 2026-04-03 00:06:39 +02:00
alam00000 ed6e6c01be fix: resolve nginx permission errors when running as non-root user 2026-04-02 22:58:15 +05:30
Stephan Paternotte 635f031e2c Update tools.json - Corrections to Dutch translation of Overlay related additions 2026-04-01 18:34:12 +02:00
alam00000 d3d8eeb4ae Release v2.8.1 2026-04-01 19:39:49 +05:30
alam00000 e60dcc5ad6 fix: create nginx cache directory 2026-04-01 19:33:50 +05:30
alam00000 7d66f3d4e5 Release v2.8.0 2026-04-01 18:20:29 +05:30
alam00000 ecfa571215 feat: add PDF overlay and underlay functionality 2026-04-01 18:11:36 +05:30
alam00000 046a421591 fix: update nginx image version to 1.28.3-alpine-slim in Dockerfiles 2026-04-01 14:08:28 +05:30
Sebastian Espei 1cbb8e487b Merge branch 'main' into fix-version-inline 2026-03-31 20:51:18 +02:00
alam00000 bd654a8bb6 feat: add FOSS Hack 2026 demo link to README 2026-03-31 22:12:05 +05:30
alam00000 9d0b68e18c Refactor and enhance type safety across various modules
- Updated function parameters and return types in `page-preview.ts`, `pdf-decrypt.ts`, and `pymupdf-loader.ts` for improved type safety.
- Introduced type definitions for `CpdfInstance`, `PyMuPDFInstance`, and other related types to ensure better type checking.
- Enhanced error handling in `sanitize.ts` by creating a utility function for error messages.
- Removed unnecessary type assertions and improved type inference in `editor.ts`, `serialization.ts`, and `tools.test.ts`.
- Added type definitions for markdown-it plugins to improve compatibility and type safety.
- Enforced stricter TypeScript settings by enabling `noImplicitAny` in `tsconfig.json`.
- Cleaned up test files by refining type assertions and ensuring consistency in type usage.
2026-03-31 17:59:49 +05:30
alam00000 a1fc2fc3c6 fix: update nginx image version to stable-alpine-slim 2026-03-31 14:34:21 +05:30
alam00000 fefc433e0b fix: update nginx image version and add ignoreEncryption flag in pdf decrypt tests 2026-03-31 11:51:25 +05:30
alam00000 d1bac8675b fix: disable caching for Trivy vulnerability scanner in workflow 2026-03-31 00:56:04 +05:30
Alam 2d64ce330a Merge pull request #615 from Stephan-P/patch-1
Update common.json - Dutch language updated
2026-03-31 00:46:20 +05:30
alam00000 4a0a985ed6 bump flatted from 3.3.3 to 3.4.2 2026-03-31 00:44:49 +05:30
alam00000 54ed64d326 feat: update commercial license price to $79 2026-03-30 23:31:04 +05:30
Sebastian Espei 4eb4efffa2 fix: update git add command to only include package.json 2026-03-30 16:02:57 +02:00
Sebastian Espei 2e8cd3fafd refactor: remove old update-version process from release process 2026-03-30 15:29:17 +02:00
alam00000 c4f389055a feat: update node-forge to version 1.4.0 in package.json and package-lock.json 2026-03-30 11:31:28 +05:30
Sebastian Espei 882f135abc fix: remove unused APP_VERSION import 2026-03-30 02:04:39 +02:00
Sebastian Espei e22229475a refactor: remove version scripts from html pages 2026-03-30 01:56:06 +02:00
Sebastian Espei 7e7409de08 fix: remove unused APP_VERSION import from simple-mode-footer 2026-03-30 01:47:29 +02:00
Sebastian Espei 1d747ffcef fix: add version display internationalization support from footer.html 2026-03-30 01:38:55 +02:00
Sebastian Espei b19c68c284 feat: update footer embed app version during build 2026-03-30 01:36:34 +02:00
Sebastian Espei 3673099646 feat: add app version to handlebars configuration 2026-03-30 01:35:12 +02:00
Sebastian Espei 2bdacb7507 refactor: remove version update script and related version handling code 2026-03-30 01:34:54 +02:00
alam00000 a617279c2d feat: add support for disabling specific features in the PDF Editor 2026-03-29 23:02:58 +05:30
alam00000 245b48464b feat: add error handling for flattening PDF forms and annotations 2026-03-29 20:29:46 +05:30
Stephan Paternotte 6c1962587a Update common.json - Dutch language updated
two additional lines in Merge PDFs
2026-03-29 15:51:50 +02:00
Alam 84b70e5048 Merge pull request #613 from alam00000/dependabot/npm_and_yarn/brace-expansion-2.0.3
build(deps-dev): bump brace-expansion from 2.0.2 to 2.0.3
2026-03-29 00:51:51 +05:30
alam00000 ba179c4b57 feat: add documentation for disabling specific tools in self-hosting 2026-03-28 23:55:30 +05:30
alam00000 9a7cf1636b feat: add support for disabling specific tools in self-hosting
- Introduced build-time and runtime options to disable tools for compliance or security.
- Updated documentation to include instructions for disabling tools in Docker and Kubernetes setups.
- Added translations for disabled tool messages in multiple languages.
- Implemented logic to filter out disabled tools from the toolbox and shortcuts in the application.
- Created utility functions to manage disabled tools configuration.
2026-03-28 23:45:17 +05:30
dependabot[bot] cfea5e734a build(deps-dev): bump brace-expansion from 2.0.2 to 2.0.3
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.0.2...v2.0.3)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.0.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-28 15:47:55 +00:00
Alam 59ebb4d358 Merge pull request #604 from lukasstorck/main
fix: in bookmarks editor focus cancel- or ok-button for opened confirm and alert modals
2026-03-28 21:17:33 +05:30
Alam d133f72442 Merge pull request #609 from alam00000/dependabot/npm_and_yarn/picomatch-2.3.2
build(deps): bump picomatch from 2.3.1 to 2.3.2
2026-03-28 21:17:14 +05:30
Alam a55595e818 Merge pull request #612 from Stephan-P/patch-1
Update tools.json - Typos corrected in Dutch language
2026-03-28 21:17:02 +05:30
Alam 1435f77d89 Merge pull request #610 from alam00000/dependabot/npm_and_yarn/handlebars-4.7.9
build(deps-dev): bump handlebars from 4.7.8 to 4.7.9
2026-03-28 21:16:50 +05:30
Stephan Paternotte c789fd8afb Update tools.json - Typos corrected in Dutch language 2026-03-28 07:42:34 +01:00
alam00000 dd36fdde7a fix: ensure correct input type for SHA-256 hashing in tests 2026-03-27 13:47:08 +05:30
alam00000 86c8086979 refactor: replace PDFDocument.load with loadPdfDocument utility in TimestampNode 2026-03-27 13:27:58 +05:30
Alam a90f74c719 Merge pull request #576 from InstaZDLL/feat/timestamp-pdf
feat: add Timestamp PDF tool with RFC 3161 support
2026-03-27 11:03:57 +05:30
dependabot[bot] 2cc248c81b build(deps-dev): bump handlebars from 4.7.8 to 4.7.9
Bumps [handlebars](https://github.com/handlebars-lang/handlebars.js) from 4.7.8 to 4.7.9.
- [Release notes](https://github.com/handlebars-lang/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.9/release-notes.md)
- [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9)

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

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-27 03:27:05 +00:00
dependabot[bot] 0884de48cd build(deps): bump picomatch from 2.3.1 to 2.3.2
Bumps [picomatch](https://github.com/micromatch/picomatch) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/2.3.1...2.3.2)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-26 10:32:31 +00:00
alam00000 bd44108296 feat: add PDF password prompt and centralized pdf-lib loader with auto-repair 2026-03-26 14:42:48 +05:30
alam00000 9278774b8a - Refactor PDF loading across workflow nodes to use loadPdfDocument utility
- Replaced direct calls to PDFDocument.load with loadPdfDocument in multiple nodes to standardize PDF loading process.
2026-03-26 13:40:21 +05:30
alam00000 9d362b1cf8 feat: enable loading of encrypted PDFs by adding ignoreEncryption option 2026-03-26 12:55:50 +05:30
Alam 816dc311ae Merge pull request #606 from Stephan-P/patch-1
Update tools.json - Alerts added
2026-03-26 12:18:59 +05:30
alam00000 1dbf907eeb Add password prompt functionality and tests while uploading encrypted PDF 2026-03-26 12:11:12 +05:30
Stephan Paternotte 6a8d8cf268 Update tools.json
Typo's corrected.
AI check worked very well !
2026-03-25 11:27:46 +01:00
Stephan Paternotte f951cad66c Update tools.json - Alerts added
Added alerts translated incl. closing comma's for preceding lines
2026-03-25 11:19:26 +01:00
alam00000 f88f872162 feat: implement filename deduplication utility and integrate across multiple file conversion modules 2026-03-24 20:36:56 +05:30
Lukas 3f5298d1e7 fix: use HTMLElement type for previous active elment 2026-03-24 13:25:30 +01:00
Lukas a5c853891f fix: focus cancel or ok button on confirm and alert modals
when opening the modal:
- remember previously focused element
- set focused element to the ok or cancel button

when closing the modal:
- restore the focus to the previously focused element
2026-03-24 12:52:57 +01:00
alam00000 850eaffc92 Release v2.7.0 2026-03-24 15:02:08 +05:30
alam00000 6e227a3aa4 feat: add tests for comic info generation functions 2026-03-24 14:58:36 +05:30
alam00000 e3216dddc5 feat: add PDF to CBZ conversion tool with metadata support
- Updated main.ts to include 'PDF to CBZ' in the tools list.
- Added new types for CBZ options and comic metadata in pdf-to-cbz-type.ts.
- Implemented comic-info utility functions for generating ComicInfo.xml and metadata OPF files.
- Created pdf-to-cbz.html page with UI for PDF to CBZ conversion, including options for image format, quality, and metadata.
- Updated vite.config.ts to route to the new PDF to CBZ page.
2026-03-24 14:55:51 +05:30
alam00000 3ca19af354 feat: add TIFF conversion options and integrate wasm-vips for image processing
- Updated README.md to include new dependencies: wasm-vips, pixelmatch, diff, and microdiff.
- Added wasm-vips to package.json and package-lock.json for advanced TIFF encoding.
- Enhanced localization files with new options for DPI, compression, color mode, and multi-page TIFF saving.
- Implemented UI changes in pdf-to-tiff.html to allow users to select DPI, compression type, color mode, and multi-page options.
- Refactored pdf-to-tiff-page.ts to utilize wasm-vips for TIFF encoding, replacing previous UTIF implementation.
- Introduced TiffOptions interface in pdf-to-tiff-type.ts for better type management.
- Updated Vite configuration to exclude wasm-vips from dependency optimization.
2026-03-24 13:24:50 +05:30
Alam b732ee7925 Merge pull request #565 from Skillkiller/translate-pdf-to-image
Implement missing i18n translations for PDF-to-Image modules
2026-03-24 11:55:11 +05:30
Sebastian Espei 6d19c5f2e4 Revert formatting churn in signing pages 2026-03-24 01:56:53 +01:00
alam00000 0bf33ccd5b fix: update health check command to use wget and fix 404 page handling in nginx configuration 2026-03-23 19:01:37 +05:30
Alam a9e3128347 Merge pull request #521 from hagibr/update-shortcuts-modal
Fix missing translations in Settings/Shortcuts modal
2026-03-23 18:47:01 +05:30
Alam 49df18f07c Merge pull request #601 from lukasstorck/main
feat: add page up/down hotkeys for quick bookmark input
2026-03-23 18:30:10 +05:30
Alam 5d74e8c3ac Merge pull request #594 from Stephan-P/patch-1
Minor Dutch language corrections
2026-03-23 18:29:27 +05:30
alam00000 d2bb7a6727 fix: update clone URL for embed-pdf-viewer in workflow 2026-03-23 18:28:09 +05:30
alam00000 3a985f745a chore: remove scheduled trigger from update-embedpdf-snippet workflow 2026-03-23 02:20:13 +05:30
github-actions[bot] ac55a42cf3 @lukasstorck has signed the CLA in alam00000/bentopdf#601 2026-03-22 12:36:01 +00:00
Lukas 252ebf962d feat: add page up/down hotkeys for quick bookmark input 2026-03-22 13:05:48 +01:00
alam00000 013cc175a6 fix: regenerate package-lock.json 2026-03-22 00:06:20 +05:30
alam00000 5119fd08f9 fix: hash 2026-03-21 23:53:49 +05:30
alam00000 db3ffd3030 Update embedpdf-snippet to version 2.9.1
- Updated the embedpdf-snippet dependency in package.json from version 2.3.0 to 2.9.1.
- Updated the upstream version file to reflect the new version.
- Removed the old embedpdf-snippet-2.3.0.tgz file.
- Added the new embedpdf-snippet-2.9.1.tgz file.
2026-03-21 23:28:22 +05:30
alam00000 37b5956bd5 feat: add option to opt out of embedding full fonts in OCR settings 2026-03-21 16:39:51 +05:30
alam00000 b4a2c98497 Add documentation for all PDF tools 2026-03-20 21:48:48 +05:30
alam00000 1d986aedb1 feat: add permissions for contents and pull-requests in workflow 2026-03-20 20:43:38 +05:30
Stephan Paternotte 3d82955b81 Minor Dutch language corrections 2026-03-20 15:29:39 +01:00
alam00000 57b143cb9c Release v2.6.0 2026-03-18 13:39:45 +05:30
alam00000 59d07a1444 feat: add security context and volume mounts to deployment configuration 2026-03-17 23:15:12 +05:30
Alam 56801bd26e Merge pull request #586 from alam00000/dependabot/npm_and_yarn/jspdf-4.2.1
build(deps): bump jspdf from 4.2.0 to 4.2.1
2026-03-17 23:07:32 +05:30
dependabot[bot] 5e5975791f build(deps): bump jspdf from 4.2.0 to 4.2.1
Bumps [jspdf](https://github.com/parallax/jsPDF) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/parallax/jsPDF/releases)
- [Changelog](https://github.com/parallax/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/parallax/jsPDF/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: jspdf
  dependency-version: 4.2.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-17 17:30:24 +00:00
alam00000 01dc3005d7 fix: update Trivy action to latest version and improve SARIF upload step 2026-03-17 22:57:00 +05:30
alam00000 23b072ea10 feat: add Trivy security scan workflow and update Dockerfiles for vulnerability scanning 2026-03-17 22:54:00 +05:30
alam00000 8bf52b9ef1 feat: implement annotation flattening functionality and add tests 2026-03-17 22:46:13 +05:30
alam00000 6c0e9c7232 feat: enhance PDF comparison with overlay options and filters 2026-03-16 21:47:35 +05:30
alam00000 477839f106 feat: add "Add Page Labels" tool to the application
- Introduced a new tool for adding page labels to PDF documents, allowing users to apply Roman numerals, prefixes, and custom numbering ranges.
- Created a new HTML page for the tool with a user-friendly interface for file upload and label rule configuration.
- Implemented logic for handling file uploads, processing PDF files, and applying page labels based on user-defined rules.
- Added necessary types and utility functions for managing page label styles and normalization of start values.
- Updated main application configuration to include the new tool in the navigation.
- Added tests for page label utilities to ensure correct functionality.
2026-03-16 14:34:27 +05:30
InstalZDLL 0a718dac8f fix: address CodeRabbit review feedback on tests
- digital-sign-pdf.test.ts: stub VITE_CORS_PROXY_URL and
  VITE_CORS_PROXY_SECRET env vars for test isolation
- timestamp-node.test.ts: replace regex-only test with actual data()
  method tests covering timestampPdf call, output filename suffix,
  and error wrapping with TSA context
2026-03-15 15:58:43 +01:00
InstalZDLL 969b74dfb5 test: add timestampPdf signature tests with sample.pdf
Test the timestampPdf() function using the real sample.pdf (SHA256 verified).
PdfSigner is mocked to avoid network calls while validating:
- Correct signdate/TSA URL passed to PdfSigner
- PDF bytes forwarded to signer.sign()
- Uint8Array returned from signed result
- Error propagation from TSA failures
- Multiple TSA URL support
- Original PDF bytes not mutated
2026-03-15 15:44:55 +01:00
InstalZDLL 1569b66d5c test: add unit tests for timestamp PDF feature
Add 31 tests across 3 test files covering:
- TSA preset configuration (uniqueness, valid URLs, known providers)
- Timestamp PDF page logic (file validation, output naming, UI state, drop zone)
- TimestampNode workflow node (category, icon, description, presets)
2026-03-15 15:34:14 +01:00
alam00000 31f43b557f feat: add transparent background option for form fields 2026-03-15 19:52:48 +05:30
Alam dae6f1b15f Merge pull request #575 from luna-cant-code/translation-de
Started translating to German
2026-03-15 19:39:24 +05:30
Alam b107acb00c Merge pull request #555 from xtotdam/russian_translation
add Russian translation
2026-03-15 19:36:04 +05:30
alam00000 47c1be6df1 refactor pdf decrypt 2026-03-15 14:29:30 +05:30
Alam 11368314dd Merge pull request #570 from alam00000/dependabot/npm_and_yarn/devalue-5.6.4
build(deps): bump devalue from 5.6.3 to 5.6.4
2026-03-15 13:04:18 +05:30
InstalZDLL 70f0834fc0 fix: address CodeRabbit review feedback
- Handle Headers instance in TSA request detection (not just plain objects)
- Wrap timestampPdf with createCorsAwareFetch for OCSP/cert chain requests
- Pass 'success' type to showAlert on successful timestamp
- Add TSA URL context to timestamp error messages with cause
- Remove redundant Uint8Array wrapping in TimestampNode
2026-03-15 00:46:47 +01:00
InstalZDLL dfd0ebcfc5 feat: add Timestamp PDF tool with RFC 3161 support
Add document timestamping to the Secure PDF section using RFC 3161
protocol. Users can select from preset TSA servers (DigiCert, Sectigo,
SSL.com, Entrust, FreeTSA) or enter a custom TSA URL. No personal
certificate is required — only a cryptographic hash is sent to the server.

Key changes:
- Timestamp PDF page with TSA server selector, FAQ and SEO structured data
- timestampPdf() function with CORS proxy URL resolution
- TimestampNode for the workflow engine
- Tool entry in Secure PDF category + homepage i18n
- Built-in CORS proxy middleware for dev/preview
- Translations for all 16 languages

Tested with DigiCert, Sectigo and Entrust TSA servers. Timestamps are
verifiable in Adobe Acrobat (ETSI.RFC3161 SubFilter).
2026-03-15 00:30:53 +01:00
luna-cant-codeandcoderabbitai[bot] f39b54a8ca Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 17:29:05 +01:00
luna-cant-code 16bc667daf fixed typos 2026-03-14 17:12:17 +01:00
luna-cant-codeandcoderabbitai[bot] 3a9fc44355 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 17:04:03 +01:00
luna-cant-codeandcoderabbitai[bot] db38061ad9 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 17:03:50 +01:00
luna-cant-codeandcoderabbitai[bot] a95ce74b58 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 17:03:12 +01:00
Alam 2de36b6605 Merge pull request #574 from alam00000/dependabot/npm_and_yarn/undici-7.24.1
build(deps-dev): bump undici from 7.22.0 to 7.24.1
2026-03-14 20:18:44 +05:30
luna-cant-codeandcoderabbitai[bot] 3b45de70a6 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:01:30 +01:00
luna-cant-codeandcoderabbitai[bot] da9e7a8b11 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:01:18 +01:00
luna-cant-codeandcoderabbitai[bot] 6cb614fadb Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:01:01 +01:00
luna-cant-codeandcoderabbitai[bot] e4b6ae32ed Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:00:45 +01:00
luna-cant-codeandcoderabbitai[bot] 2403e13d26 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:00:32 +01:00
luna-cant-codeandcoderabbitai[bot] 3ecdcb13e8 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 15:00:03 +01:00
luna-cant-codeandcoderabbitai[bot] 88eac45452 Update public/locales/de/common.json
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-14 14:59:41 +01:00
luna-cant-code 3db95665e5 Merge branch 'main' into translation-de 2026-03-14 14:48:03 +01:00
github-actions[bot] 767028a654 @luna-cant-code has signed the CLA in alam00000/bentopdf#575 2026-03-14 13:47:29 +00:00
xtotdam cb4db2d762 fix rabbitai bot suggestions 2026-03-14 14:48:49 +03:00
xtotdam 03ecaf8603 add ru to nginx.conf and sw.js 2026-03-14 14:26:22 +03:00
alam00000 f2aabab68a fix: adjust formatting in documentation for clarity on self-hosting requirements 2026-03-14 16:06:29 +05:30
alam00000 77da6d7a7d feat: integrate Tesseract.js with improved language availability and font handling
- Refactored OCR page recognition to utilize a configured Tesseract worker.
- Added functions to manage font URLs and asset filenames based on language.
- Implemented language availability checks and error handling for unsupported languages.
- Enhanced PDF workflow to display available OCR languages and handle user selections.
- Introduced utility functions for resolving Tesseract asset configurations.
- Added tests for OCR functionality, font loading, and Tesseract runtime behavior.
- Updated global types to include environment variables for Tesseract and font configurations.
2026-03-14 15:50:30 +05:30
dependabot[bot] 000ef5bef9 build(deps-dev): bump undici from 7.22.0 to 7.24.1
Bumps [undici](https://github.com/nodejs/undici) from 7.22.0 to 7.24.1.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.22.0...v7.24.1)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 7.24.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-13 23:35:01 +00:00
alam00000 58c78b09d2 docs: update self-hosting documentation with secure context requirements for Office file conversion 2026-03-13 23:32:52 +05:30
alam00000 d7e06ce361 feat(i18n): enhance language detection from browser preferences and add tests 2026-03-13 19:20:37 +05:30
dependabot[bot] 9f09a01c08 build(deps): bump devalue from 5.6.3 to 5.6.4
Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.3 to 5.6.4.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/devalue/compare/v5.6.3...v5.6.4)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.6.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-12 15:30:17 +00:00
alam00000 e117ab93bd fix: form creator bug and added tests 2026-03-12 18:37:35 +05:30
Alam e55c2f6b6a Merge pull request #568 from YuF-9468/fix-567-checkbox-resize-cursors
fix(form-creator): checkbox/radio resize constraints + handle cursors
2026-03-12 14:30:15 +05:30
alam00000 e477689b1f fix: cla check bot 2026-03-12 14:17:47 +05:30
github-actions[bot] a6274a6a02 @YuF-9468 has signed the CLA in alam00000/bentopdf#568 2026-03-12 04:50:36 +00:00
YuF-9468 6b7eeea51a fix(form-creator): improve checkbox/radio resize constraints and cursors 2026-03-12 11:56:35 +08:00
alam00000 272a8cd038 fix: remove false highlights 2026-03-11 15:54:01 +05:30
alam00000 18b469a334 fix: add missing separator 2026-03-11 15:24:36 +05:30
Alam ff4e6672f1 Merge pull request #564 from Stephan-P/patch-2
Update tools.json - Dutch translation updated
2026-03-11 15:08:24 +05:30
Alam ea5db9d22d Merge pull request #563 from Stephan-P/patch-1
Update common.json - Dutch translation updated
2026-03-11 15:08:01 +05:30
Sebastian Espei 2ede256de2 Add localization for loading page count in various PDF processing pages 2026-03-10 20:13:13 +01:00
Sebastian Espei 571ce07af6 Add localization for PDF to BMP and PDF to TIFF conversion alerts and loader messages 2026-03-10 19:55:21 +01:00
Sebastian Espei 8d26378611 Add localization for PDF to WebP conversion alerts and loader messages 2026-03-10 19:52:38 +01:00
Stephan Paternotte b60c254c74 Update tools.json - Dutch translation updated
Latest additions translated + Full review of BentoPDF translation refined
2026-03-10 19:21:43 +01:00
Sebastian Espei 37d95e249d Add localization for PDF to PNG conversion alerts and loader messages 2026-03-10 19:18:39 +01:00
Sebastian Espei 01c4d3bd7c Add localization for PDF to JPG conversion alerts and loader messages 2026-03-10 19:17:17 +01:00
Stephan Paternotte 38596dc47c Update common.json - Dutch translation updated 2026-03-10 18:46:01 +01:00
Sebastian Espei d5244649a3 Update imports according to the translation guidelines 2026-03-10 18:40:47 +01:00
Sebastian Espei 4f86960265 Add localization for image scale 2026-03-10 18:38:09 +01:00
Sebastian Espei 67e3887165 Add localization for image quality 2026-03-10 18:35:17 +01:00
Sebastian Espei f1b03d076c Add localization for image quality 2026-03-10 18:31:27 +01:00
Sebastian Espei 667385ee1c Add localization to fileDisplayArea 2026-03-10 18:24:31 +01:00
Sebastian Espei b479abf6cf Add localization to "download" button 2026-03-10 17:49:03 +01:00
Sebastian Espei e21ee9605b Centralize convert local string into common
This reverts commit 3093dcbf4a.
2026-03-10 17:44:11 +01:00
Sebastian Espei 3093dcbf4a Add convert strings 2026-03-10 17:26:08 +01:00
alam00000 b6105408e0 Release v2.5.0 2026-03-10 13:51:23 +05:30
alam00000 5232102ac0 feat: enhance PDF comparison with new change types and zoom functionality
- Added support for 'moved' and 'style-changed' change types in PDF comparison.
- Implemented category filters for changes, allowing users to filter by text, images, headers, annotations, formatting, and background.
- Introduced zoom functionality with buttons for zooming in, out, and resetting to default.
- Updated UI to reflect new change types and categories, including visual indicators for moved and style-changed items.
- Enhanced summary display to include counts for moved and style-changed changes.
- Refactored rendering logic to accommodate zoom levels and improve performance.
- Added tests for new change detection features and category assignments.
2026-03-10 13:51:23 +05:30
github-actions[bot] 89d7cd8e3d @oleole39 has signed the CLA in alam00000/bentopdf#560 2026-03-10 00:20:26 +00:00
alam00000 d2a1450bc0 refactor: remove HTML report export and implement PDF export options in PDF comparison tool
- Deleted the exportCompareHtmlReport function and its related imports.
- Introduced a dropdown menu for exporting comparison results as PDFs with multiple modes (split, alternating, left, right).
- Updated the comparison logic to utilize caching for page models and comparison results.
- Refactored rendering functions to improve code organization and maintainability.
- Enhanced UI elements for better user experience during PDF export.
2026-03-09 23:27:40 +05:30
Alam 0fe94795cc Merge pull request #215 from Skillkiller/pdf-to-image-direct-image
Pdf to image direct image
2026-03-09 22:05:19 +05:30
Alam 30fe0b52f1 Merge pull request #531 from Olivetti/patch-1
minor correction in documentation
2026-03-09 21:38:52 +05:30
Sebastian Espei 92d5e40ac3 Add direct image download to pdf-to-bmp 2026-03-09 17:04:28 +01:00
Sebastian Espei 7c09768109 Add direct image download to pdf-to-tiff 2026-03-09 17:04:28 +01:00
Sebastian Espei 3748463d38 Add direct image download to pdf-to-webp 2026-03-09 17:04:28 +01:00
Sebastian Espei 65f99f0646 Add direct image download to pdf-to-png 2026-03-09 17:04:27 +01:00
Sebastian Espei 22ff7f435c Add direct image download to pdf-to-jpg 2026-03-09 17:04:27 +01:00
Sebastian Espei 1625ba0f45 Fix es-lint not not used error 2026-03-09 17:04:27 +01:00
Sebastian Espei 7d614a6ca7 Merge branch 'main' into pdf-to-image-direct-image 2026-03-09 17:02:37 +01:00
Sebastian Espei e474d11730 Reset branch to main 2026-03-09 17:02:30 +01:00
Alam 3d8a0866a9 Merge pull request #522 from alam00000/dependabot/npm_and_yarn/rollup-4.59.0
build(deps): bump rollup from 4.55.1 to 4.59.0
2026-03-09 19:58:36 +05:30
Alam f0c163f475 Merge pull request #550 from alam00000/dependabot/npm_and_yarn/minimatch-5.1.9
build(deps-dev): bump minimatch from 5.1.6 to 5.1.9
2026-03-09 19:58:17 +05:30
Alam 4df7d797c4 Merge pull request #551 from alam00000/dependabot/npm_and_yarn/dompurify-3.3.2
build(deps): bump dompurify from 3.3.1 to 3.3.2
2026-03-09 19:57:59 +05:30
alam00000 f57ea089e9 fix: rotation functionality for PDF page and add corresponding tests 2026-03-09 19:56:50 +05:30
dependabot[bot] 45df666152 build(deps): bump rollup from 4.55.1 to 4.59.0
Bumps [rollup](https://github.com/rollup/rollup) from 4.55.1 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.55.1...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-08 18:26:58 +00:00
alam00000 1d68691331 refactor: update PDF comparison types and enhance UI for better usability
- Refactored CompareState to import from a centralized type definition.
- Enhanced the compare-pdfs.html layout with improved styles for overlay and side-by-side modes.
- Added new CSS styles for various UI components including panels, buttons, and highlights.
- Implemented a new sidebar for displaying change summaries and filters.
- Created unit tests for text comparison logic, including diffing text runs and page pairing.
- Added tests for text normalization functions to ensure proper handling of punctuation and character normalization.
2026-03-08 23:55:33 +05:30
github-actions[bot] 86cbaf6cd3 @xtotdam has signed the CLA in alam00000/bentopdf#555 2026-03-08 13:05:26 +00:00
xtotdam 73795dbe13 add Russian translation 2026-03-08 15:51:11 +03:00
Alam 255d8402c2 Merge pull request #553 from iegl3/fix/docs-and-footer-consistency
fix correct locale path in translation guide, add missing link attributes in footer, fix wasm version in readme
2026-03-08 14:15:12 +05:30
Alam ded9809e4c Merge pull request #552 from the0807/add-korean-translation
add Korean (ko) translation
2026-03-08 14:12:30 +05:30
github-actions[bot] 5028e31e8a @iegl3 has signed the CLA in alam00000/bentopdf#553 2026-03-08 00:25:40 +00:00
iegl3 0cf546ab51 fix: correct locale path in translation guide, add missing link attributes in footer, fix wasm version in readme
- TRANSLATION.md: Spanish example incorrectly referenced fr/ locale path instead of es/

- footer.html: Instagram and LinkedIn links were missing target=_blank and rel=noopener noreferrer, unlike the other social links

- README.md: air-gapped manual steps referenced [email protected] but the current default is 0.11.16
2026-03-08 07:16:47 +07:00
github-actions[bot] ec96caf1a4 @the0807 has signed the CLA in alam00000/bentopdf#552 2026-03-07 15:47:34 +00:00
the0807 1401b9ee15 add Korean (ko) translation 2026-03-08 00:35:28 +09:00
dependabot[bot] 0ebfaa48a3 build(deps): bump dompurify from 3.3.1 to 3.3.2
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-07 09:10:23 +00:00
dependabot[bot] ad131db536 build(deps-dev): bump minimatch from 5.1.6 to 5.1.9
Bumps [minimatch](https://github.com/isaacs/minimatch) from 5.1.6 to 5.1.9.
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v5.1.6...v5.1.9)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 5.1.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-07 09:10:16 +00:00
alam00000 0d9ffe2997 Release v2.4.1 2026-03-07 14:38:08 +05:30
alam00000 d32251014e feat: integrate fix page size functionality into the workflow by extracting core logic to a utility and adding a new workflow node. 2026-03-07 14:33:33 +05:30
alam00000 c2147a2f20 Refactor page titles and subtitles for consistency and clarity across various PDF conversion tools 2026-03-04 13:46:16 +05:30
alam00000 90998edb25 Add tests for image effects, PDF operations, rotation state, and XML to PDF utilities 2026-03-04 13:33:00 +05:30
alam00000 84848ab902 feat: add Quick Look page preview and unify thumbnail styles across all tools 2026-03-04 00:38:07 +05:30
alam00000 2aaea50031 feat: fix bug for remove blank pages tool. added i18n translations 2026-03-03 23:35:15 +05:30
Alam 5fbf48601e Merge pull request #535 from Stephan-P/patch-1
Update tools.json - Option Apply watermark to all pages
2026-03-02 21:38:45 +05:30
github-actions[bot] 4cec7bbe58 @InstaZDLL has signed the CLA in alam00000/bentopdf#538 2026-03-02 14:33:23 +00:00
github-actions[bot] e505c70b2f @Olivetti has signed the CLA in alam00000/bentopdf#531 2026-03-02 13:46:13 +00:00
Stephan Paternotte 841428f2e2 Update tools.json - Option Apply watermark to all pages
Option Apply watermark to all pages TRANSLATED
2026-03-02 07:03:06 +01:00
alam00000 957b78fafd fix: revert cropperjs dependency to version 1.6.2 and adjust Docker build commands for CORS proxy secrets 2026-03-01 21:29:13 +05:30
Alam 34f12655c1 Merge pull request #534 from alam00000/dependabot/npm_and_yarn/npm-dependencies-b1e467bd1f
build(deps): bump the npm-dependencies group across 1 directory with 29 updates
2026-03-01 19:59:30 +05:30
Alam 74d7af283e Merge pull request #533 from alam00000/dependabot/npm_and_yarn/svelte-5.53.6
build(deps): bump svelte from 5.53.1 to 5.53.6
2026-03-01 19:57:44 +05:30
dependabot[bot] 5ef73edea2 build(deps): bump the npm-dependencies group across 1 directory with 29 updates
Bumps the npm-dependencies group with 28 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@kenjiuno/msgreader](https://github.com/HiraokaHyperTools/msgreader) | `1.27.1-alpha.1` | `1.28.0` |
| [@matbee/libreoffice-converter](https://github.com/matbeedotcom/libreoffice-document-converter) | `2.3.1` | `2.5.0` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.1.18` | `4.2.1` |
| [cropperjs](https://github.com/fengyuanchen/cropperjs/tree/HEAD/packages/cropperjs) | `1.6.2` | `2.1.0` |
| [i18next](https://github.com/i18next/i18next) | `25.7.3` | `25.8.13` |
| [i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector) | `8.2.0` | `8.2.1` |
| [lucide](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide) | `0.546.0` | `0.575.0` |
| [mermaid](https://github.com/mermaid-js/mermaid) | `11.12.2` | `11.12.3` |
| [pdfjs-dist](https://github.com/mozilla/pdf.js) | `5.4.530` | `5.4.624` |
| [postal-mime](https://github.com/postalsys/postal-mime) | `2.7.1` | `2.7.3` |
| [sortablejs](https://github.com/SortableJS/Sortable) | `1.15.6` | `1.15.7` |
| [terser](https://github.com/terser/terser) | `5.44.1` | `5.46.0` |
| [tesseract.js](https://github.com/naptha/tesseract.js) | `6.0.1` | `7.0.0` |
| [vite-plugin-static-copy](https://github.com/sapphi-red/vite-plugin-static-copy) | `3.1.4` | `3.2.0` |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.39.2` | `10.0.1` |
| [@types/pdfkit](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/pdfkit) | `0.17.4` | `0.17.5` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `3.2.4` | `4.0.18` |
| [@vitest/ui](https://github.com/vitest-dev/vitest/tree/HEAD/packages/ui) | `3.2.4` | `4.0.18` |
| [eslint](https://github.com/eslint/eslint) | `9.39.2` | `10.0.2` |
| [globals](https://github.com/sindresorhus/globals) | `17.0.0` | `17.4.0` |
| [jsdom](https://github.com/jsdom/jsdom) | `27.4.0` | `28.1.0` |
| [lint-staged](https://github.com/lint-staged/lint-staged) | `16.2.7` | `16.3.1` |
| [prettier](https://github.com/prettier/prettier) | `3.7.4` | `3.8.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.51.0` | `8.56.1` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `7.3.0` | `7.3.1` |
| [vite-plugin-node-polyfills](https://github.com/davidmyersdev/vite-plugin-node-polyfills) | `0.24.0` | `0.25.0` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `3.2.4` | `4.0.18` |
| [vue](https://github.com/vuejs/core) | `3.5.26` | `3.5.29` |



Updates `@kenjiuno/msgreader` from 1.27.1-alpha.1 to 1.28.0
- [Commits](https://github.com/HiraokaHyperTools/msgreader/commits)

Updates `@matbee/libreoffice-converter` from 2.3.1 to 2.5.0
- [Release notes](https://github.com/matbeedotcom/libreoffice-document-converter/releases)
- [Changelog](https://github.com/matbeedotcom/libreoffice-document-converter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/matbeedotcom/libreoffice-document-converter/compare/v2.3.1...v2.5.0)

Updates `@tailwindcss/vite` from 4.1.18 to 4.2.1
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/@tailwindcss-vite)

Updates `cropperjs` from 1.6.2 to 2.1.0
- [Release notes](https://github.com/fengyuanchen/cropperjs/releases)
- [Changelog](https://github.com/fengyuanchen/cropperjs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fengyuanchen/cropperjs/commits/v2.1.0/packages/cropperjs)

Updates `i18next` from 25.7.3 to 25.8.13
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v25.7.3...v25.8.13)

Updates `i18next-browser-languagedetector` from 8.2.0 to 8.2.1
- [Changelog](https://github.com/i18next/i18next-browser-languageDetector/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-browser-languageDetector/compare/v8.2.0...v8.2.1)

Updates `lucide` from 0.546.0 to 0.575.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.575.0/packages/lucide)

Updates `mermaid` from 11.12.2 to 11.12.3
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/[email protected]@11.12.3)

Updates `pdfjs-dist` from 5.4.530 to 5.4.624
- [Release notes](https://github.com/mozilla/pdf.js/releases)
- [Commits](https://github.com/mozilla/pdf.js/compare/v5.4.530...v5.4.624)

Updates `postal-mime` from 2.7.1 to 2.7.3
- [Release notes](https://github.com/postalsys/postal-mime/releases)
- [Changelog](https://github.com/postalsys/postal-mime/blob/master/CHANGELOG.md)
- [Commits](https://github.com/postalsys/postal-mime/compare/v2.7.1...v2.7.3)

Updates `sortablejs` from 1.15.6 to 1.15.7
- [Release notes](https://github.com/SortableJS/Sortable/releases)
- [Commits](https://github.com/SortableJS/Sortable/compare/1.15.6...1.15.7)

Updates `tailwindcss` from 4.1.18 to 4.2.1
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.1/packages/tailwindcss)

Updates `terser` from 5.44.1 to 5.46.0
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/compare/v5.44.1...v5.46.0)

Updates `tesseract.js` from 6.0.1 to 7.0.0
- [Release notes](https://github.com/naptha/tesseract.js/releases)
- [Commits](https://github.com/naptha/tesseract.js/compare/v6.0.1...v7.0.0)

Updates `vite-plugin-static-copy` from 3.1.4 to 3.2.0
- [Release notes](https://github.com/sapphi-red/vite-plugin-static-copy/releases)
- [Changelog](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sapphi-red/vite-plugin-static-copy/compare/[email protected]@3.2.0)

Updates `@eslint/js` from 9.39.2 to 10.0.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v10.0.1/packages/js)

Updates `@types/pdfkit` from 0.17.4 to 0.17.5
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/pdfkit)

Updates `@vitest/coverage-v8` from 3.2.4 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/coverage-v8)

Updates `@vitest/ui` from 3.2.4 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/ui)

Updates `eslint` from 9.39.2 to 10.0.2
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.2...v10.0.2)

Updates `globals` from 17.0.0 to 17.4.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v17.0.0...v17.4.0)

Updates `jsdom` from 27.4.0 to 28.1.0
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/main/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/27.4.0...28.1.0)

Updates `lint-staged` from 16.2.7 to 16.3.1
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lint-staged/lint-staged/compare/v16.2.7...v16.3.1)

Updates `prettier` from 3.7.4 to 3.8.1
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.7.4...3.8.1)

Updates `typescript-eslint` from 8.51.0 to 8.56.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/typescript-eslint)

Updates `vite` from 7.3.0 to 7.3.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.1/packages/vite)

Updates `vite-plugin-node-polyfills` from 0.24.0 to 0.25.0
- [Release notes](https://github.com/davidmyersdev/vite-plugin-node-polyfills/releases)
- [Commits](https://github.com/davidmyersdev/vite-plugin-node-polyfills/compare/v0.24.0...v0.25.0)

Updates `vitest` from 3.2.4 to 4.0.18
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.0.18/packages/vitest)

Updates `vue` from 3.5.26 to 3.5.29
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.26...v3.5.29)

---
updated-dependencies:
- dependency-name: "@kenjiuno/msgreader"
  dependency-version: 1.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@matbee/libreoffice-converter"
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: cropperjs
  dependency-version: 2.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: i18next
  dependency-version: 25.8.13
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: i18next-browser-languagedetector
  dependency-version: 8.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: lucide
  dependency-version: 0.575.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: mermaid
  dependency-version: 11.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: pdfjs-dist
  dependency-version: 5.4.624
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: postal-mime
  dependency-version: 2.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: sortablejs
  dependency-version: 1.15.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: tailwindcss
  dependency-version: 4.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: terser
  dependency-version: 5.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: tesseract.js
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: vite-plugin-static-copy
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@eslint/js"
  dependency-version: 10.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@types/pdfkit"
  dependency-version: 0.17.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@vitest/ui"
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: eslint
  dependency-version: 10.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: globals
  dependency-version: 17.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: jsdom
  dependency-version: 28.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: lint-staged
  dependency-version: 16.3.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: prettier
  dependency-version: 3.8.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.56.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: vite
  dependency-version: 7.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: vite-plugin-node-polyfills
  dependency-version: 0.25.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: vitest
  dependency-version: 4.0.18
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: vue
  dependency-version: 3.5.29
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-01 14:26:20 +00:00
dependabot[bot] 9b099c6a6d build(deps): bump svelte from 5.53.1 to 5.53.6
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.53.1 to 5.53.6.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/[email protected]/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.53.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-03-01 14:21:39 +00:00
alam00000 146e3f07d4 Release v2.4.0 2026-03-01 19:49:14 +05:30
alam00000 e8563a1392 feat: add barcode field support in form creator and support to edit existing form fields 2026-03-01 19:48:34 +05:30
alam00000 d66287a55b feat: support multiple PDF in PDF encryption tool 2026-03-01 18:43:38 +05:30
Olivetti 0c67620b6a Add hosting instructions for BentoPDF
Added hosting instructions for BentoPDF as a static website with examples for Netlify, Vercel, and GitHub Pages.
2026-02-28 18:07:55 +01:00
alam00000 0695361469 feat: add CORS proxy configuration to Dockerfiles 2026-02-28 21:59:49 +05:30
Alam 88561b2fcb Merge pull request #529 from maxbengtzen/feature/swedish-translation
Add swedish translation
2026-02-28 18:39:47 +05:30
github-actions[bot] 9686c38d7f @maxbengtzen has signed the CLA in alam00000/bentopdf#529 2026-02-27 13:07:45 +00:00
Max Bengtzén 5b7f1fc85f Add swedish translation 2026-02-27 13:43:20 +01:00
alam00000 2c6d36037a refactor: move PageWatermarkConfig interface to dedicated types file
feat(i18n): add missing translations for 5 languages
- be: common.close, upload.clearFiles
- zh: addStamps username fields
- zh-TW, tr, pt: compressPdf compression settings
2026-02-27 15:00:51 +05:30
alam00000 98c65d2b45 Release v2.3.3 2026-02-27 14:03:58 +05:30
alam00000 1e7ef30fac Release v2.3.2 2026-02-27 14:02:13 +05:30
Alam 0eb7dc7114 Merge pull request #480 from alam00000/dependabot/npm_and_yarn/markdown-it-14.1.1
build(deps): bump markdown-it from 14.1.0 to 14.1.1
2026-02-26 20:34:56 +05:30
Alam 9e96abfbb1 Merge pull request #496 from alam00000/dependabot/npm_and_yarn/qs-6.15.0
build(deps-dev): bump qs from 6.14.1 to 6.15.0
2026-02-26 20:34:44 +05:30
Alam 9220507f63 Merge pull request #519 from hagibr/update-tool-translation-keys
Adding 'PDF Workflow Builder' and 'Bates Numbering' to toolTranslationKeys
2026-02-26 20:34:25 +05:30
Alam 0882bc9bc0 Merge pull request #518 from hagibr/update-portuguese-translation
Correction on pdfToExcel.name (Portuguese)
2026-02-26 20:33:06 +05:30
alam00000 85d90c3382 feat: node creation and serialization logic in workflow editor 2026-02-26 20:28:16 +05:30
Alexandre Hagihara 6251b25195 Adding some data-i18n attributes that were available on common.json but not applied yet on index.html 2026-02-26 11:56:40 -03:00
alam00000 88260c26ab Refactor color input fields and enhance watermark functionality
- Updated color input fields in various HTML pages to remove unnecessary classes for improved styling consistency.
- Modified the watermark node to include options for positioning and flattening watermarks.
- Enhanced the addTextWatermark function to support customizable positioning and page selection for watermarks.
- Added new controls for text and image watermarks in the UI, allowing users to specify text, font size, color, opacity, angle, and image scaling.
- Updated the WASM provider to use the latest version of pymupdf-wasm.
2026-02-26 19:40:22 +05:30
Alexandre Hagihara 582e5bf9cb Adding 'PDF Workflow Builder' and 'Bates Numbering' to toolTranslationKeys 2026-02-26 09:38:01 -03:00
Alexandre Hagihara 6e47777c15 Correction on pdfToExcel.name 2026-02-26 09:06:34 -03:00
Alam 2e64e8e8d4 Merge pull request #516 from hagibr/update-portuguese-translation
Updating the portuguese translations for the new tools
2026-02-26 04:54:44 +05:30
github-actions[bot] 93d012c92a @hagibr has signed the CLA in alam00000/bentopdf#516 2026-02-25 18:02:44 +00:00
Alexandre Hagihara f5953d8c87 Updating the portuguese translations for the new tools 2026-02-25 14:34:28 -03:00
alam00000 64153e698b fix: improve error handling, race condition and optimize page rendering logic in pdf multi tool 2026-02-25 13:17:30 +05:30
Alam 518c18664d Merge pull request #502 from alam00000/dependabot/npm_and_yarn/svelte-5.53.1
build(deps): bump svelte from 5.48.2 to 5.53.1
2026-02-25 12:22:06 +05:30
Alam dbbad3f5d9 Merge pull request #498 from alam00000/dependabot/npm_and_yarn/jspdf-4.2.0
build(deps): bump jspdf from 4.1.0 to 4.2.0
2026-02-25 12:21:05 +05:30
alam00000 3e38e5b175 fix: add compact mode to simple mode 2026-02-24 20:40:24 +05:30
Alam 3fb779b231 Merge pull request #504 from Stephan-P/patch-2
Update tools.json
2026-02-22 23:39:33 +05:30
Alam 988949dbf2 Merge pull request #503 from Stephan-P/patch-1
Update common.json
2026-02-22 23:39:18 +05:30
Stephan Paternotte 4f7f477898 Update common.json
interpunction corrected
2026-02-22 11:43:39 +01:00
Stephan Paternotte c94d15f305 Update tools.json 2026-02-21 10:50:58 +01:00
Stephan Paternotte 9283e89f19 Update common.json 2026-02-21 10:48:41 +01:00
alam00000 a386fd26fc fix: enhance error handling for i18n page generation 2026-02-21 14:44:09 +05:30
alam00000 32ba24782f Release v2.3.1 2026-02-21 14:27:59 +05:30
alam00000 a119837c8a fix: improve error handling in performCondenseCompression function
fix: routing
2026-02-21 14:27:53 +05:30
alam00000 b9499b228a Release v2.3.0 2026-02-21 14:05:57 +05:30
alam00000 3cae20a10c feat: add Bates numbering tool with PDF processing capabilities
- Implemented bates-numbering-page.ts for handling Bates numbering logic.
- Created a new HTML page for Bates numbering functionality.
- Added style presets and file handling for multiple PDF uploads.
- Integrated user interface elements for file selection, style customization, and preview.
- Enhanced main.ts to support collapsible categories and compact mode for tool grid.
- Updated types for Bates numbering in bates-numbering-type.ts.
- Registered the new tool in tools.html and updated routing in vite.config.ts.
2026-02-21 14:05:48 +05:30
dependabot[bot] f7a1eef5ec build(deps): bump svelte from 5.48.2 to 5.53.1
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.48.2 to 5.53.1.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/[email protected]/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.53.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-02-21 08:31:36 +00:00
dependabot[bot] 7351cb2e32 build(deps): bump markdown-it from 14.1.0 to 14.1.1
Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 14.1.0 to 14.1.1.
- [Changelog](https://github.com/markdown-it/markdown-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/markdown-it/compare/14.1.0...14.1.1)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-version: 14.1.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-02-21 08:30:54 +00:00
Alam 7313fa08a8 Merge pull request #501 from diogotcorreia/pin-xlsx
chore: pin xlsx version
2026-02-21 13:59:36 +05:30
github-actions[bot] 1174a6dbaa @diogotcorreia has signed the CLA in alam00000/bentopdf#501 2026-02-21 00:26:40 +00:00
Diogo Correia c37218b86d chore: update project version in package-lock.json 2026-02-21 01:17:32 +01:00
Diogo Correia efa91e7a72 chore: pin xlsx version
This ensures reproducibility when building this project.
2026-02-21 01:16:16 +01:00
dependabot[bot] c8391d5886 build(deps): bump jspdf from 4.1.0 to 4.2.0
Bumps [jspdf](https://github.com/parallax/jsPDF) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/parallax/jsPDF/releases)
- [Changelog](https://github.com/parallax/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/parallax/jsPDF/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: jspdf
  dependency-version: 4.2.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-02-20 13:13:36 +00:00
dependabot[bot] 43d747b3c5 build(deps-dev): bump qs from 6.14.1 to 6.15.0
Bumps [qs](https://github.com/ljharb/qs) from 6.14.1 to 6.15.0.
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.1...v6.15.0)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.15.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-02-20 11:58:48 +00:00
alam00000 e6c8eaf23c fix: improve CORS proxy handling and update documentation for certificate fetching 2026-02-20 16:07:38 +05:30
Alam 832e28aaca Merge pull request #494 from tzabbi/main
chore: update bentopdf version in helm chart
2026-02-20 15:26:34 +05:30
Tom Zaspel 404dd544ab Merge branch 'alam00000:main' into main 2026-02-19 17:33:17 +01:00
Tom Zaspel 87d37a8be4 chore: update version of bentopdf 2026-02-19 17:32:48 +01:00
Alam 561ac12304 Merge pull request #493 from tzabbi/main
fix: httproute invalid syntax and tweak chart
2026-02-19 20:50:17 +05:30
Tom Zaspel 450815db96 chore: bump version of helm chart and update appVersion 2026-02-19 15:16:44 +01:00
github-actions[bot] eea81e7fd6 @tzabbi has signed the CLA in alam00000/bentopdf#493 2026-02-19 11:27:47 +00:00
Tom Zaspel dffcfb77f3 chore: remove fullname because it is not needed 2026-02-19 12:18:33 +01:00
Tom Zaspel b4ff2f68f8 chore: replace chart value from the _helpers.tpl and set it to bentopdf 2026-02-19 11:06:50 +01:00
Tom Zaspel 1c7cc36472 fix: httpRoute template file 2026-02-18 06:48:01 +01:00
Alam b42d991157 Merge pull request #486 from pavel-miniutka/main
Belarusian translation update
2026-02-17 20:01:17 +05:30
pavel-miniutka f129b732ae Belarusian translation update 2026-02-17 15:20:27 +03:00
alam00000 179de7ef83 Release v2.2.1 2026-02-14 21:57:54 +05:30
alam00000 dc0f3b30ad add: tools to readme 2026-02-14 21:55:15 +05:30
alam00000 3cf435d59d feat: add custom branding, air-gapped deployment script, and updated self-hosting docs 2026-02-14 21:41:45 +05:30
alam00000 75b1d67fbd feat: add support for default UI language configuration and non-root Dockerfile 2026-02-13 13:45:11 +05:30
Alam d1d354359c Merge pull request #473 from Stephan-P/patch-1
Update tools.json
2026-02-12 19:48:55 +05:30
Stephan Paternotte a9e007af66 Update tools.json
Translation of Workflow builder revisited
2026-02-10 17:45:40 +01:00
alam00000 f19e901a65 Release v2.2.0 2026-02-09 12:31:31 +05:30
alam00000 45be8b832d feat: implement PDF password handling and enhance toolbox UI for better accessibility 2026-02-09 12:27:52 +05:30
alam00000 d36c1f4ab9 feat: add RedactNode for secure PDF text redaction and update node registry 2026-02-08 20:40:16 +05:30
alam00000 49cccf95b4 fix: image compression functionality and integrate quality selection for PDF conversion 2026-02-08 20:12:07 +05:30
Alam 271279505b Merge pull request #453 from spwoodcock/fix/helm-chart
Tweak gateway + httproute usage in production helm chart release
2026-02-08 20:00:17 +05:30
Alam 7ab602a05f Merge pull request #454 from alam00000/dependabot/npm_and_yarn/jspdf-4.1.0
build(deps): bump jspdf from 4.0.0 to 4.1.0
2026-02-08 17:21:13 +05:30
dependabot[bot] 04587be28b build(deps): bump jspdf from 4.0.0 to 4.1.0
Bumps [jspdf](https://github.com/parallax/jsPDF) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/parallax/jsPDF/releases)
- [Changelog](https://github.com/parallax/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/parallax/jsPDF/compare/v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: jspdf
  dependency-version: 4.1.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-02-08 11:37:06 +00:00
alam00000 5d8b83e105 Add visual workflow builder, fix critical bugs, and add Arabic i18n support 2026-02-08 17:05:40 +05:30
Alam 36ebb3b429 Merge pull request #457 from Stephan-P/patch-1
Update common.json
2026-02-05 19:03:42 +05:30
Alam 174eb0631e Merge pull request #458 from pavel-miniutka/main
Belarusian translation update
2026-02-05 19:03:26 +05:30
Alam bd957717a2 Merge pull request #459 from TheScienceotter/fix-watermark_rotation
(Fix) Rotate watermark text around centre of page
2026-02-05 19:03:12 +05:30
Alam 56f1b46389 Merge pull request #461 from froeand/add-danish-translation
Add danish translation
2026-02-05 19:02:52 +05:30
github-actions[bot] db72cf6d6b @froeand has signed the CLA in alam00000/bentopdf#461 2026-02-03 13:50:14 +00:00
Frørup Andelskasse 13484e3e44 Update vite.config.ts
Added Danish.
2026-02-03 14:32:04 +01:00
Frørup Andelskasse abba411cf0 Update i18n.ts
Added danish
2026-02-03 14:30:54 +01:00
Frørup Andelskasse 86eaf1f045 Update tools.json 2026-02-03 14:27:30 +01:00
Frørup Andelskasse 2e50d4f717 Update common.json 2026-02-03 14:24:00 +01:00
Frørup Andelskasse a491d359e3 Create tools.json
Danish
2026-02-03 14:13:01 +01:00
Frørup Andelskasse 888ef253e7 Create common.json
Danish
2026-02-03 14:12:45 +01:00
github-actions[bot] dc86c780d6 @TheScienceotter has signed the CLA in alam00000/bentopdf#459 2026-02-03 09:45:30 +00:00
pavel-miniutka 92636f33c5 Belarusian translation update 2026-02-03 12:35:45 +03:00
Stephan Paternotte 943abdd77a Update common.json
A few Dutch language corrections
2026-02-03 08:01:53 +01:00
spwoodcock 9b1fd41cf1 build: bump chart version 1.0.0 for prod release 2026-02-02 21:22:33 +00:00
spwoodcock f98f77281e docs: restructure helm chart usage notes + examples 2026-02-02 21:22:21 +00:00
spwoodcock 655ac7ed08 fix: helm chart, a few fixes to gateway and httroute after prod testing 2026-02-02 21:21:53 +00:00
spwoodcock 220d5d59c3 docs: specify bumping appVersion in helm chart during release 2026-02-02 18:20:22 +00:00
spwoodcock 3a6ce7b25e fix: specify ghcr for default helm chart image + bump --> 2.1.0 2026-02-02 18:19:54 +00:00
Alam 4fe8ba6110 Merge pull request #450 from Stephan-P/patch-1
Update tools.json
2026-02-02 23:25:24 +05:30
Stephan Paternotte 7986107b57 Update tools.json
one faulty utf-8 character corrected
2026-02-02 18:46:26 +01:00
alam00000 073e6b12bf Release v2.1.0 2026-02-02 19:55:37 +05:30
alam00000 93e26ea178 fix: WASM CDN defaults bypass Docker empty env vars, nginx redirect port issue
- Fix envOrDefault() to treat empty strings as unset, so Docker builds
  without WASM build args correctly fall through to hardcoded CDN defaults
- Show CDN defaults as placeholder text in WASM settings page instead of
  filling input values, with "Pre-configured" status badge
- Fix nginx redirecting locale URLs without trailing slash (e.g. /de) to
  internal port 8080 by adding absolute_redirect off
- Handle encrypted PDF error in compress tool with descriptive message
- Replace Docker Hub pulls badge with GHCR downloads badge
2026-02-02 19:38:04 +05:30
alam00000 f9ddd51eb1 refactor: streamline WASM package configuration and improve default URL handling 2026-02-02 17:12:02 +05:30
alam00000 70f31aa90e fix: Add internationalization support for various pages by updating text elements with data-i18n attributes for better localization 2026-02-02 16:30:59 +05:30
alam00000 612f6f9a2d feat: add WASM module configuration with pre-configured CDN URLs and update settings UI 2026-02-02 15:14:30 +05:30
Alam 200359d2e2 Merge pull request #444 from Stephan-P/patch-1
Update common.json
2026-02-01 22:55:49 +05:30
Alam 3fe1069e2f Merge pull request #445 from Stephan-P/patch-2
Update tools.json
2026-02-01 22:55:29 +05:30
Stephan Paternotte 6eb6d879f3 Update tools.json
Various corrections in the Dutch translation
2026-02-01 12:26:49 +01:00
Stephan Paternotte 55afb2f61e Update common.json
Dutch language updated
2026-02-01 12:12:07 +01:00
alam00000 325519b9f7 feat: add adjust colors and scanner effect pages with corresponding types and configurations 2026-02-01 12:21:14 +05:30
alam00000 a929524f09 Release v2.0.0 2026-01-31 15:38:38 +05:30
alam00000 5c1b00e9d1 fix: update supported languages and improve PDF editor functionality with multi file support 2026-01-31 15:24:08 +05:30
Alam e4a477567b Merge pull request #375 from EmeraldPi/main
Fix: restore embedpdf workflow, external xlsx reference, workflow changes
2026-01-31 14:02:08 +05:30
Alam 50e31b922b Merge branch 'main' into main 2026-01-31 14:00:46 +05:30
Alam b616ec0fbf Merge pull request #432 from pavel-miniutka/main
Added Belarusian translation
2026-01-31 13:58:06 +05:30
Richard Grimes 5e66d42f59 Position of watermark text now calculated in polar coordinates
Watermark text will now appear to rotate around the page centre, rather than at the bottom corner of the text element.
2026-01-30 11:50:17 +01:00
alam00000 75df8a48cb fix:gs loading issue 2026-01-30 15:50:08 +05:30
alam00000 fa10e97a00 refactor: remove ghostscript-wasm and update service worker and ghostscript loader
- Deleted the ghostscript-wasm binary file.
- Added new ICC profile file for color management.
- Updated service worker to change cache version and remove ghostscript-wasm assets from critical assets.
- Modified ghostscript loader to handle asset URLs more robustly and fetch the new ICC profile correctly.
2026-01-30 15:24:33 +05:30
alam00000 981aff3c5a fix: service worker caching and ghostscript loader path issues 2026-01-30 14:58:18 +05:30
alam00000 a85f21dcb5 fix: apply network-first strategy to language prefixed URLs in service worker 2026-01-30 14:19:42 +05:30
alam00000 eb60bbe771 added advanced settings to simple mode 2026-01-27 22:51:58 +05:30
EmeraldPi 3fbb97d24b Merge pull request #7 from EmeraldPi/chore/update-embedpdf-snippet 2026-01-27 11:51:26 -05:00
alam00000 25687fa049 fix: separate GHCR and Docker Hub builds 2026-01-27 19:19:44 +05:30
github-actions[bot] 9c57adf634 @pavel-miniutka has signed the CLA in alam00000/bentopdf#432 2026-01-27 13:42:55 +00:00
pavel-miniutka 9e1aeb178a Added Belarusian translation 2026-01-27 16:29:24 +03:00
alam00000 09d3afa1da ci: split Docker Hub and GHCR manifest jobs to prevent rate limit failures 2026-01-27 18:54:35 +05:30
alam00000 a14c046b89 fix: pymupdf-wasm to use the latest version 2026-01-27 17:26:42 +05:30
alam00000 4fb3b0ec1c fix: optimize i18n page generation to prevent OOM during Docker build 2026-01-27 16:40:57 +05:30
alam00000 73a8156c80 fix(docker): increase Node.js memory limit for i18n build
Add NODE_OPTIONS with --max-old-space-size=4096 to prevent OOM kills
during i18n page generation. JSDOM is memory-intensive when processing
multiple language pages.
2026-01-27 16:10:08 +05:30
alam00000 0c1e89f6f4 refactor: simplify Dockerfile build command 2026-01-27 15:51:03 +05:30
alam00000 2c85ca74e9 feat: separate AGPL libraries and add dynamic WASM loading
- Add WASM settings page for configuring external AGPL modules
- Implement dynamic loading for PyMuPDF, Ghostscript, and CoherentPDF
- Add Cloudflare Worker proxy for serving WASM files with CORS
- Update all affected tool pages to check WASM availability
- Add showWasmRequiredDialog for missing module configuration

Documentation:
- Update README, licensing.html, and docs to clarify AGPL components
  are not bundled and must be configured separately
- Add WASM-PROXY.md deployment guide with recommended source URLs
- Rename "CPDF" to "CoherentPDF" for consistency
2026-01-27 15:26:26 +05:30
Alam f6d432eaa7 Merge pull request #405 from LoganK/crop_restore
(Fix) Restore crop bounds when navigating
2026-01-27 13:54:01 +05:30
Alam 627e932441 Merge pull request #421 from alam00000/dependabot/npm_and_yarn/lodash-4.17.23
build(deps): bump lodash from 4.17.21 to 4.17.23
2026-01-27 13:53:36 +05:30
dependabot[bot] febf664f74 build(deps): bump lodash from 4.17.21 to 4.17.23
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-27 08:21:25 +00:00
Alam 544bc2f0b6 Merge pull request #428 from alam00000/dependabot/npm_and_yarn/svelte-5.48.2
build(deps): bump svelte from 5.46.1 to 5.48.2
2026-01-27 13:50:05 +05:30
alam00000 b745831526 fix: use absolute paths for i18n links to prevent URL duplication 2026-01-26 23:46:19 +05:30
alam00000 c010327daa fix: detect language prefix in relative hrefs without leading slash 2026-01-26 23:14:05 +05:30
alam00000 c2520f7736 fix: add missing comma 2026-01-26 22:57:32 +05:30
alam00000 62c373d76a fix: resolve i18n issues - URL duplication, translation loading, and caching
- Fix URL path duplication when clicking logo (added missing leading slash)
- Use network-first caching for translation files in service worker
- Add missing translation keys (common.close, upload.clearFiles) to all languages
- Add Dutch (nl) language support to URL regex patterns
- Bump service worker cache version to v8
2026-01-26 22:34:36 +05:30
Alam 2d99a28b07 Merge pull request #386 from sheing-google/feat/organize-by-page-number-15124152069150472705
feat: Add page number string reordering to Organize PDF tool
2026-01-26 17:17:09 +05:30
Alam adc511193d Merge pull request #292 from Stephan-P/main
Introduction of Dutch language support
2026-01-26 15:29:15 +05:30
Alam 4825997299 Merge branch 'main' into main 2026-01-26 15:28:56 +05:30
Alam e0f5e71a55 Merge pull request #388 from spwoodcock/build/helm-chart
Add helm chart for kubernetes deployment
2026-01-26 15:27:46 +05:30
alam00000 36b98eb1af Release v1.16.1 2026-01-26 13:52:17 +05:30
dependabot[bot] 80e504032c build(deps): bump svelte from 5.46.1 to 5.48.2
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.46.1 to 5.48.2.
- [Release notes](https://github.com/sveltejs/svelte/releases)
- [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md)
- [Commits](https://github.com/sveltejs/svelte/commits/[email protected]/packages/svelte)

---
updated-dependencies:
- dependency-name: svelte
  dependency-version: 5.48.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-26 08:11:17 +00:00
alam00000 b059ac6ada chore: migrate Docker Hub to bentopdfteam, add Podman/Quadlet support
- Migrate Docker Hub account from bentopdf to bentopdfteam
- Make GHCR the recommended container registry
- Add Podman and Podman Compose support
- Add Podman Quadlet (systemd) documentation
- Add Table of Contents to README
2026-01-26 13:34:50 +05:30
EmeraldPi a6dcca0313 build(deps): bump embedpdf-snippet from 2.1.2 to 2.3.0 2026-01-26 04:25:23 +00:00
spwoodcock eb9ff4a1a0 fix: bump chart to use GHCR, due to https://github.com/alam00000/bentopdf/issues/399 2026-01-25 21:17:51 +00:00
luna-cant-code 0bad67a40f translated common 2026-01-24 15:00:44 +01:00
Stephan Paternotte 53a03599e4 Update i18n.ts
My attempt to resolve the PR conflict
2026-01-23 08:39:03 +01:00
github-actions[bot] 21b9b58610 @JaL-P has signed the CLA in alam00000/bentopdf#410 2026-01-20 21:00:50 +00:00
github-actions[bot] bf6e212a2d @LoganK has signed the CLA in alam00000/bentopdf#405 2026-01-19 09:14:32 +00:00
Logan Kennelly 23e40f9ef9 fix(crop-pdf): Restore crop bounds when navigating
cropperjs ignores attempts to modify the data before ready. This change
migrates setup to a one-time 'ready' callback.

Steps:
1. Change the cropping bounds of page 1
2. Change to page 2
3. Change to page 1
4. Change to page 2
5. Download cropped PDF

Observed behavior:
* (3) shows the default (autocrop) bounds
* (5) results in a download without the set bounds

Expected behavior:
* (3) should restore the bounds already set
* (4) should not override the set bounds with the autocrop

Tested:
* Local builds using the docker dev config
2026-01-19 01:14:07 -08:00
alam00000 fb8c8c07ae chore: update licensing information and readme 2026-01-15 21:53:01 +05:30
spwoodcock 67b17138f0 docs: add docs for kubernetes deployment 2026-01-15 13:39:49 +00:00
spwoodcock 3f585e2676 build: downgrade to v1.15.3, as the latest available tagged image 2026-01-15 12:37:16 +00:00
github-actions[bot] b9b98294b5 @spwoodcock has signed the CLA in alam00000/bentopdf#388 2026-01-15 11:54:02 +00:00
Stephan Paternotte 180befda84 Update tools.json
Additional translations: emailtopdf, fonttooutline + deskewpdf 
Fix indenting in line with latest EN sources
2026-01-15 10:05:11 +01:00
Stephan Paternotte 704ad60b26 Update common.json
Another in-between update
reformat indenting in line with latest EN sources
2026-01-15 10:03:03 +01:00
spwoodcock 359dd48b2a build: add helm chart for kubernetes deployment 2026-01-14 21:45:05 +00:00
github-actions[bot] 61390d97fe @sheing-google has signed the CLA in alam00000/bentopdf#386 2026-01-14 21:38:20 +00:00
sheing-google b8dcf39772 feat: Add page number string reordering to Organize PDF tool
This commit introduces a new feature to the "Organize PDF" tool that allows users to reorder pages by providing a comma-separated string of page numbers.

An "Advanced Settings" section has been added to the UI, containing a text input for the page order and an "Apply Order" button. The implementation includes validation for the input and updates the page thumbnail grid accordingly.
2026-01-14 21:24:46 +00:00
Sheing da115e97c2 Delete package-lock.json 2026-01-14 15:20:56 -06:00
sheing-google 5f49cac1b2 feat: Add page number string reordering to Organize PDF tool
This commit introduces a new feature to the "Organize PDF" tool that allows users to reorder pages by providing a comma-separated string of page numbers.

An "Advanced Settings" section has been added to the UI, containing a text input for the page order and an "Apply Order" button. The implementation includes validation for the input and updates the page thumbnail grid accordingly.
2026-01-14 21:15:30 +00:00
sheing-google 4a23dabd52 feat: Add page number string reordering to Organize PDF tool
This commit introduces a new feature to the "Organize PDF" tool that allows users to reorder pages by providing a comma-separated string of page numbers.

An "Advanced Settings" section has been added to the UI, containing a text input for the page order and an "Apply Order" button. The implementation includes validation for the input and updates the page thumbnail grid accordingly.
2026-01-14 21:11:11 +00:00
alam00000 8f628e2b5a ci(docker): refactor build workflow to separate platform builds and merge manifests 2026-01-14 22:38:56 +05:30
alam00000 7787e1d9ac chore(docker,docs): improve npm reliability and update feature documentation
- Configure npm fetch retries and timeouts in Dockerfile to handle network issues during dependency installation
- Set fetch-retries to 5, fetch-retry-mintimeout to 60s, fetch-retry-maxtimeout to 300s, and fetch-timeout to 600s
- Update README.md feature descriptions for improved clarity and accuracy
- Add bookmark preservation notes to Merge PDFs and Alternate & Mix Pages tools
- Add new features: Rotate by Custom Degrees, PDF Booklet, PDF Form Filler, Deskew PDF, and Font to Outline
- Enhance PDF Editor description with specific capabilities (annotate, highlight, redact, comment, shapes, images, search)
- Reorganize feature table entries for better logical grouping
- Remove duplicate "Fill Forms" entry in favor of new PDF Form Filler tool
2026-01-14 22:20:41 +05:30
alam00000 21c928365a Release v1.16.0 2026-01-14 22:09:26 +05:30
alam00000 531e1ad1c6 add comprehensive .htaccess configuration for production deployment
- Update Apache documentation with complete .htaccess examples for both root and subdirectory deployments
- Include configuration examples for subpath deployments (e.g., /pdf/)
2026-01-14 22:05:16 +05:30
alam00000 abf7ae8a00 feat(i18n): add static pre-rendering for multi-language support
- Add `generate-i18n-pages.mjs` script to pre-render localized HTML files at build time
- Add `generate-sitemap.mjs` script to generate language-aware sitemap.xml
- Create `navbar-simple.html` and `footer-simple.html` partials for simple mode
- Update all 80+ tool pages with language routing support
- Expand supported languages to 12: en, de, es, fr, it, pt, tr, vi, id, zh, zh-TW
- Update i18n.ts with new language names and support configuration
- Implement languageRouterPlugin in vite.config.ts for dev server routing
- Update nginx.conf for production static file serving from language directories
- Update TRANSLATION.md with new architecture documentation and language addition guide
- Fix relative paths in 404.html for static deployment compatibility
- Update package.json with new build scripts and dependencies
- Improves SEO through static pre-rendering and proper sitemap generation
2026-01-14 21:04:56 +05:30
alam00000 90346d7ea9 feat: Simple Mode language routing and translation improvements
## Simple Mode Enhancements
- Add `simple-index.html` as dedicated homepage for Simple Mode
- Hide marketing sections (FAQ, How It Works, Related Tools) on tool pages
- Add simplified navbar and footer for tool pages in Simple Mode
- Configure vite preview server to handle language-prefixed URLs

## Language Routing
- Add middleware to rewrite language-prefixed URLs (e.g., /de/merge-pdf.html)
- Support all languages: en, de, es, fr, id, it, pt, tr, vi, zh, zh-TW
- Create .htaccess with internal rewrites for Apache/Hostinger hosting

## Translation Updates
- Add missing translations for digitalSignPdf, validateSignaturePdf,
  emailToPdf, fontToOutline, deskewPdf to es, pt, tr, zh-TW
- Add Digital Signature and Validate Signature to homepage translation keys
- Fix language regex patterns to include all supported languages
- Fix typo in encrypt-pdf.html
2026-01-14 02:31:44 +05:30
Alam 59584813e4 Merge pull request #348 from raulgcode/add-spanish-translation
(Feature): Add spanish translation and update documentation with missing steps
2026-01-13 22:45:55 +05:30
Alam 7eeae0bda5 Merge branch 'main' into add-spanish-translation 2026-01-13 22:45:05 +05:30
alam00000 4db4c6c719 fix(vite): add @/types path alias to resolve.alias for build compatibility 2026-01-13 17:19:07 +05:30
alam00000 b57c9a8575 fix: made bookmark pdf type safe 2026-01-13 16:59:25 +05:30
alam00000 446b399be2 refactor: extract navbar and footer into reusable handlebars partials
- Replace duplicated navbar markup across all HTML pages with {{> navbar }} partial
- Replace duplicated footer markup across all HTML pages with {{> footer }} partial
- Add TypeScript type definitions for vite-plugin-handlebars integration
- Update vite.config.ts to support handlebars partial compilation
- Update tsconfig.json to include handlebars type definitions
- Update nginx.conf for proper static file serving with partials
- Update translation files for de, pt, tr, vi, and zh-TW locales
- Reduce code duplication and improve maintainability across 13+ HTML pages
- Ensure consistent navbar and footer behavior across the entire application
2026-01-13 15:13:57 +05:30
alam00000 d9045efcb0 fix: static deployment for github pages 2026-01-13 13:33:23 +05:30
abdullahalam123 dfd56c12d5 refactor: extract navbar and footer into reusable partials
- Extract navbar component from index.html into src/partials/navbar.html
- Extract footer component from index.html into src/partials/footer.html
- Add update-partials.js script to automate partial injection into page templates
- Update all 80+ page templates to use injected navbar and footer partials
- Update vite.config.ts to support partial file processing
- Update package.json and package-lock.json with build script changes
- Sync all translation files (de, en, fr, id, it, pt, tr, vi, zh, zh-TW) with latest keys
- Improves maintainability by centralizing navbar and footer updates across all pages
2026-01-12 22:11:01 +05:30
abdullahalam123 8337c8b45b Merge branch 'fix/pdf-form-creator-bug' 2026-01-12 14:16:05 +05:30
Alam e46f612d4e Merge pull request #379 from NightFeather0615/i18n/zh-TW
feat(i18n): Add Traditional Chinese (`zh-TW`) language support
2026-01-12 13:58:50 +05:30
NightFeather bc3de197c8 Add missing i18n guide for zh and zh-TW 2026-01-12 16:10:38 +08:00
abdullahalam123 cf61212515 feat(form-creator): add custom date formats, fix duplicate field bug, improve sticky UX
Bug Fixes:
- Fix duplicate field appearing when removing all options from dropdown/list and dragging
- Fix selected tool button ring being clipped by removing overflow-hidden from Fields toolbar

Date Format Enhancements:
- Add all 30 Adobe Acrobat-compatible date formats
- Add ISO 8601 formats (yyyy-mm-dd, yyyy-mm, yyyy)
- Add European dot-separated formats (dd.mm.yyyy, dd.mm.yy)
- Add date-time formats with 12h/24h time support
- Add Custom format option with input field
- Add live date format example preview

UI/UX Improvements:
- Make Properties sidebar sticky on large screens
- Make Page Management toolbar sticky below navbar
- Make Fields toolbar sticky below Page Management toolbar
- Increase Fields toolbar padding for better spacing
- Fix browser note text alignment in date properties
2026-01-12 13:30:54 +05:30
NightFeather 5e9ac1c492 Merge branch 'main' into i18n/zh-TW 2026-01-12 15:55:44 +08:00
Alam 2910a3f72d Merge pull request #282 from alexandreforeis/feat-pt-br
feat(i18n): add Portuguese (Brazil) translation
2026-01-12 12:46:20 +05:30
Alam 50f62a815c Merge pull request #380 from gianlucaalfa/main
fix-italian-translation
2026-01-12 12:43:58 +05:30
Alam ac8ea1311d Merge pull request #260 from StanislasMzx/add-french-translation
feat(i18n): Add French (Français) language support
2026-01-12 12:43:11 +05:30
Stanislas MEZUREUX ec830880e7 chore(i18n): add new translation keys 2026-01-12 00:02:28 +01:00
Stanislas MEZUREUX 584acc68d0 feat(i18n): Add French (Français) language support 2026-01-11 23:38:39 +01:00
github-actions[bot] 41970ec330 @gianlucaalfa has signed the CLA in alam00000/bentopdf#380 2026-01-11 10:30:57 +00:00
gianlucaalfa d7fce5987d fix-italian-translation 2026-01-11 11:19:27 +01:00
github-actions[bot] 3137b0e2c4 @NightFeather0615 has signed the CLA in alam00000/bentopdf#379 2026-01-10 19:30:32 +00:00
NightFeather 1ac0f751e8 Add Traditional Chinese (zh-TW) localization 2026-01-11 03:19:45 +08:00
Alam 01f5aca5aa Merge pull request #363 from alam00000/dependabot/npm_and_yarn/jspdf-4.0.0
build(deps): bump jspdf from 3.0.4 to 4.0.0
2026-01-10 14:49:47 +05:30
abdullahalam123 c5799954dc fix(ocr): improve text layer alignment with width-based font sizing
- Create new hocr-transform.ts utility for parsing hOCR output
- Add line-aware text processing with baseline and rotation support
- Implement width-based font size calculation to match word bounding boxes
- Fix text selection not covering full characters issue
- Add proper type definitions for OcrLine, OcrPage, WordTransform
- Support RTL languages and CJK word break handling
2026-01-10 13:09:52 +05:30
abdullahalam123 1f7238d0b5 feat: add Deskew PDF and Font to Outline tools with improved issue templates
New Features:
- Add Deskew PDF tool for straightening scanned/skewed PDF pages
- Add Font to Outline tool for converting text to vector paths
- Add translations for new tools in all supported locales (de, en, id, it, tr, vi, zh)

Improvements:
- Migrate GitHub issue templates from markdown to YAML forms
  - Separate templates for bug reports, feature requests, and questions
  - Add config.yml for issue template chooser
- Update sitemap.xml with new tool pages
- Update ghostscript loader and helper utilities
2026-01-09 20:53:36 +05:30
Connor Smith 1fc962082a Fix: restore embedpdf workflow, external xlsx reference 2026-01-09 04:09:27 +00:00
Raul Gonzalez cc891f2b0a Merge branch 'main' of https://github.com/alam00000/bentopdf into add-spanish-translation 2026-01-08 14:01:02 -06:00
abdullahalam123 280348763d feat(email-to-pdf): add inline images, clickable links, and embedded attachments
- Add CID inline image support via base64 data URI replacement
- Implement clickable link extraction from HTML anchors using regex
- Embed email attachments into PDF using pymupdf embfile_add
- Reduce font sizes for more compact PDF output (18px subject, 12px body)
- Format date with timezone (UTC+HH:MM) while preserving original time
- Clean email address formatting (Name (email) instead of <brackets>)
- Add UI options: page size selector, CC/BCC toggle, attachments toggle
2026-01-08 21:36:21 +05:30
Alam 4a4a47158f Merge pull request #289 from htekgulds/add-lang-tr
(Feature) Add support for Turkish language
2026-01-08 14:00:07 +05:30
github-actions[bot] c58fcec497 @alam00000 has signed the CLA in alam00000/bentopdf#289 2026-01-08 08:29:39 +00:00
Alam 11ea5d21c5 Merge branch 'main' into add-lang-tr 2026-01-08 13:58:26 +05:30
Alam ad28b5450a Merge pull request #367 from hnfnfl/feature/indonesian-translation
(Feature) Add Indonesian language support
2026-01-08 13:54:55 +05:30
Hanif Naufal 7907f20907 fix: correct Indonesian language name in languageNames mapping 2026-01-08 00:09:39 +07:00
github-actions[bot] e44f4960b6 @hnfnfl has signed the CLA in alam00000/bentopdf#367 2026-01-07 16:11:21 +00:00
Hanif Naufal 2ee1dbf542 feat: update translation guide and configuration for Indonesian language support 2026-01-07 23:02:41 +07:00
Hanif Naufal 5f8e94c41f feat: add Indonesian language support with translations for common phrases and tools 2026-01-07 22:49:05 +07:00
Hanif Naufal e399315798 feat: add Indonesian language support to translation guide 2026-01-07 22:46:54 +07:00
abdullahalam123 4cec0e2be4 chore: update sitemap with signature tools and clean unused imports 2026-01-07 16:55:12 +05:30
abdullahalam123 b51d611c8a Fix header/subtitle FOUC and Simple Mode translations
- Refactor tool page headers to prevent flash of unstyled content (FOUC):
  - Move long SEO titles to visually hidden `<h1>` tags for search engines.
  - Use `<h2>` for visible tool titles with text matching i18n keys.
  - Sync default HTML subtitles with [tools.json]
2026-01-06 20:48:59 +05:30
Raul Gonzalez e34b106e10 Merge remote-tracking branch 'upstream/main' into add-spanish-translation 2026-01-06 08:27:11 -06:00
dependabot[bot] 0491c1118e build(deps): bump jspdf from 3.0.4 to 4.0.0
Bumps [jspdf](https://github.com/parallax/jsPDF) from 3.0.4 to 4.0.0.
- [Release notes](https://github.com/parallax/jsPDF/releases)
- [Changelog](https://github.com/parallax/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/parallax/jsPDF/compare/v3.0.4...v4.0.0)

---
updated-dependencies:
- dependency-name: jspdf
  dependency-version: 4.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-01-05 18:21:15 +00:00
abdullahalam123 809508b492 chore: add react and react-dom overrides to package.json 2026-01-05 19:58:08 +05:30
abdullahalam123 38713ef563 build: Disable Husky hooks in CI/CD workflows and Dockerfile. 2026-01-05 19:40:36 +05:30
abdullahalam123 3d0b829af8 chore: Delete npm prepare script from package.json during build. 2026-01-05 19:34:55 +05:30
abdullahalam123 6f47b3f16f chore(security): fix high-severity vulnerability in node-forge
- Added NPM override to force `node-forge` version 1.3.3.
- Resolves high-severity ASN.1 vulnerability in `zgapdfsigner` dependency chain.
2026-01-05 19:16:57 +05:30
abdullahalam123 8332616346 chore: add Husky and lint-staged for pre-commit checks 2026-01-05 19:11:58 +05:30
abdullahalam123 a347cbda3d Configure ESLint with Prettier and TypeScript support.
- Baseline existing errors to warnings.
- Fix Image to PDF tool for HEIC and WebP inputs.
- Apply linting auto-fixes.
2026-01-05 19:04:47 +05:30
abdullahalam123 c9b9482cb6 fix: webp & heic convert in images to pdf 2026-01-05 18:35:17 +05:30
abdullahalam123 d52d2e3647 refactor: move all TypeScript interfaces to centralized src/js/types folder
- Create type files with barrel export via @/types alias
- Update logic files to use centralized type imports
2026-01-05 14:57:30 +05:30
abdullahalam123 8a96426254 feat(cors-proxy): add anti-spoofing security measures
Security improvements for the Cloudflare Worker CORS proxy:

- Add rate limiting per IP (60 requests/minute) using Cloudflare KV
- Add file size limit (10MB max) to prevent abuse
- Add HMAC signature verification (optional, for deterrence)
- Add timestamp validation to prevent replay attacks
- Block private IP ranges (localhost, 10.x, 192.168.x, 172.16-31.x)

Client-side changes:
- Add signature generation in digital-sign-pdf.ts
- Add security warning about client-side secrets

Documentation:
- Update README with production security features
- Update docs/self-hosting/cloudflare.md with CORS proxy section
- Document KV setup for rate limiting
- Add clear warnings about client-side HMAC limitations

Files changed:
- cloudflare/cors-proxy-worker.js
- cloudflare/wrangler.toml
- src/js/logic/digital-sign-pdf.ts
- README.md
- docs/self-hosting/cloudflare.md
2026-01-05 13:44:35 +05:30
Stephan Paternotte 6e865efb2a Update tools.json
Included latest additions re. PDF Signature and Validation
2026-01-04 20:04:16 +01:00
Alam 534eb01010 Merge pull request #325 from Timmy93/main
Add italian localization
2026-01-04 19:26:51 +05:30
abdullahalam123 05110c7f6a feat: Add Digital Signature and Validate Signature tools
New Features:
- Digital Signature tool: Sign PDFs with X.509 certificates (PFX/PEM)
  - Visible and invisible signatures
  - All pages, first page, last page, or custom page selection
  - Dynamic signature height based on text content
  - Custom signature text, image, and styling options

- Validate Signature tool: Verify digital signatures in PDFs
  - Extract and parse PKCS#7 signatures
  - View signer and issuer certificate details
  - Check certificate validity and expiry
  - Optional custom X.509 certificate for trust verification
  - Full/partial coverage detection

Infrastructure:
- Added Cloudflare Worker CORS proxy for certificate chain fetching
- Updated README with new tools and proxy deployment instructions

Documentation:
- Added Digital Signature and Validate Signature to README tools table
- Added CORS proxy deployment guide for self-hosters
2026-01-04 19:09:11 +05:30
Alam 94504d4b75 Merge pull request #350 from immanuelfodor/patch-1
Fix Docker container unable to start on IPv4-only environments
2026-01-04 14:24:30 +05:30
abdullahalam123 d9561d79b9 fix: nginx.conf for docker deployment 2026-01-04 00:56:06 +05:30
abdullahalam123 771de32cf0 feat: add digital signature PDF tool
- Add new tool to apply cryptographic signatures to PDFs using X.509 certificates
- Support PKCS#12 (.pfx, .p12) and PEM certificate formats
- Create PKCS#7 detached signatures compatible with all major PDF viewers
- Optional visible signature with customizable position, image, and text overlay
- Add translations for English, German, Vietnamese, and Chinese
2026-01-03 20:47:50 +05:30
abdullahalam123 d694a674ac change: sponsors.yml 2026-01-03 14:23:45 +05:30
abdullahalam123 0914acf46e fix: add fallback for cbz to pdf for unsupported formats 2026-01-03 14:23:45 +05:30
github-actions[bot] f8b8744b7b @immanuelfodor has signed the CLA in alam00000/bentopdf#350 2026-01-02 22:41:09 +00:00
Immánuel! d6e7a89e9f Add env example to compose files 2026-01-02 23:33:26 +01:00
Immánuel! 444be0587b Fix Dockerfile env declaration 2026-01-02 23:26:24 +01:00
Immánuel! 5b7319b520 Add config option to disable Nginx IPv6 lsitener 2026-01-02 23:19:10 +01:00
abdullahalam123 55f4beb86d update:pymupdf-wasm 2026-01-02 22:47:00 +05:30
abdullahalam123 47c70b43e5 Release v1.15.4 2026-01-02 21:47:10 +05:30
abdullahalam123 c6e9e29e84 update: year 2026-01-02 21:34:39 +05:30
Raul Gonzalez f39a29e2cc fix: Rollback changes in ICLA file 2026-01-02 07:40:12 -06:00
Raul Gonzalez 2b0ddfebfe fix: add Spanish language support in URL rewrite rules 2026-01-02 07:38:29 -06:00
github-actions[bot] bfcf1f5fc3 @raulgcode has signed the CLA in alam00000/bentopdf#348 2026-01-02 13:35:10 +00:00
Raul Gonzalez 528b14f604 Sign ICLA 2026-01-02 07:27:28 -06:00
Raul Gonzalez 14afebb5f0 Add spanish translation and update documentation with missing steps 2026-01-02 07:00:27 -06:00
abdullahalam123 bddd11c07b fix(pdf-a): fix PDF/A-2b and PDF/A-3b transparency compliance
- Add post-processing step using pdf-lib to fix ISO 19005-2/3 clause 6.2.10
- Add Group dictionaries with ICC-based color space to all pages
- Fix XObjects (Form XObjects) that have DeviceRGB in their Group dictionaries
- Reference OutputIntent's ICC profile as the blending color space
- Enable page compression for smaller output files

This ensures PDFs with transparency pass VeraPDF validation for PDF/A-2b and PDF/A-3b.
2026-01-02 17:04:50 +05:30
abdullahalam123 bb42a5aec0 fix: split-pdf page range 2026-01-01 19:21:10 +05:30
abdullahalam123 c6fb46cbf2 feat: fix favicon implementation for Google search and PWA support
- Add background to favicon.svg (RGB 38,45,59)
- Generate all required PNG sizes (192x192, 512x512, 180x180)
- Create site.webmanifest with proper PWA config
- Standardize favicon links across 116 HTML files
- Fix incorrect MIME types in 50+ pages
2026-01-01 19:21:10 +05:30
abdullahalam123 2f8086ad59 refactor: centralize CDN config and fix service worker fallback
- Centralize CDN versions/URLs in cdn-version.ts
- Switch LibreOffice to @bentopdf/libreoffice-wasm package
- Fix service worker fallback to support all WASM packages
- Remove dead code and silence production logs
2026-01-01 19:21:10 +05:30
github-actions[bot] 659a4b1a32 @mafridi143 has signed the CLA in alam00000/bentopdf#338 2025-12-30 12:27:19 +00:00
abdullahalam123 13221f8bee add: funding manifest 2025-12-30 15:32:00 +05:30
abdullahalam123 f22488120b fix:xlsx vulnearability 2025-12-30 13:34:25 +05:30
abdullahalam123 34d65300d7 add:include-docs script 2025-12-30 13:27:11 +05:30
abdullahalam123 7b09956493 Merge branch 'enhance-seo' 2025-12-30 13:21:35 +05:30
abdullahalam123 5e488ac071 add: 404 page 2025-12-30 13:10:22 +05:30
Alam b1116b01c9 Merge pull request #335 from Roddy-D/main
Fix subdirectory hosting for static pages
2025-12-30 12:54:29 +05:30
abdullahalam123 4e5d747cac add: seo 2025-12-30 12:36:30 +05:30
github-actions[bot] 1ab535f873 @Roddy-D has signed the CLA in alam00000/bentopdf#335 2025-12-29 23:42:29 +00:00
Roddy 12c61a2d53 Fix subdirectory hosting for static pages 2025-12-29 18:34:31 -05:00
abdullahalam123 a77cd6380c Release v1.15.3 2025-12-29 14:59:18 +05:30
abdullahalam123 578f569c0a Release v1.15.2 2025-12-29 14:59:11 +05:30
abdullahalam123 183c1f0d7a fix: metadata 2025-12-29 14:59:11 +05:30
abdullahalam123 8bae2b662a fix: markdown to pdf spacing and added mermaid diagram support 2025-12-29 14:59:11 +05:30
github-actions[bot] b4c77acee7 @Timmy93 has signed the CLA in alam00000/bentopdf#325 2025-12-29 00:17:20 +00:00
Federico c9aa895894 Add italian localization
- Added it locale
- Add it language ro other config files (nginx.conf, vite.config.ts, i18n.ts)
2025-12-29 01:09:46 +01:00
Stephan Paternotte 704045b024 Update common.json 2025-12-28 14:05:01 +01:00
Stephan Paternotte ac0094368b Update tools.json
feat: Add VitePress docs, EPUB to PDF tool, Phosphor icons, and licensing updates
2025-12-28 13:47:08 +01:00
Stephan Paternotte c4a67b35c7 Update common.json
feat: Add VitePress docs, EPUB to PDF tool, Phosphor icons, and licensing updates
2025-12-28 13:46:22 +01:00
Alam bd6fd53d8b Merge pull request #317 from ryuupendragon/main
Add LABEL "org.opencontainers.image.url"
2025-12-28 13:18:43 +05:30
github-actions[bot] 665275be1e @ryuupendragon has signed the CLA in alam00000/bentopdf#317 2025-12-28 07:40:18 +00:00
ryuupendragon 210af94722 Add LABEL "org.opencontainers.image.url" 2025-12-28 12:58:47 +05:30
abdullahalam123 1aae928689 Release v1.15.1 2025-12-27 21:56:17 +05:30
abdullahalam123 c32fed3add Release v1.15.0 2025-12-27 21:55:41 +05:30
abdullahalam123 fe32de047e fix: docker deployment issues and update readme" -m "Fixed nginx brotli_static error, duplicates, and added COOP/COEP headers for SharedArrayBuffer. Updated README with acknowledgments 2025-12-27 21:55:40 +05:30
github-actions[bot] cd3529bf7e @matteo-genovese has signed the CLA in alam00000/bentopdf#315 2025-12-27 15:47:21 +00:00
abdullahalam123 a912ff7b09 Release v1.14.0 2025-12-27 19:59:00 +05:30
abdullahalam123 0aba1b070a Release v1.13.0 2025-12-27 19:53:30 +05:30
abdullahalam123 6fe222d3be fix: vite.config 2025-12-27 19:53:20 +05:30
abdullahalam123 24df502824 Release v1.12.0 2025-12-27 19:38:55 +05:30
abdullahalam123 f30a084fce feat: Add VitePress docs, EPUB to PDF tool, Phosphor icons, and licensing updates
- Set up VitePress documentation site (docs:dev, docs:build, docs:preview)
- Added Getting Started, Tools Reference, Contributing, and Commercial License pages
- Created self-hosting guides for Docker, Vercel, Netlify, Cloudflare, AWS, Hostinger, Nginx, Apache
- Updated README with documentation link, sponsors section, and docs contribution guide

- Added EPUB to PDF converter using LibreOffice WASM

- Migrated to Phosphor Icons for consistent iconography

- Added donation ribbon banner on landing page
- Removed 'Like My Work?' section (replaced by ribbon)
- Updated licensing.html with delivery model, AGPL notice, invoicing, and no-refund policy

- Added Commercial License documentation page
- Updated translations table (Chinese added, marked non-English as In Progress)

- Added sponsors.yml workflow for auto-generating sponsor avatars
2025-12-27 19:38:33 +05:30
github-actions[bot] 0e888743d3 @jdalrymple has signed the CLA in alam00000/bentopdf#312 2025-12-27 00:51:25 +00:00
Alam 283b02027c Fix link to STATIC-HOSTING.md in README
Updated link to Static Hosting documentation for clarity.
2025-12-26 22:09:23 +05:30
Alam aae03f3ae9 Merge pull request #307 from larryclaman/ghpages-docs
Documentation for static website hosting of BentoPDF
2025-12-26 22:00:11 +05:30
github-actions[bot] 91c7f9c246 @larryclaman has signed the CLA in alam00000/bentopdf#307 2025-12-23 22:28:52 +00:00
Larry Claman 673b1f1fa7 wrote docs 2025-12-23 17:17:02 -05:00
Alam 25656ca7b0 Merge pull request #300 from EmeraldPi/package-embedpdf
Fix: EmbedPDF package runner broken from v2 change
2025-12-23 05:32:32 +05:30
Connor Smith d40521335d Fix embedpdf package with v2 change 2025-12-22 11:12:05 -05:00
Larry Claman 8487cb7d56 Merge branch 'alam00000:main' into main 2025-12-21 09:41:34 -05:00
github-actions[bot] 6f0cdb1457 @AB527 has signed the CLA in alam00000/bentopdf#297 2025-12-21 13:52:37 +00:00
Alam 370968e199 Merge pull request #293 from Stephan-P/patch-1
Update ICLA.md
2025-12-20 21:59:34 +05:30
github-actions[bot] 2c978d974c @Stephan-P has signed the CLA in alam00000/bentopdf#293 2025-12-20 11:13:27 +00:00
Stephan Paternotte e92abc2e3b Update ICLA.md
Stephan-P
2025-12-20 12:12:25 +01:00
Stephan Paternotte 9e99cf6b77 Update i18n.ts
Added Dutch (nl) to various lists
Alphabetical order
2025-12-20 12:02:49 +01:00
Stephan Paternotte 7f5dafcd2f Create common.json
Introducing Dutch language
2025-12-20 11:55:41 +01:00
Stephan Paternotte be59c2b8ea Create tools.json
Introducing Dutch language
2025-12-20 11:54:46 +01:00
github-actions[bot] ad39335f56 @htekgulds has signed the CLA in alam00000/bentopdf#289 2025-12-19 15:25:30 +00:00
Hasan Tekgül 33e558b290 add tr lang 2025-12-19 18:17:04 +03:00
Sebastian Espei 68343a4c9a Merge remote-tracking branch 'origin/main' into pdf-to-image-direct-image 2025-12-19 02:08:06 +01:00
Larry Claman 295cfd6197 Merge branch 'alam00000:main' into main 2025-12-18 12:58:54 -05:00
github-actions[bot] 2417168fb9 @amatosg has signed the CLA in alam00000/bentopdf#284 2025-12-18 14:26:30 +00:00
Larry Claman 3a9f943832 added static.yml 2025-12-18 09:14:16 -05:00
github-actions[bot] 8c26d61a68 @alexandreforeis has signed the CLA in alam00000/bentopdf#282 2025-12-18 02:42:36 +00:00
Alexandre Reis b2e6978649 feat(i18n): add pt-BR translation 2025-12-17 23:16:58 -03:00
Alam 731434e557 Merge pull request #262 from hemantapkh/main
fix:  Absolute paths for logo and favicons
2025-12-17 11:04:39 +05:30
github-actions[bot] 6e82fa5bdf @topcu-muhammet has signed the CLA in alam00000/bentopdf#275 2025-12-17 00:25:05 +00:00
github-actions[bot] b3d43cbd42 @crstian19 has signed the CLA in alam00000/bentopdf#266 2025-12-16 08:30:36 +00:00
Alam e34996006a Merge pull request #274 from EmeraldPi/package-embedpdf
Fix edit-pdf-page.ts and revert fileHandler.ts (EmbedPDF.js snippet fix)
2025-12-16 12:05:47 +05:30
Connor Smith 71aac226ed Fix edit-pdf-page.ts and revert fileHandler.ts 2025-12-15 17:11:38 -05:00
Alam 9f99a29d83 Merge pull request #235 from EmeraldPi/package-embedpdf
Buid and package EmbedPDF.js using Github workflow
2025-12-15 15:08:13 +05:30
EmeraldPi d07d12a975 Buid and package EmbedPDF.js using Github workflow 2025-12-14 19:02:53 -05:00
github-actions[bot] 438ae4466f @Zakmaf has signed the CLA in alam00000/bentopdf#267 2025-12-14 22:39:02 +00:00
github-actions[bot] 7b5f3a3575 @mobiwise-dev has signed the CLA in alam00000/bentopdf#263 2025-12-14 16:35:45 +00:00
github-actions[bot] 3be60d36fb @hemantapkh has signed the CLA in alam00000/bentopdf#262 2025-12-14 09:42:18 +00:00
Hemanta Pokharel 49aabb7029 fix: favicon issue 2025-12-14 15:11:55 +05:45
Hemanta Pokharel 61b4cfe5df fix: broken logo path on language change 2025-12-14 14:35:26 +05:45
github-actions[bot] 319ec177bd @StanislasMzx has signed the CLA in alam00000/bentopdf#260 2025-12-13 23:53:21 +00:00
abdullahalam123 f667616107 feat(i18n): Add Vietnamese language routing support to Vite config
- Update language regex pattern to include Vietnamese (vi) locale
- Modify pagesRewritePlugin to recognize and route Vietnamese URLs
- Enable proper URL rewriting for /vi/* paths alongside existing en, de, zh routes
- Ensures Vietnamese language pages are correctly served through development server
2025-12-13 21:29:10 +05:30
abdullahalam123 bbd9742032 Release v1.11.2 2025-12-13 20:57:43 +05:30
abdullahalam123 1fe05ec59f ci: Improve Docker build workflow and update dependencies
- Add release type detection to distinguish between version tags and edge builds
- Implement separate Docker build steps for release and edge builds with appropriate tags
- Add edge and SHA-based image tags for main branch builds
- Update nginx configuration to support Vietnamese (vi) language routing
- Simplify nginx location block to handle static files and fallback to index.html
- Remove javascript-obfuscator and ts-migrate from dependencies
- Update README with simplified self-hosting instructions using npx http-server
- Consolidate multiple server setup examples into single recommended approach
- Update build preview command to use npm run preview instead of npx serve
- Improve localization files for German, English, Vietnamese, and Chinese
- Update worker files and TypeScript logic files for improved functionality
- Enhance PDF tool pages with better structure and internationalization support
2025-12-13 20:57:32 +05:30
Alam 80cfb3dc0f Merge pull request #256 from Cxllxc/main
(Bug/Feature)Add Chinese language support and fix Multi Tool localization
2025-12-13 13:02:17 +05:30
zhenyao xu 264ccd77d8 Merge branch 'main' into main 2025-12-12 19:14:25 +00:00
github-actions[bot] d8a94c1261 @Cxllxc has signed the CLA in alam00000/bentopdf#256 2025-12-12 19:11:56 +00:00
cxllxc ab122e19df feat: Add internationalization support and introduce a new PDF multi-tool. 2025-12-12 12:54:06 +00:00
cxllxc 3c0fbc8f8f at: Add Chinese language support with new i18n utilities and update routing configura 2025-12-12 12:41:40 +00:00
Alam 9de06775f3 Merge pull request #252 from tuyndoan/feat/add-vietnamese-language
feat(i18n): Add Vietnamese (Tiếng Việt) language support
2025-12-12 17:53:19 +05:30
Tuyn Doan 39e35b3282 Merge branch 'main' into feat/add-vietnamese-language 2025-12-12 08:48:47 +07:00
Tuyn Doan 6e68b08d80 feat(seo): Add Vietnamese hreflang tags to all HTML pages 2025-12-12 08:49:23 +07:00
abdullahalam123 d3fe6b2fcc chore: Refactor Dockerfile and update HTML favicon links
- Simplify Dockerfile by removing redundant BASE_URL handling logic and complex RUN commands
- Change SIMPLE_MODE default from true to false for production builds
- Fix indentation inconsistencies in Dockerfile conditional statements
- Move favicon link tags from body to head section in all HTML files for proper semantic structure
- Replace inline favicon links with img tag in navigation logo across all pages
- Update README.md documentation to clarify BASE_URL trailing slash requirements
- Remove commented-out legacy Dockerfile code for cleaner maintenance
- Consolidate favicon declarations in document head for better performance and SEO
2025-12-12 00:19:24 +05:30
Alam 9712f50fc6 Merge pull request #240 from munqsy/dockerfile-BASE_DIR-support
Added BASE_URL support to the Dockerfile
2025-12-12 00:14:46 +05:30
Alam aefa978ef2 Merge branch 'main' into dockerfile-BASE_DIR-support 2025-12-12 00:14:31 +05:30
Tuyn Doan 2834ddecee fix: Remove duplicate text in compliance.title data-i18n attribute 2025-12-12 01:12:58 +07:00
github-actions[bot] f4380efb90 @tuyndoan has signed the CLA in alam00000/bentopdf#252 2025-12-11 18:05:57 +00:00
Tuyn Doan 8c065fcdf0 feat(i18n): Add Vietnamese (Tiếng Việt) language support
- Add Vietnamese translation files (common.json and tools.json)
- Register 'vi' as a supported language in i18n configuration
- Update language switcher to support Vietnamese footer text
- Update URL routing regex to handle /vi/ paths

All 170 translation keys have been translated to Vietnamese.
Users can now access BentoPDF in Vietnamese by visiting /vi/ URLs.
2025-12-12 00:58:08 +07:00
abdullahalam123 ac31f017eb Release v1.11.1 2025-12-11 19:41:10 +05:30
abdullahalam123 6eaa7c18ea fix: Add space between consecutive data-i18n attributes in HTML files. 2025-12-11 19:40:57 +05:30
abdullahalam123 dc258f808d Release v1.11.0 2025-12-11 19:36:35 +05:30
abdullahalam123 a83d9b6604 Merge branch 'port-to-standalone-pages' 2025-12-11 19:35:28 +05:30
abdullahalam123 78dc6333f9 setup i18n and ported all tools to standalone pages 2025-12-11 19:34:14 +05:30
github-actions[bot] 79f58257dd @nabaco has signed the CLA in alam00000/bentopdf#242 2025-12-10 08:11:51 +00:00
github-actions[bot] f2e7a1a239 @munqsy has signed the CLA in alam00000/bentopdf#240 2025-12-09 13:21:31 +00:00
Michael Amann 2468962f01 Added BASE_URL support to the Dockerfile 2025-12-09 14:02:40 +01:00
github-actions[bot] ce4c464c32 @EmeraldPi has signed the CLA in alam00000/bentopdf#235 2025-12-07 20:55:43 +00:00
Alam 02075cb869 Merge pull request #225 from Akhrameev/patch-1
Change image embedding from PNG to JPEG format
2025-12-06 21:05:07 +05:30
github-actions[bot] 0d3efcaa84 @ShiranJ has signed the CLA in alam00000/bentopdf#222 2025-12-06 08:13:31 +00:00
Sebastian Espei a25ec05e17 Merge remote-tracking branch 'origin/main' into pdf-to-image-direct-image 2025-12-06 00:52:30 +01:00
github-actions[bot] 1a18a630bc @Skillkiller has signed the CLA in alam00000/bentopdf#215 2025-12-05 23:29:32 +00:00
Sebastian Espei 3d59dea821 feat(pdf-to-webp): show processing in loader message 2025-12-06 00:26:34 +01:00
Sebastian Espei 35e7281bc3 feat(pdf-to-tiff): show processing in loader message 2025-12-06 00:26:29 +01:00
Sebastian Espei 1637ed6b44 feat(pdf-to-png): show processing in loader message 2025-12-06 00:26:22 +01:00
Sebastian Espei ac32e09fe9 feat(pdf-to-jpg): show processing in loader message 2025-12-06 00:26:14 +01:00
Sebastian Espei 650ff1fca5 feat(pdf-to-bmp): add yieldToUI 2025-12-06 00:25:46 +01:00
Sebastian Espei 09c554a3e6 feat(pdf-to-jpg): fix wrong indentation 2025-12-06 00:21:03 +01:00
Sebastian Espei 9602fef1e8 feat(pdf-to-bmp): add yieldToUI 2025-12-06 00:17:15 +01:00
Sebastian Espei cc926d0b07 feat(pdf-to-bmp): update single-page processing message 2025-12-06 00:14:06 +01:00
github-actions[bot] 428cab115a @alam00000 has signed the CLA in alam00000/bentopdf#225 2025-12-05 22:37:40 +00:00
abdullahalam123 df346eb08a ci: Update CLA workflow to grant write permissions for contents and remove internal comments. 2025-12-06 04:01:01 +05:30
abdullahalam123 947a6b57c0 fix: correct CLA signatures file structure 2025-12-06 02:46:11 +05:30
Alam 9c46b4fb1a Remove content from cla.json file 2025-12-06 02:34:57 +05:30
Alam f35ed5f464 Add initial CLA JSON structure 2025-12-06 02:24:40 +05:30
Alam 529958e325 Update cla.yml 2025-12-06 02:04:01 +05:30
abdullahalam123 fe3e54f979 Release v1.10.5 2025-12-05 14:57:46 +05:30
abdullahalam123 5e23a7e77e feat: Add Contributor License Agreements (CLA) for individual and corporate contributors with automated enforcement. 2025-12-05 14:57:35 +05:30
Pavel Akhrameev e831a477d2 Change image embedding from PNG to JPEG format
using PNG increased filesize from ~60 MB to ~112 MB. That's too much. May require some "quality" parameter adjustment.
2025-12-05 04:29:40 +04:00
abdullahalam123 e0381e6aa0 Release v1.10.4 2025-12-05 00:38:15 +05:30
abdullahalam123 c682f9d9b3 fix(config): Remove leading slash from merge PDF tool path
- Remove leading slash from merge-pdf.html path in tools configuration
- Ensure consistent path resolution with BASE_URL environment variable
- Fix asset path handling for subdirectory hosting compatibility
2025-12-05 00:38:08 +05:30
abdullahalam123 a976295b4c Release v1.10.3 2025-12-04 23:57:42 +05:30
abdullahalam123 af01a041bf Release v1.10.2 2025-12-04 23:53:31 +05:30
abdullahalam123 b279c05281 feat: Add subdirectory hosting support and fix asset path resolution
- Update README with comprehensive subdirectory hosting instructions and BASE_URL configuration guide
- Convert absolute asset paths to relative paths in index.html for proper subdirectory deployment
- Update all worker script imports to use relative paths instead of absolute paths
- Fix favicon and image references to work correctly when hosted in nested directories
- Normalize whitespace and formatting across worker files for consistency
- Update vite.config.ts to properly handle BASE_URL configuration for subdirectory deployments
- Ensure all tool pages and logic files maintain compatibility with subdirectory hosting
- Enable BentoPDF to be deployed at any URL path (e.g., example.com/tools/bentopdf/) without breaking asset loading
2025-12-04 23:53:00 +05:30
abdullahalam123 19425d98f9 feat: Add JPG to PDF conversion tool with dedicated page and logic. 2025-12-04 21:21:34 +05:30
abdullahalam123 62d1b9ada2 feat: add new Edit PDF tool with dedicated page and logic, and update build configuration 2025-12-04 15:29:01 +05:30
abdullahalam123 9620084789 feat: Add dedicated compress PDF page and reimplement compression logic. 2025-12-04 14:32:37 +05:30
abdullahalam123 6676fe9f89 feat: Reimplement PDF splitting functionality on a new dedicated page. 2025-12-04 14:02:20 +05:30
abdullahalam123 fb3063324c feat: implement dedicated merge PDF tool page with new logic and UI structure 2025-12-04 12:26:57 +05:30
abdullahalam123 c79b0ae144 Release v1.10.1 2025-12-03 23:15:15 +05:30
abdullahalam123 649aec046d feat(ocr,form-creator): Add comprehensive font support and TypeScript type definitions
- Add @pdf-lib/fontkit dependency for enhanced font rendering capabilities
- Create font-mappings.ts configuration with language-to-font-family mappings for 100+ languages
- Implement font-loader.ts utility for dynamic font loading from CDN sources
- Add TypeScript type definitions for form-creator, OCR, and general application types
- Create types/index.ts as centralized type exports
- Remove hidden-on-touch CSS class and update shortcuts button styling for better accessibility
- Update OCR text layer rendering to support multilingual font families
- Enhance form-creator with improved font handling for international text
- Update txt-to-pdf with font support for diverse character sets
- Migrate fileHandler to support new font loading workflow
- Update main.ts and ui.ts to integrate new type system and font utilities
- Update form-creator.html page with enhanced font configuration UI
2025-12-03 23:13:14 +05:30
Sebastian Espei d2769a02f5 feat(pdf-to-image): simplify get clean filename 2025-12-02 22:07:25 +01:00
Sebastian Espei 3fcf9757f7 feat(pdf-to-jpg): direct download resulting image and adjust filename 2025-12-02 21:31:19 +01:00
Sebastian Espei 59510899bb Merge remote-tracking branch 'origin/main' into pdf-to-image-direct-image 2025-12-02 21:17:20 +01:00
abdullahalam123 f213d9dc27 Release v1.10.0 2025-12-01 15:15:51 +05:30
abdullahalam123 b39d2c267c Merge branch 'pdf-multi-tool-bug-fixes' 2025-12-01 14:56:09 +05:30
abdullahalam123 09436a689d feat(rotate,delete-pages): Add custom rotation angles and enhance page management UI
- Add TypeScript type definitions for merge and alternate-merge Web Workers
- Implement custom rotation angle input with increment/decrement controls for rotate tool
- Extend delete-pages tool to render page thumbnails for better UX
- Hide number input spin buttons across all number inputs via CSS
- Refactor rotateAll function to accept angle parameter instead of direction multiplier
- Update fileHandler to support delete-pages tool thumbnail rendering
- Improve type safety in alternate-merge logic with proper interface definitions
- Enhance rotate tool UI with custom angle input field and adjustment buttons
2025-12-01 14:54:46 +05:30
abdullahalam123 c5764e4172 feat(favicon,repair-pdf): Add favicon support and implement PDF repair tool
- Add favicon.ico to public directory for browser tab display
- Update favicon references across all HTML pages with proper link tags for SVG, PNG, and ICO formats
- Add Apple touch icon support for iOS devices
- Create new repair-pdf.ts logic module for PDF repair functionality
- Create new repair-pdf-page.ts utility module for page-level repair operations
- Add repair-pdf.html page with UI for PDF repair tool
- Register repair PDF tool in tools configuration and PDF tools registry
- Update UI rendering utilities to support new repair tool
- Improve favicon handling with multiple format fallbacks for cross-browser compatibility
- Standardize favicon paths to use absolute URLs for consistency
- Clean up whitespace and formatting in licensing.html for code consistency
2025-12-01 12:44:34 +05:30
Sebastian Espei f390fc92dd feat(pdf-to-png): adjust download button text 2025-12-01 00:57:21 +01:00
Sebastian Espei 2a45e26efe feat(pdf-to-png): remove misleading notice 2025-12-01 00:56:53 +01:00
Sebastian Espei 33ebcf4479 feat(pdf-to-webp): direct download resulting image and adjust filename 2025-12-01 00:56:14 +01:00
Sebastian Espei 30b16a6bf1 feat(pdf-to-tiff): direct download resulting image and adjust filename 2025-12-01 00:46:38 +01:00
Sebastian Espei b29395a011 feat(pdf-to-bmp): direct download resulting image and adjust filename 2025-11-30 23:57:04 +01:00
Sebastian Espei e5cd2e6ab5 feat(pdf-to-png): direct download resulting image and adjust filename 2025-11-30 23:45:27 +01:00
Alam 2741b29ad1 Merge pull request #177 from RJGhugo/patch-2
Update nginx.conf
2025-11-30 19:45:19 +05:30
abdullahalam123 05bc0d5a3c Release v1.9.0 2025-11-28 20:50:05 +05:30
abdullahalam123 8651ca366f feat(merge): Migrate merge operations to Web Workers and reorganize tool categories
- Create merge.worker.js and alternate-merge.worker.js for offloading PDF merge operations to background threads
- Migrate merge and alternate-merge logic to use Web Worker architecture for improved performance
- Move flatten tool from singlePdfLoadTools to multiFileTools configuration
- Update merge and alternate-merge tool subtitles to indicate bookmark preservation
- Refactor alternate-merge.ts to use Web Worker instead of pdf-lib for interleaving operations
- Refactor merge.ts to use Web Worker for standard merge operations
- Update fileHandler.ts to recognize flatten as a multi-file tool requiring process button handling
- Simplify form-creator.ts and flatten.ts implementations with Web Worker integration
- Update UI state management to support Web Worker-based PDF processing
- Improve performance by moving computationally intensive PDF operations off the main thread
2025-11-28 20:49:49 +05:30
abdullahalam123 6b7163991e feat(ui): Add GitHub integration and enhance hero section design
- Add GitHub star counter badge to navigation (desktop and mobile)
- Implement grid pattern background in hero section
- Redesign hero title with inline PDF Toolkit badge and briefcase icon
- Update feature badges styling with improved visual hierarchy
- Refactor CTA button layout with icon integration
- Add simple-mode-footer utility component for footer management
- Update all tool pages with consistent styling improvements
- Enhance responsive design for mobile navigation with GitHub link
- Improve visual consistency across all pages with updated color scheme
2025-11-26 18:33:08 +05:30
abdullahalam123 f3f6af079f Release v1.8.1 2025-11-25 14:52:41 +05:30
abdullahalam123 6e7563d0c2 fix(bookmark-pdf): Improve page reference resolution and simplify destination handling
- Refactor findPageIndex() to use multiple resolution strategies (direct ref comparison, object number matching, string representation, numeric values)
- Add resolvedPageRef parameter to findPageIndex() for more efficient page dictionary matching
- Improve named destination handling to properly extract 'D' entry from dictionary-wrapped destinations
- Remove unnecessary resolveRef() call on destination arrays to preserve array structure integrity
- Pass resolved page reference to findPageIndex() for better accuracy in page lookup
- Simplify footer markup across multiple pages (add-stamps, bookmark, form-creator, json-to-pdf, pdf-to-json, table-of-contents) by removing redundant background color and grid layout
- Enhance error handling and logging for page reference resolution diagnostics
2025-11-25 14:52:34 +05:30
abdullahalam123 b9572dfea8 Release v1.8.0 2025-11-24 22:02:43 +05:30
abdullahalam123 e8c0e82d29 feat(form-creator): Simplify date field rendering and fix PDF date actions
- Refactor date field UI rendering to use inline HTML with calendar icon and format text
- Consolidate date format and keystroke action creation by removing unnecessary widget loop
- Attach Additional Actions (AA) directly to field dictionary instead of individual widgets
- Improve code clarity and reduce redundant DOM manipulation in date field initialization
- Ensure date formatting and keystroke validation work correctly at the field level in generated PDFs
2025-11-24 21:43:33 +05:30
abdullahalam123 95927cd899 squash: feat: Create fillable PDF forms 2025-11-24 21:16:23 +05:30
abdullahalam123 1e8866018d Release v1.7.9 2025-11-21 19:32:14 +05:30
abdullahalam123 83aadb6d98 fix: enhance shortcut key detection for alt key combinations and update Discord invite link across all pages. 2025-11-21 19:32:08 +05:30
abdullahalam123 1a17cd4e7e Release v1.7.8 2025-11-21 17:11:15 +05:30
abdullahalam123 5fecc701c6 feat: Implement keyboard shortcuts system with UI management, add txt-to-pdf tests, and introduce a generic warning modal. 2025-11-21 17:10:56 +05:30
Alam 77ee986e2c Update index.html
The script that counts the number of anonymous users visiting BentoPDF's live website was added by mistake and is now removed
2025-11-20 20:14:12 +05:30
abdullahalam123 606a3603f4 Release v1.7.7 2025-11-20 19:58:46 +05:30
abdullahalam123 8a8ae3f0c5 feat: Add licensing page and FAQ script, update site content and navigation, and refine PDF tool logic for multi tool 2025-11-20 19:58:41 +05:30
abdullahalam123 092f84be23 Release v1.7.6 2025-11-20 16:23:59 +05:30
abdullahalam123 2aa26e496c feat: Add progressive rendering utilities, enhance image-to-pdf with reordering and broader type support, improve rotate tool with global rotation state 2025-11-20 16:23:36 +05:30
RJGhugo 41a35586c7 Update nginx.conf
listen [::]:8080;

Missing IPv6 plus SEMICOLONE...

https://github.com/alam00000/bentopdf/issues/136
2025-11-19 10:52:58 +01:00
abdullahalam123 900196879f Release v1.7.5 2025-11-19 13:19:21 +05:30
abdullahalam123 bd985f06f8 feat: Add alerts for attachment extraction status and improve UI state handling after processing.
feat: add page and document level support for adding atttachments
2025-11-19 13:19:14 +05:30
abdullahalam123 98467f4809 Release v1.7.4 2025-11-18 20:31:24 +05:30
abdullahalam123 151060204d feat(attachments,security): migrate attachment processing to web worker and update CORS policy
- Add web worker for PDF attachment processing to improve performance and prevent UI blocking
- Create add-attachments.worker.js with TypeScript definitions for type safety
- Implement worker message handling with success and error responses
- Update nginx.conf to use Cross-Origin-Resource-Policy instead of Cross-Origin-Embedder-Policy for better cross-origin resource sharing
- Refactor add-attachments.ts to use worker-based processing with transferable objects
- Update main.ts to add home logo click handler for navigation
- Improve error handling with worker error event listener
- Add validation checks for PDF file availability before processing attachments
2025-11-18 20:31:13 +05:30
Alam 3019195fe5 Merge pull request #176 from ildoc/feat/centralized_version
Feat/centralized version
2025-11-18 20:10:00 +05:30
ildoc 3673b6e434 updated readme 2025-11-18 12:45:38 +01:00
ildoc ad915b7527 version fetched from package.json 2025-11-18 12:35:12 +01:00
abdullahalam123 bbafb11246 Release v1.7.3 2025-11-18 11:15:40 +05:30
abdullahalam123 e33e79ef4d Release v1.7.2 2025-11-18 11:13:48 +05:30
abdullahalam123 1e557d5b2a feat(security,build): add COOP/COEP headers and improve PDF viewer initialization
- Add Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers to nginx.conf for enhanced security
- Create serve.json configuration file with security headers for local development
- Update npm scripts to use vite preview instead of serve package for consistency
- Fix PDF viewer file parameter handling to prevent fallback to default URL
- Enable annotation editor mode by default in PDF viewers (annotationEditorMode: 1)
- Improve PDF preference management by clearing conflicting annotation editor settings before loading
- Update iframe URL construction to use URL API for proper origin handling
- Refactor annotation viewer setup to use eventBus for stamp button activation instead of direct DOM manipulation
- Add localStorage preference configuration for signature editor and permissions in sign tool
- Enhance security posture by implementing COOP/COEP headers required for SharedArrayBuffer and cross-origin isolation
2025-11-18 11:13:03 +05:30
4114 changed files with 689067 additions and 32705 deletions
+2
View File
@@ -0,0 +1,2 @@
# Dev-only: route TSA/certificate requests through the built-in Vite CORS proxy
VITE_CORS_PROXY_URL=/cors-proxy
+33
View File
@@ -0,0 +1,33 @@
# BentoPDF Environment Variables
# Copy this file to .env.production and configure as needed.
# CORS Proxy for digital signature certificate chain fetching
VITE_CORS_PROXY_URL=
VITE_CORS_PROXY_SECRET=
# WASM Module URLs
# Pre-configured defaults enable advanced PDF features out of the box.
# For air-gapped / offline deployments, point these to your internal server (e.g., /wasm/pymupdf/).
VITE_WASM_PYMUPDF_URL=https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/
VITE_WASM_GS_URL=https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/assets/
VITE_WASM_CPDF_URL=https://cdn.jsdelivr.net/npm/[email protected]/dist/
# OCR assets (optional)
# Set all three together for self-hosted or air-gapped OCR.
# Leave empty to use Tesseract.js runtime defaults.
VITE_TESSERACT_WORKER_URL=
VITE_TESSERACT_CORE_URL=
VITE_TESSERACT_LANG_URL=
VITE_TESSERACT_AVAILABLE_LANGUAGES=
VITE_OCR_FONT_BASE_URL=
# Default UI language (build-time)
# Supported: en, ar, be, fr, de, es, zh, zh-TW, vi, tr, id, it, pt, nl, da, ko, sv, ru
VITE_DEFAULT_LANGUAGE=
# Custom branding (build-time)
# Replace the default BentoPDF branding with your own.
# Place your logo file in the public/ folder and set the path relative to it.
VITE_BRAND_NAME=
VITE_BRAND_LOGO=
VITE_FOOTER_TEXT=
@@ -1,80 +0,0 @@
---
name: '🐛 Bug / 💡 Feature / ❓ Question'
about: 'Report a bug, request a feature, or ask a question about BentoPDF'
title: '(Bug) <short title>, (Feature) <short title>, or (Question) <short title>'
labels: ['needs triage']
assignees: []
---
## Type of Issue
Please check one:
- [ ] 🐛 Bug Report <!-- Label: bug -->
- [ ] 💡 Feature Request <!-- Label: feature -->
- [ ] ❓ Question / Help <!-- Label: question -->
---
## Description
Provide a clear and concise description of the issue, feature request, or question.
---
## Steps to Reproduce (for Bugs)
1. Go to '...'
2. Run '...'
3. Observe error: '...'
**Expected Behavior:**
Describe what you expected BentoPDF to do.
**Actual Behavior:**
Describe what actually happened, including error messages.
---
## Feature Request Details (if applicable)
- What functionality are you requesting?
- Why is this useful?
- Any example or context to illustrate it?
---
## Question Details (if applicable)
- What is your question?
- What have you tried so far?
- Any relevant code snippet or scenario?
---
## Screenshots / Logs (if applicable)
Attach any screenshots, logs, or stack traces that help explain the problem or question.
---
## Environment
- **OS:** (e.g., macOS 14.0 / Ubuntu 22.04 / Windows 11)
- **Dependencies / setup details (if any):**
---
## 💭 Additional Context
Any other information, suggestions, or references that might help maintainers.
---
✅ **Title Format Reminder:**
- `(Bug) Text alignment incorrect on multi-line paragraphs`
- `(Feature) Add support for custom PDF metadata`
- `(Question) How to embed custom fonts?`
---
+122
View File
@@ -0,0 +1,122 @@
name: 🐛 Bug Report
description: Report a bug in BentoPDF
title: "(Bug) "
labels: ["bug", "needs triage"]
body:
- type: markdown
attributes:
value: |
## ⚠️ Important Notice
**Bug reports without logs or a sample file demonstrating the issue will not be investigated.**
Please help us help you by providing the information needed to reproduce and fix the problem.
- type: textarea
id: description
attributes:
label: Description
description: Provide a clear and concise description of the bug.
placeholder: What happened? What did you expect to happen?
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: How can we reproduce this issue?
placeholder: |
1. Go to '...'
2. Click on '...'
3. Upload file '...'
4. See error
validations:
required: true
- type: textarea
id: console-logs
attributes:
label: Console Logs
description: Open browser DevTools (F12 → Console tab) and paste any errors here.
placeholder: Paste console logs here...
render: shell
validations:
required: true
- type: textarea
id: sample-file
attributes:
label: Sample PDF or File
description: |
Attach a sample PDF that reproduces the issue, or describe how to create one.
If you cannot share the original, create a minimal example that shows the problem.
placeholder: Drag and drop your file here, or describe how to reproduce with any PDF...
validations:
required: true
- type: dropdown
id: browser
attributes:
label: Browser
description: Which browser are you using?
options:
- Chrome
- Firefox
- Safari
- Edge
- Brave
- Other
validations:
required: true
- type: input
id: browser-version
attributes:
label: Browser Version
description: e.g., Chrome 120, Firefox 121
placeholder: "120"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
options:
- macOS
- Windows
- Linux
- iOS
- Android
- Other
validations:
required: true
- type: input
id: bentopdf-version
attributes:
label: BentoPDF Version
description: Check the footer or package.json
placeholder: "1.15.4"
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Any other information that might help us debug this issue.
placeholder: Screenshots, network errors, stack traces, etc.
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: Pre-submission Checklist
options:
- label: I have included console logs from the browser DevTools
required: true
- label: I have attached a sample file or described how to reproduce the issue
required: true
- label: I have searched existing issues to ensure this is not a duplicate
required: true
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Discord Community
url: https://discord.gg/Bgq3Ay3f2w
about: Join our Discord for quick questions and community support
- name: 📖 Documentation
url: https://github.com/nicholaschen09/BentoPDF#readme
about: Check the README for setup and usage instructions
@@ -0,0 +1,39 @@
name: 💡 Feature Request
description: Suggest a new feature for BentoPDF
title: "(Feature) "
labels: ["enhancement", "needs triage"]
body:
- type: textarea
id: description
attributes:
label: Feature Description
description: What functionality are you requesting?
placeholder: Describe the feature you'd like to see...
validations:
required: true
- type: textarea
id: use-case
attributes:
label: Use Case
description: Why is this feature useful? What problem does it solve?
placeholder: Explain why you need this feature...
validations:
required: true
- type: textarea
id: examples
attributes:
label: Examples
description: Any examples, mockups, or references to illustrate the feature?
placeholder: Links to similar features, screenshots, etc.
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Any other information about the feature request.
validations:
required: false
+30
View File
@@ -0,0 +1,30 @@
name: ❓ Question
description: Ask a question about BentoPDF
title: "(Question) "
labels: ["question"]
body:
- type: textarea
id: question
attributes:
label: Question
description: What would you like to know?
placeholder: Your question here...
validations:
required: true
- type: textarea
id: tried
attributes:
label: What have you tried?
description: What solutions have you already attempted?
placeholder: Describe what you've tried so far...
validations:
required: false
- type: textarea
id: context
attributes:
label: Additional Context
description: Any relevant code snippets, screenshots, or scenarios.
validations:
required: false
+18
View File
@@ -0,0 +1,18 @@
{
"name": "BentoPDF CLA",
"text": [
"Thank you for your contribution to BentoPDF!",
"",
"By signing this CLA, you agree to the terms of our Contributor License Agreement.",
"",
"**Individual Contributors**: Please review and sign our [Individual CLA (ICLA)](ICLA.md)",
"",
"**Corporate Contributors**: If you are contributing on behalf of your employer, please have your organization sign our [Corporate CLA (CCLA)](CCLA.md) by contacting [email protected]"
],
"notes": {
"purpose": "This CLA enables BentoPDF's dual licensing model (AGPL-3.0 + commercial license)",
"icla_url": "https://github.com/alam00000/bentopdf/blob/main/ICLA.md",
"ccla_url": "https://github.com/alam00000/bentopdf/blob/main/CCLA.md",
"contact": "[email protected]"
}
}
+28
View File
@@ -0,0 +1,28 @@
name: BentoPDF CodeQL config
paths-ignore:
- dist
- dist-test
- coverage
- node_modules
- vendor
- bentopdf-pymupdf-wasm
- libreoffice-wasm-package
- bentopdf-airgap-bundle
- public/pdfjs-viewer
- public/pdfjs-annotation-viewer
- public/libreoffice-wasm
- public/coherentpdf.browser.min.js
- public/workers
- public/embedpdf
- docs/.vitepress
- '**/*.min.js'
- '**/*.d.ts'
query-filters:
- exclude:
id: js/log-injection
- exclude:
id: js/tainted-format-string
- exclude:
id: js/file-system-race
+5
View File
@@ -13,3 +13,8 @@ updates:
directory: '/' directory: '/'
schedule: schedule:
interval: 'daily' interval: 'daily'
- package-ecosystem: 'docker'
directory: '/'
schedule:
interval: 'weekly'
+1
View File
@@ -33,6 +33,7 @@ Please describe **how you tested your changes** so that maintainers can verify t
### Checklist: ### Checklist:
- [ ] I have signed the [Contributor License Agreement (CLA)](ICLA.md) or my organization has signed the [Corporate CLA](CCLA.md)
- [ ] My code follows the style guidelines of this project - [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code - [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have commented my code, particularly in hard-to-understand areas
+243 -32
View File
@@ -12,21 +12,26 @@ jobs:
# New job to build dist and create release # New job to build dist and create release
build-and-release: build-and-release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') if: github.repository == 'alam00000/bentopdf' && startsWith(github.ref, 'refs/tags/')
permissions: permissions:
contents: write contents: write
env:
HUSKY: 0
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: "20" node-version: "20"
- name: Install dependencies - name: Install dependencies
run: npm ci run: npm ci
- name: Run tests
run: npm run test:run
- name: Build distribution - name: Build distribution
run: npm run build run: npm run build
@@ -40,19 +45,23 @@ jobs:
run: npm run package run: npm run package
- name: Create GitHub Release - name: Create GitHub Release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
with: with:
files: dist-${{ steps.version.outputs.version }}.zip files: |
dist-${{ steps.version.outputs.version }}.zip
dist-simple-${{ steps.version.outputs.version }}.zip
generate_release_notes: true generate_release_notes: true
draft: false draft: false
prerelease: false prerelease: false
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker-build-and-push: # Build each platform natively in parallel, then merge manifests
build-amd64:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'alam00000/bentopdf'
permissions: permissions:
contents: write contents: read
packages: write packages: write
strategy: strategy:
matrix: matrix:
@@ -67,50 +76,252 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@v3 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version from tag - name: Extract version
id: version id: version
run: | run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then if [[ $GITHUB_REF == refs/tags/v* ]]; then
VERSION=${GITHUB_REF#refs/tags/} VERSION=${GITHUB_REF#refs/tags/}
echo "version=${VERSION}" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
else else
echo "version=latest" >> $GITHUB_OUTPUT SHORT_SHA=${GITHUB_SHA::7}
echo "version_without_v=latest" >> $GITHUB_OUTPUT echo "version=edge" >> $GITHUB_OUTPUT
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
fi fi
- name: Build and push ${{ matrix.mode.name }} image - name: Build and push amd64 ${{ matrix.mode.name }} (release)
uses: docker/build-push-action@v6 if: steps.version.outputs.is_release == 'true'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with: with:
push: true push: true
build-args: | build-args: |
SIMPLE_MODE=${{ matrix.mode.simple_mode }} SIMPLE_MODE=${{ matrix.mode.simple_mode }}
tags: | tags: |
bentopdf/bentopdf${{ matrix.mode.suffix }}:latest ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64
bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} platforms: linux/amd64
bentopdf/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} no-cache: true
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} - name: Build and push amd64 ${{ matrix.mode.name }} (edge)
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} if: steps.version.outputs.is_release == 'false'
platforms: linux/amd64,linux/arm64 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
cache-from: type=gha with:
cache-to: type=gha,mode=max push: true
build-args: |
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
tags: |
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64
platforms: linux/amd64
cache-from: type=gha,scope=amd64-${{ matrix.mode.name }}
cache-to: type=gha,mode=max,scope=amd64-${{ matrix.mode.name }}
build-arm64:
runs-on: ubuntu-24.04-arm # Native ARM64 runner
permissions:
contents: read
packages: write
strategy:
matrix:
mode:
- name: default
simple_mode: false
suffix: ""
- name: simple
simple_mode: true
suffix: "-simple"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version
id: version
run: |
if [[ $GITHUB_REF == refs/tags/v* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
else
SHORT_SHA=${GITHUB_SHA::7}
echo "version=edge" >> $GITHUB_OUTPUT
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
fi
- name: Build and push arm64 ${{ matrix.mode.name }} (release)
if: steps.version.outputs.is_release == 'true'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
tags: |
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
platforms: linux/arm64
no-cache: true
- name: Build and push arm64 ${{ matrix.mode.name }} (edge)
if: steps.version.outputs.is_release == 'false'
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
push: true
build-args: |
SIMPLE_MODE=${{ matrix.mode.simple_mode }}
tags: |
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
platforms: linux/arm64
cache-from: type=gha,scope=arm64-${{ matrix.mode.name }}
cache-to: type=gha,mode=max,scope=arm64-${{ matrix.mode.name }}
# Merge GHCR manifests after both platforms are built
merge-manifests-ghcr:
runs-on: ubuntu-latest
needs: [build-amd64, build-arm64]
permissions:
packages: write
strategy:
matrix:
mode:
- name: default
suffix: ""
- name: simple
suffix: "-simple"
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version
id: version
run: |
if [[ $GITHUB_REF == refs/tags/v* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
else
SHORT_SHA=${GITHUB_SHA::7}
echo "version=edge" >> $GITHUB_OUTPUT
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
fi
- name: Create and push GHCR manifest (release)
if: steps.version.outputs.is_release == 'true'
run: |
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:latest \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
- name: Create and push GHCR manifest (edge)
if: steps.version.outputs.is_release == 'false'
run: |
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
docker buildx imagetools create -t ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
# Copy images from GHCR to DockerHub
push-to-dockerhub:
runs-on: ubuntu-latest
needs: [merge-manifests-ghcr]
continue-on-error: true
permissions:
contents: read
packages: read
strategy:
matrix:
mode:
- name: default
suffix: ""
- name: simple
suffix: "-simple"
steps:
- name: Login to GitHub Container Registry
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@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Extract version
id: version
run: |
if [[ $GITHUB_REF == refs/tags/v* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_without_v=${VERSION#v}" >> $GITHUB_OUTPUT
echo "is_release=true" >> $GITHUB_OUTPUT
else
SHORT_SHA=${GITHUB_SHA::7}
echo "version=edge" >> $GITHUB_OUTPUT
echo "short_sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
echo "is_release=false" >> $GITHUB_OUTPUT
fi
- name: Copy images to DockerHub (release)
if: steps.version.outputs.is_release == 'true'
run: |
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:latest \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version_without_v }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:${{ steps.version.outputs.version }}-arm64
- name: Copy images to DockerHub (edge)
if: steps.version.outputs.is_release == 'false'
run: |
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:edge \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
docker buildx imagetools create -t bentopdfteam/bentopdf${{ matrix.mode.suffix }}:sha-${{ steps.version.outputs.short_sha }} \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-amd64 \
ghcr.io/${{ github.repository_owner }}/bentopdf${{ matrix.mode.suffix }}:edge-arm64
+76
View File
@@ -0,0 +1,76 @@
name: "CLA Assistant"
on:
issue_comment:
types: [created]
pull_request_target:
types: [opened, closed, synchronize]
# Permissions needed for the workflow
permissions:
actions: write
contents: write
pull-requests: write
jobs:
cla-check:
runs-on: ubuntu-latest
if: >
github.event_name == 'pull_request_target' ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
(
github.event.comment.body == 'recheck' ||
github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA'
)
)
steps:
- name: "CLA Assistant"
uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_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: 'cla-signatures'
# Allowlist for bot accounts (won't need to sign CLA)
allowlist: 'bot*,*[bot],dependabot*,renovate*,github-actions*'
# Custom messages
custom-notsigned-prcomment: |
## CLA Signature Required
Thank you for your contribution! Before we can accept your pull request, you need to sign our [Contributor License Agreement (CLA)](https://github.com/${{ github.repository }}/blob/main/ICLA.md).
### Why do we need a CLA?
BentoPDF uses a dual licensing model (AGPL-3.0 for open source + commercial license). The CLA allows us to:
- Include your contributions in both open source and commercial versions
- Protect you and us legally
- Keep the project sustainable
### How to sign
To sign the CLA, please comment on this PR with:
```
I have read the CLA Document and I hereby sign the CLA
```
**For corporate contributions**, please have your organization sign our [Corporate CLA (CCLA)](https://github.com/${{ github.repository }}/blob/main/CCLA.md) by contacting us at [email protected].
---
⚠️ **Note**: You only need to sign the CLA once. Future contributions to this repository will not require re-signing.
custom-pr-sign-comment: 'I have read the CLA Document and I hereby sign the CLA'
# Lock PR while waiting for CLA signature
lock-pullrequest-aftermerge: false
# Use issues to store signatures (alternative to branch storage)
use-dco-flag: false
+41
View File
@@ -0,0 +1,41 @@
name: CodeQL
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1'
permissions:
contents: read
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
fail-fast: false
matrix:
language: [javascript-typescript]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-extended
config-file: ./.github/codeql-config.yml
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: /language:${{ matrix.language }}
@@ -0,0 +1,59 @@
name: Update Docker Downloads Badge
on:
schedule:
- cron: '17 4 * * 1'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: docker-downloads-badge
cancel-in-progress: false
jobs:
update:
if: github.repository == 'alam00000/bentopdf'
runs-on: ubuntu-latest
steps:
- name: Sum GHCR download counts
id: counts
run: |
set -euo pipefail
total=0
for pkg in bentopdf bentopdf-simple; do
raw=$(curl -sf --retry 3 --retry-delay 5 --max-time 30 \
"https://ghcr-badge.elias.eu.org/api/alam00000/bentopdf/$pkg" \
| jq -e -r '.downloadCountRaw')
case "$raw" in ''|*[!0-9]*) echo "::error::invalid count for $pkg: $raw"; exit 1 ;; esac
echo "$pkg: $raw"
total=$((total + raw))
done
if [ "$total" -le 0 ]; then echo "::error::total is zero"; exit 1; fi
message=$(awk -v n="$total" 'BEGIN{
if (n >= 1000000) printf "%.1fM", n/1000000;
else if (n >= 1000) printf "%.1fk", n/1000;
else printf "%d", n
}')
echo "total=$total" >> "$GITHUB_OUTPUT"
echo "message=$message" >> "$GITHUB_OUTPUT"
echo "combined: $total -> $message"
- name: Publish badge JSON to badges branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MESSAGE: ${{ steps.counts.outputs.message }}
run: |
set -euo pipefail
mkdir badges && cd badges
jq -n --arg message "$MESSAGE" \
'{schemaVersion: 1, label: "Docker Downloads", message: $message, color: "blue", namedLogo: "docker"}' \
> docker-downloads.json
cat docker-downloads.json
git init -q -b badges
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add docker-downloads.json
git commit -qm "chore: update docker downloads badge ($MESSAGE)"
git push -qf "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" badges
+35
View File
@@ -0,0 +1,35 @@
name: SEO audit
on:
pull_request:
paths:
- '**/*.html'
- 'public/locales/**'
- 'scripts/**'
- 'translations/**'
- 'docs/**'
- 'src/partials/**'
- 'package.json'
- 'package-lock.json'
- 'vite.config.ts'
jobs:
audit:
runs-on: ubuntu-latest
env:
HUSKY: 0
SITE_URL: https://www.bentopdf.com
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: SEO audit
run: npm run seo-audit
+30
View File
@@ -0,0 +1,30 @@
name: Update Sponsors
on:
workflow_dispatch:
schedule:
- cron: '0 6 * * 1'
permissions:
contents: read
jobs:
update:
runs-on: ubuntu-latest
if: github.repository == 'alam00000/bentopdf'
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: JamesIves/github-sponsors-readme-action@02650b8cd445fc16dfef73195f9c406dce041623 # v1.6.1
with:
token: ${{ secrets.SPONSORS_TOKEN }}
file: 'README.md'
active-only: false
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
commit-message: 'docs: update sponsors'
title: 'docs: update sponsors'
body: Updates the sponsors list in the README from GitHub Sponsors.
branch: chore/update-sponsors
delete-branch: true
+68
View File
@@ -0,0 +1,68 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
# Configure these variables under your repo settings.
# You will likely need to set BASE_URL to be the name of your repo eg 'bentopdf'
env:
SIMPLE_MODE: ${{ vars.SIMPLE_MODE }}
BASE_URL: ${{ vars.BASE_URL }}/
SITE_URL: ${{ vars.SITE_URL }}
ALLOW_INDEXING: ${{ vars.ALLOW_INDEXING }}
HUSKY: 0
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Build distribution
run: |
# export SIMPLE_MODE=${{ vars.SIMPLE_MODE }}
# export BASE_URL=${{ vars.BASE_URL }}/
npm run build
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: dist
name: github-pages-deployment
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
with:
artifact_name: github-pages-deployment
+36
View File
@@ -0,0 +1,36 @@
name: Tests
on:
push:
branches:
- 'main'
pull_request:
workflow_dispatch:
concurrency:
group: tests-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
env:
HUSKY: 0
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Typecheck
run: npx tsc --noEmit
- name: Run tests
run: npm run test:run
+102
View File
@@ -0,0 +1,102 @@
name: Trivy Security Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1'
workflow_dispatch:
permissions:
contents: read
security-events: write
jobs:
scan-image:
runs-on: ubuntu-latest
strategy:
matrix:
image:
- name: bentopdf
file: Dockerfile
- name: bentopdf-nonroot
file: Dockerfile.nonroot
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Build image for scanning
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
with:
context: .
file: ${{ matrix.image.file }}
push: false
load: true
tags: ${{ matrix.image.name }}:scan
no-cache: true
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
image-ref: ${{ matrix.image.name }}:scan
format: sarif
output: trivy-${{ matrix.image.name }}.sarif
severity: CRITICAL,HIGH
exit-code: '1'
- name: Upload Trivy results to GitHub Security
uses: github/codeql-action/upload-sarif@v4
if: always() && hashFiles('trivy-*.sarif') != ''
with:
sarif_file: trivy-${{ matrix.image.name }}.sarif
category: trivy-${{ matrix.image.name }}
scan-dependencies:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Scan npm dependencies with Trivy
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
format: sarif
output: trivy-deps.sarif
severity: CRITICAL,HIGH
scanners: vuln
- name: Upload dependency scan results
uses: github/codeql-action/upload-sarif@v4
if: always() && hashFiles('trivy-deps.sarif') != ''
with:
sarif_file: trivy-deps.sarif
category: trivy-dependencies
scan-config:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Scan Dockerfiles for misconfigurations
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: config
scan-ref: .
format: sarif
output: trivy-config.sarif
severity: CRITICAL,HIGH
- name: Upload config scan results
uses: github/codeql-action/upload-sarif@v4
if: always() && hashFiles('trivy-config.sarif') != ''
with:
sarif_file: trivy-config.sarif
category: trivy-config
@@ -0,0 +1,270 @@
name: Update PDF Engine and Viewer
on:
workflow_dispatch:
schedule:
- cron: '17 4 * * *'
permissions:
contents: read
concurrency:
group: update-engine
cancel-in-progress: false
env:
FORK_URL: https://github.com/alam00000/bentopdf-pdfium-viewer
HUSKY: 0
jobs:
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
run: |
if [ -f vendor/bentopdf-viewer/.upstream-version ]; then
echo "version=$(cat vendor/bentopdf-viewer/.upstream-version)" >> "$GITHUB_OUTPUT"
else
echo "version=" >> "$GITHUB_OUTPUT"
fi
- name: Read fork HEAD
id: upstream
run: echo "version=$(git ls-remote "$FORK_URL" refs/heads/main | cut -c1-12)" >> "$GITHUB_OUTPUT"
- name: Should update?
id: gate
env:
CURRENT: ${{ steps.current.outputs.version }}
UPSTREAM: ${{ steps.upstream.outputs.version }}
run: |
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 $CURRENT."
else
echo "run=true" >> "$GITHUB_OUTPUT"
echo "Updating $CURRENT -> $UPSTREAM"
fi
- name: Setup Node
if: steps.gate.outputs.run == 'true'
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Enable corepack (pnpm)
if: steps.gate.outputs.run == 'true'
run: corepack enable
- name: Clone the viewer fork
if: steps.gate.outputs.run == 'true'
run: git clone --depth 1 --branch main "$FORK_URL" ./_fork
- name: Require a published engine
if: steps.gate.outputs.run == 'true'
run: |
test -s ./_fork/packages/pdfium/src/vendor/pdfium.wasm
test -s ./_fork/packages/pdfium/src/vendor/pdfium.js
- name: Pack the engine
if: steps.gate.outputs.run == 'true'
id: engine
env:
SHA: ${{ steps.gate.outputs.version }}
run: |
set -euo pipefail
VENDOR=./_fork/packages/pdfium/src/vendor
STAGE=$(mktemp -d)/package
mkdir -p "$STAGE"
cp "$VENDOR/pdfium.js" "$STAGE/editcore.js"
cp "$VENDOR/pdfium.wasm" "$STAGE/editcore.wasm"
cat > "$STAGE/package.json" <<JSON
{
"name": "bentopdf-pdfium",
"version": "0.0.0-$SHA",
"type": "module",
"main": "editcore.js",
"exports": { ".": "./editcore.js", "./editcore.wasm": "./editcore.wasm" },
"license": "AGPL-3.0"
}
JSON
mkdir -p vendor/bentopdf-pdfium
OUT="vendor/bentopdf-pdfium/bentopdf-pdfium-$SHA.tgz"
tar -czf "$OUT" -C "$(dirname "$STAGE")" package
find vendor/bentopdf-pdfium -maxdepth 1 -name 'bentopdf-pdfium*.tgz' ! -name "$(basename "$OUT")" -delete
echo "tarball=$OUT" >> "$GITHUB_OUTPUT"
- name: Build the viewer
if: steps.gate.outputs.run == 'true'
working-directory: ./_fork
run: |
pnpm install --no-frozen-lockfile
pnpm run build:snippet
- 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
WORK=$(mktemp -d)
(cd ./_fork && npm pack ./viewers/snippet --pack-destination "$WORK" >/dev/null)
TMP=$(mktemp -d)
tar -xzf "$WORK"/*.tgz -C "$TMP"
rm -f "$TMP/package/dist/pdfium.wasm"
PKG="$TMP/package/package.json" node - <<'NODE'
const fs = require('fs');
const p = process.env.PKG;
const pkg = JSON.parse(fs.readFileSync(p, 'utf8'));
pkg.name = 'bentopdf-viewer';
pkg.dependencies = pkg.dependencies || {};
// The rollup bundle inlines every @embedpdf/* package, so these
// declared deps would only pull unused copies from upstream npm.
for (const k of Object.keys(pkg.dependencies)) {
if (k.startsWith('@embedpdf/')) delete pkg.dependencies[k];
if (k === 'preact') pkg.dependencies[k] = '^10.17.0';
}
fs.writeFileSync(p, JSON.stringify(pkg, null, 2) + '\n');
NODE
mkdir -p vendor/bentopdf-viewer
OUT="vendor/bentopdf-viewer/bentopdf-viewer-$SHA.tgz"
tar -czf "$OUT" -C "$TMP" package
find vendor/bentopdf-viewer -maxdepth 1 -name 'bentopdf-viewer-*.tgz' ! -name "$(basename "$OUT")" -delete
echo "tarball=$OUT" >> "$GITHUB_OUTPUT"
- 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.env.ENGINE_TARBALL;
pkg.dependencies['bentopdf-viewer'] = 'file:' + process.env.VIEWER_TARBALL;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
- name: Cleanup upstream clone
if: steps.gate.outputs.run == 'true'
run: rm -rf ./_fork
- name: Install and verify one shared engine
if: steps.gate.outputs.run == 'true'
run: |
set -euo pipefail
npm install
test -s node_modules/bentopdf-pdfium/editcore.wasm
if find node_modules/bentopdf-viewer -name '*.wasm' | grep -q .; then
echo "::error::viewer package still ships a wasm; the engine would be duplicated"
exit 1
fi
if ! grep -q "bentopdf-pdfium/editcore.wasm" src/js/logic/edit-pdf-page.ts; then
echo "::error::the PDF editor no longer points at the shared engine"
exit 1
fi
echo "engine sha256: $(sha256sum node_modules/bentopdf-pdfium/editcore.wasm | cut -c1-16)"
- name: Typecheck and test
if: steps.gate.outputs.run == 'true'
run: |
npx tsc --noEmit
npm run test:run
- name: Write upstream marker
if: steps.gate.outputs.run == 'true'
env:
SHA: ${{ steps.gate.outputs.version }}
run: |
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
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
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
`${{ 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`
- `bentopdf-viewer` — the snippet bundle, packed **without** `dist/pdfium.wasm`
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
+35
View File
@@ -11,6 +11,10 @@ node_modules
dist dist
dist-ssr dist-ssr
*.local *.local
.npm-cache
.env
.env.production
.env.local
# Editor directories and files # Editor directories and files
.vscode/* .vscode/*
@@ -26,3 +30,34 @@ dist-ssr
coverage/ coverage/
*.lcov *.lcov
# Generated sitemap
public/sitemap.xml
# Generated by scripts/generate-security-headers.mjs at build time
security-headers.conf
# CodeQL local scan artifacts (npm run security:codeql)
codeql-db/
codeql-results.sarif
codeql-results.csv
#backup
.seo-backup
libreoffice-wasm-package
# helm chart
/bentopdf-*.tgz
# test
dist-test
test
# Sibling checkouts of the engine/viewer forks
bentopdf-pdfium-viewer/
bentopdf-pymupdf-wasm/
/blog/*.html
!/blog/author-alam.html
/src/partials/tool-links-static.html
/security-headers-docs.conf
/dist-*.zip
/docs/.vitepress/cache/
+145
View File
@@ -0,0 +1,145 @@
RewriteEngine On
RewriteBase /
# ============================================
# 1. SECURITY HEADERS (UPDATED FOR CDN COMPATIBILITY)
# ============================================
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
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/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
<FilesMatch "\.map$">
Require all denied
</FilesMatch>
# ============================================
# 2. BROWSER CACHING
# ============================================
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/ttf "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/wasm "access plus 1 year"
ExpiresByType application/gzip "access plus 1 year"
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
# ============================================
# 3. COMPRESSION (STANDARD)
# ============================================
SetEnvIfNoCase Request_URI "\.gz$" no-gzip
SetEnvIfNoCase Request_URI "\.br$" no-gzip
SetEnvIfNoCase Request_URI "\.wasm$" no-gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/woff
AddOutputFilterByType DEFLATE font/ttf
</IfModule>
# ============================================
# 4. MIME TYPES & SPECIAL FILE HANDLING
# ============================================
AddType application/javascript .js .mjs
AddType application/wasm .wasm
AddType font/woff2 .woff2
AddType font/woff .woff
AddType image/webp .webp
<FilesMatch "soffice\.wasm\.gz$">
ForceType application/wasm
Header set Content-Encoding "gzip"
Header set Cross-Origin-Resource-Policy "cross-origin"
Header append Vary Accept-Encoding
</FilesMatch>
<FilesMatch "soffice\.data\.gz$">
ForceType application/octet-stream
Header set Content-Encoding "gzip"
Header append Vary Accept-Encoding
</FilesMatch>
# ============================================
# 5. REDIRECTS & ROUTING
# ============================================
# Canonical WWW
RewriteCond %{HTTP_HOST} ^bentopdf\.com [NC]
RewriteRule ^(.*)$ https://www.bentopdf.com/$1 [L,R=301]
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Remove trailing slash (except for language root directories)
RewriteCond %{REQUEST_FILENAME} !-d
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]
# Existing files/dirs - serve directly
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# ============================================
# 5.1. LANGUAGE ROUTES (MUST BE BEFORE .html extension rule)
# ============================================
# English prefix redirects to root
RewriteRule ^en/?$ / [R=301,L]
RewriteRule ^en/(.+)$ /$1 [R=301,L]
# Language prefix root (e.g., /de/ -> /de/index.html)
RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f
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 ^(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)
# ============================================
RewriteCond %{REQUEST_URI} ^/docs
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [L]
# ============================================
# 6. ADD .HTML EXTENSION IF FILE EXISTS (ROOT LEVEL ONLY)
# ============================================
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^/]+)$ $1.html [L]
# ============================================
# 7. ERROR PAGES
# ============================================
ErrorDocument 404 /404.html
+1
View File
@@ -0,0 +1 @@
npx lint-staged
+11
View File
@@ -0,0 +1,11 @@
# Handlebars partials with template syntax inside HTML attributes
src/partials/footer.html
blog/posts/
public/pdfjs-viewer/
public/pdfjs-annotation-viewer/
translations/source.json
translations/pages.json
translations/ui-source.json
+5
View File
@@ -0,0 +1,5 @@
DS-0002
KSV-0125
DS-0013
+1
View File
@@ -0,0 +1 @@
https://www.bentopdf.com/funding.json
+176
View File
@@ -0,0 +1,176 @@
<!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>404 - Page Not Found | BentoPDF</title>
<meta
name="description"
content="Oops! The page you're looking for doesn't exist. Return to BentoPDF's homepage to access our free PDF tools."
/>
<meta name="robots" content="noindex, nofollow" />
<!-- Canonical URL -->
<link rel="canonical" href="https://www.bentopdf.com/404" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/404" />
<meta property="og:title" content="404 - Page Not Found | BentoPDF" />
<meta
property="og:description"
content="The page you're looking for doesn't exist."
/>
<meta property="og:site_name" content="BentoPDF" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="404 - Page Not Found" />
<meta
name="twitter:description"
content="The page you're looking for doesn't exist."
/>
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.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="antialiased bg-gray-900 text-gray-300">
{{> navbar }}
<div id="app" class="min-h-screen container mx-auto p-4 md:p-8">
<section id="404-content" class="text-center py-20 md:py-32">
<!-- 404 Number -->
<div class="mb-8">
<h1
class="text-9xl md:text-[12rem] font-bold text-indigo-500 leading-none"
>
404
</h1>
</div>
<!-- Main heading -->
<h2 class="text-3xl md:text-5xl font-bold text-white mb-4">
Page Not Found
</h2>
<!-- Description -->
<p class="text-lg md:text-xl text-gray-400 mb-8 max-w-2xl mx-auto">
Oops! The page you're looking for seems to have wandered off into the
digital void. Don't worry though, our PDF tools are still right where
you left them.
</p>
<!-- Action buttons -->
<div
class="flex flex-col sm:flex-row gap-4 justify-center items-center"
>
<a
href="index.html"
class="inline-flex items-center gap-3 pl-8 pr-2 py-2 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"
>
<span>Back to Home</span>
<span class="bg-white text-indigo-600 rounded-full p-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
>
<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<polyline points="9 22 9 12 15 12 15 22" />
</svg>
</span>
</a>
<a
href="/index.html#tools-header"
class="inline-block px-8 py-3 rounded-full bg-gray-800 text-white font-semibold border border-gray-700 hover:bg-gray-700 focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-900 focus:ring-gray-700 transition-all duration-200"
>
Browse All Tools
</a>
</div>
<!-- Helpful links -->
<div class="mt-16">
<p class="text-gray-500 mb-4">Or try these popular tools:</p>
<div class="flex flex-wrap justify-center gap-3">
<a
href="/merge-pdf"
class="px-4 py-2 bg-gray-800 text-gray-300 rounded-lg hover:bg-gray-700 hover:text-white transition-colors text-sm"
>
Merge PDF
</a>
<a
href="/split-pdf"
class="px-4 py-2 bg-gray-800 text-gray-300 rounded-lg hover:bg-gray-700 hover:text-white transition-colors text-sm"
>
Split PDF
</a>
<a
href="/compress-pdf"
class="px-4 py-2 bg-gray-800 text-gray-300 rounded-lg hover:bg-gray-700 hover:text-white transition-colors text-sm"
>
Compress PDF
</a>
<a
href="/edit-pdf"
class="px-4 py-2 bg-gray-800 text-gray-300 rounded-lg hover:bg-gray-700 hover:text-white transition-colors text-sm"
>
Edit PDF
</a>
</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>
<!-- JSON-LD Schema -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "404 - Page Not Found",
"description": "The page you're looking for doesn't exist on BentoPDF.",
"url": "https://www.bentopdf.com/404"
}
</script>
</body>
</html>
+140
View File
@@ -0,0 +1,140 @@
# BentoPDF Corporate Contributor License Agreement (CCLA)
Thank you for your organization's interest in contributing to BentoPDF. This Corporate Contributor License Agreement ("Agreement") documents the rights granted by corporate contributors to the Project.
By signing this Agreement, you accept and agree to the following terms and conditions for your organization's present and future Contributions submitted to the Project.
## 1. Definitions
**"You" (or "Your")** means the legal entity on behalf of which this Agreement is being entered into.
**"Contributor"** means any employee, contractor, or authorized agent of You who submits Contributions on Your behalf.
**"Contribution"** means any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You or any of Your Contributors to the Project for inclusion in, or documentation of, the Project. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Project or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of discussing and improving the Project.
**"Project"** means the BentoPDF software project and all associated repositories, documentation, and related materials maintained at https://github.com/alam00000/bentopdf.
**"Project Owner"** means the owners and maintainers of the Project.
## 2. Grant of Copyright License
Subject to the terms and conditions of this Agreement, You hereby grant to the Project Owner and to recipients of software distributed by the Project Owner a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to:
- Reproduce, prepare derivative works of, publicly display, publicly perform, and distribute Contributions made by You and Your Contributors, and such derivative works
- Sublicense any or all of the foregoing rights to third parties
- **Relicense Contributions under any license**, including but not limited to proprietary licenses, commercial licenses, or any other open source license
This grant specifically enables the Project Owner to offer commercial licenses of the Project incorporating Your Contributions, consistent with the Project's dual licensing model (AGPL-3.0 for open source use, and a separate commercial license for proprietary use).
## 3. Grant of Patent License
Subject to the terms and conditions of this Agreement, You hereby grant to the Project Owner and to recipients of software distributed by the Project Owner a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Contribution, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Project to which such Contribution(s) was submitted.
If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that Your Contribution, or the Project to which You have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Project shall terminate as of the date such litigation is filed.
## 4. Authorized Contributors
You are responsible for:
a) Identifying the initial list of Contributors authorized to submit Contributions on Your behalf by listing them in Schedule A below
b) Keeping the list of authorized Contributors current by notifying the Project Owner when Contributors should be added or removed
c) Ensuring that all authorized Contributors are aware of and comply with the terms of this Agreement
All Contributions made by Your authorized Contributors shall be deemed to be made on Your behalf and subject to this Agreement.
## 5. Representations and Warranties
You represent and warrant that:
a) **Authority**: You are legally entitled to grant the above licenses and have the authority to bind the legal entity You represent. You have taken all necessary corporate action to authorize the execution of this Agreement.
b) **Contributor Authorization**: Each Contributor identified by You is authorized to submit Contributions on Your behalf.
c) **Originality**: Each Contribution is Your organization's original creation, or You have sufficient rights to submit the Contribution on behalf of the original authors.
d) **Third-Party Rights**: Your Contributions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which You are aware and which are associated with any part of Your Contributions.
e) **No Conflicting Obligations**: Your Contributions do not violate any agreement or obligation You have with any third party.
f) **Accuracy**: All information You provide in connection with this Agreement and Your Contributions is accurate and complete.
## 6. Moral Rights Waiver
To the fullest extent permitted under applicable law, You hereby waive, and agree to cause Your Contributors to waive, any and all moral rights in or relating to Contributions, including without limitation:
- The right of attribution
- The right of integrity
- The right to object to derogatory treatment
- Any similar rights existing under the laws of any jurisdiction
You acknowledge that the Project Owner may modify, adapt, translate, or otherwise change Contributions without consent and without attribution.
## 7. No Revocation
**This license grant is irrevocable.** Once a Contribution has been submitted under this Agreement, You may not revoke or withdraw the licenses granted herein. The Project Owner and all downstream recipients may continue to use, distribute, modify, and sublicense Contributions indefinitely.
## 8. Retention of Copyright
You retain all right, title, and interest in and to the copyright of Your Contributions. Nothing in this Agreement is intended to transfer ownership of Your Contributions to the Project Owner. You are free to use Your Contributions for any other purpose.
## 9. No Obligation
You understand that the decision to include any Contribution in any project or source repository is entirely at the discretion of the Project Owner. The Project Owner is under no obligation to accept, use, or include any Contribution.
## 10. Support and Warranty Disclaimer
Unless required by applicable law or agreed to in writing, You provide Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
You are not expected to provide support for Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all.
## 11. Notification
You agree to notify the Project Owner of any facts or circumstances of which You become aware that would make any of Your representations in this Agreement inaccurate in any respect.
## 12. Governing Law
This Agreement shall be governed by and construed in accordance with the laws of India, without regard to its conflict of law provisions.
---
## Signature
By signing this Agreement, You confirm that You have the authority to bind the legal entity named below, and that entity agrees to the terms of this Corporate Contributor License Agreement.
**Legal Entity Name:** ___________________________
**Address:** ___________________________
**Point of Contact Name:** ___________________________
**Point of Contact Email:** ___________________________
**Point of Contact Phone:** ___________________________
**Signature:** ___________________________
**Title:** ___________________________
**Date:** ___________________________
---
## Schedule A: Authorized Contributors
The following individuals are authorized to submit Contributions to the Project on behalf of the above-named legal entity:
| Full Name | GitHub Username | Email Address | Date Added |
|-----------|-----------------|---------------|------------|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
*Add additional rows as needed. To update this list, contact the Project Owner at [email protected]*
---
*This CLA is based on the Apache Corporate Contributor License Agreement and has been adapted for BentoPDF's dual licensing model.*
+37
View File
@@ -0,0 +1,37 @@
# BentoPDF Commercial License
Thank you for purchasing a BentoPDF commercial license. This file summarizes what your license covers. The full terms are on the [licensing page](https://www.bentopdf.com/licensing).
## What the license covers
- Use of BentoPDF in closed-source or proprietary applications, without the AGPL-3.0 obligation to disclose your source code.
- Unlimited users and devices.
- Private modifications, including your own branding and removing the BentoPDF branding (Simple Mode).
- Self-hosting, including hosted access for your own users and customers.
- Lifetime updates and email support.
No license key is required or provided.
## Bundled components
**Building on BentoPDF? Hyper Compress is included.** The license includes Hyper Compress as a bundled component, so you don't need a separate Hyper Compress license to use it inside BentoPDF.
You may use a bundled component only through BentoPDF's own tools, as part of the BentoPDF application you deploy, including your branded or modified version of BentoPDF. You may not:
- call it from your own code through an API, SDK, command line, or headless or server process;
- separate, repackage or sublicense it, or use it in other software;
- offer a product or service whose main purpose is what the bundled component does, such as a compression-only app or website;
- modify the bundled component itself.
Any other use requires a separate [Hyper Compress license](https://www.bentopdf.com/hyper-compress#pricing), from $99/year. Kura is not a bundled component and is always licensed separately, with [commercial licenses](https://www.bentopdf.com/kura#pricing) from $99/year.
## Third-party components
The commercial license covers BentoPDF's own code. Third-party components keep their own licenses:
- **PyMuPDF, Ghostscript and CoherentPDF** are licensed under AGPL-3.0. By default they load at runtime from a CDN. If you host or modify them yourself, their AGPL-3.0 terms apply to them.
- Other components are distributed under their own open-source licenses. Keep their license and notice files in your deployment.
## Questions
Email [[email protected]](mailto:[email protected]) with your purchase details.
+29 -1
View File
@@ -6,6 +6,34 @@ This document outlines how to contribute, report issues, and get involved in the
--- ---
## Contributor License Agreement (CLA)
Before we can accept your contributions, you must sign our Contributor License Agreement (CLA). This is required because BentoPDF uses a dual licensing model:
- **AGPL-3.0** for open source use
- **Commercial license** for proprietary use
The CLA ensures we can include your contributions in both versions of the project.
### For Individual Contributors
Sign our [Individual Contributor License Agreement (ICLA)](ICLA.md). When you submit your first pull request, the CLA Assistant bot will automatically ask you to sign by commenting on the PR.
### For Corporate Contributors
If you are contributing on behalf of your employer, your organization needs to sign our [Corporate Contributor License Agreement (CCLA)](CCLA.md). Please contact us at [[email protected]](mailto:[email protected]) to arrange corporate CLA signing.
### What the CLA Grants
By signing the CLA, you:
- Grant us a broad copyright license to use, modify, and relicense your contributions (including for commercial use)
- Grant a patent license for any patents covering your contribution
- Represent that you have the authority to make the contribution
- Retain full copyright ownership of your contributions
---
## 1. How to Contribute ## 1. How to Contribute
You can contribute in several ways: You can contribute in several ways:
@@ -53,7 +81,7 @@ When submitting code contributions, please use our [pull request template](.gith
```bash ```bash
git clone https://github.com/alam00000/bentopdf.git git clone https://github.com/alam00000/bentopdf.git
cd bento-pdf cd bentopdf
npm install npm install
``` ```
+90 -33
View File
@@ -1,52 +1,109 @@
# Global variable declaration:
# Build to serve under Subdirectory BASE_URL if provided, eg: "ARG BASE_URL=/pdf/", otherwise leave blank: "ARG BASE_URL="
ARG BASE_URL=
# Build stage # Build stage
FROM node:20-alpine AS builder FROM mirror.gcr.io/library/node:26-alpine AS builder
WORKDIR /app WORKDIR /app
COPY package*.json ./ COPY package*.json ./
RUN npm ci COPY vendor ./vendor
ENV HUSKY=0
RUN npm config set fetch-retries 5 && \
npm config set fetch-retry-mintimeout 60000 && \
npm config set fetch-retry-maxtimeout 300000 && \
npm config set fetch-timeout 600000 && \
npm ci
COPY . . COPY . .
# Build without type checking (vite build only) # Build without type checking (vite build only)
# Pass SIMPLE_MODE environment variable if provided # Pass SIMPLE_MODE environment variable if provided
ARG SIMPLE_MODE=false ARG SIMPLE_MODE=false
ENV SIMPLE_MODE=$SIMPLE_MODE ENV SIMPLE_MODE=$SIMPLE_MODE
RUN npm run build -- --mode production ARG DISABLE_GITHUB_STARS=false
ENV DISABLE_GITHUB_STARS=$DISABLE_GITHUB_STARS
ARG COMPRESSION_MODE=o
ENV COMPRESSION_MODE=$COMPRESSION_MODE
# global arg to local arg - BASE_URL is read from env by vite.config.ts
ARG BASE_URL
ENV BASE_URL=$BASE_URL
# WASM module URLs (pre-configured defaults)
# Override these for air-gapped or self-hosted WASM deployments
ARG VITE_WASM_PYMUPDF_URL
ARG VITE_WASM_GS_URL
ARG VITE_WASM_CPDF_URL
ENV VITE_WASM_PYMUPDF_URL=$VITE_WASM_PYMUPDF_URL
ENV VITE_WASM_GS_URL=$VITE_WASM_GS_URL
ENV VITE_WASM_CPDF_URL=$VITE_WASM_CPDF_URL
# OCR asset URLs (optional, used for self-hosted or air-gapped OCR)
ARG VITE_TESSERACT_WORKER_URL
ARG VITE_TESSERACT_CORE_URL
ARG VITE_TESSERACT_LANG_URL
ARG VITE_TESSERACT_AVAILABLE_LANGUAGES
ARG VITE_OCR_FONT_BASE_URL
ENV VITE_TESSERACT_WORKER_URL=$VITE_TESSERACT_WORKER_URL
ENV VITE_TESSERACT_CORE_URL=$VITE_TESSERACT_CORE_URL
ENV VITE_TESSERACT_LANG_URL=$VITE_TESSERACT_LANG_URL
ENV VITE_TESSERACT_AVAILABLE_LANGUAGES=$VITE_TESSERACT_AVAILABLE_LANGUAGES
ENV VITE_OCR_FONT_BASE_URL=$VITE_OCR_FONT_BASE_URL
# Default UI language (e.g. en, fr, de, es, zh, ar)
ARG VITE_DEFAULT_LANGUAGE
ENV VITE_DEFAULT_LANGUAGE=$VITE_DEFAULT_LANGUAGE
# Custom branding (e.g. VITE_BRAND_NAME=MyCompany VITE_BRAND_LOGO=my-logo.svg)
ARG VITE_BRAND_NAME
ARG VITE_BRAND_LOGO
ARG VITE_FOOTER_TEXT
ENV VITE_BRAND_NAME=$VITE_BRAND_NAME
ENV VITE_BRAND_LOGO=$VITE_BRAND_LOGO
ENV VITE_FOOTER_TEXT=$VITE_FOOTER_TEXT
ARG DISABLE_TOOLS
ENV DISABLE_TOOLS=$DISABLE_TOOLS
# Public-facing canonical site URL. Defaults to the official site so self-hosters
# consolidate SEO signals back to bentopdf.com. A custom SITE_URL marks every page
# noindex unless ALLOW_INDEXING=true is also set.
ARG SITE_URL=https://www.bentopdf.com
ENV SITE_URL=$SITE_URL
ARG ALLOW_INDEXING=false
ENV ALLOW_INDEXING=$ALLOW_INDEXING
ENV NODE_OPTIONS="--max-old-space-size=3072"
RUN --mount=type=secret,id=VITE_CORS_PROXY_URL,required=false \
--mount=type=secret,id=VITE_CORS_PROXY_SECRET,required=false \
VITE_CORS_PROXY_URL=$(cat /run/secrets/VITE_CORS_PROXY_URL 2>/dev/null || echo "") \
VITE_CORS_PROXY_SECRET=$(cat /run/secrets/VITE_CORS_PROXY_SECRET 2>/dev/null || echo "") \
npm run build:with-docs
# Production stage # Production stage
FROM nginxinc/nginx-unprivileged:stable-alpine-slim FROM quay.io/nginx/nginx-unprivileged:alpine-slim
LABEL org.opencontainers.image.source="https://github.com/alam00000/bentopdf" LABEL org.opencontainers.image.source="https://github.com/alam00000/bentopdf"
LABEL org.opencontainers.image.url="https://github.com/alam00000/bentopdf"
COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html # global arg to local arg
ARG BASE_URL
# Set this to "true" to disable Nginx listening on IPv6
ENV DISABLE_IPV6=false
ENV PORT=8080
USER root
RUN apk upgrade --no-cache
USER nginx
COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html${BASE_URL%/}
COPY --chown=nginx:nginx nginx.conf /etc/nginx/nginx.conf COPY --chown=nginx:nginx nginx.conf /etc/nginx/nginx.conf
COPY --chown=nginx:nginx --from=builder /app/security-headers.conf /etc/nginx/security-headers.conf
COPY --chown=nginx:nginx --from=builder /app/security-headers-docs.conf /etc/nginx/security-headers-docs.conf
COPY --chown=nginx:nginx --chmod=755 nginx-ipv6.sh /docker-entrypoint.d/99-disable-ipv6.sh
COPY --chown=nginx:nginx --chmod=755 nginx-noindex.sh /docker-entrypoint.d/98-noindex.sh
RUN mkdir -p /etc/nginx/tmp && chown -R nginx:nginx /etc/nginx/tmp RUN mkdir -p /etc/nginx/tmp && chown -R nginx:nginx /etc/nginx/tmp
EXPOSE 8080 EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]
# Old Dockerfile for Root User
# # Build stage
# FROM node:20-alpine AS builder
# WORKDIR /app
# COPY package*.json ./
# RUN npm ci
# COPY . .
# # Build without type checking (vite build only)
# # Pass SIMPLE_MODE environment variable if provided
# ARG SIMPLE_MODE=false
# ENV SIMPLE_MODE=$SIMPLE_MODE
# RUN npm run build -- --mode production
# # Production stage
# FROM nginx:alpine
# COPY --from=builder /app/dist /usr/share/nginx/html
# COPY nginx.conf /etc/nginx/nginx.conf
# EXPOSE 8080
# CMD ["nginx", "-g", "daemon off;"]
+105
View File
@@ -0,0 +1,105 @@
# Non-root Dockerfile — supports PUID/PGID environment variables (LSIO-style)
# Usage: docker build -f Dockerfile.nonroot -t bentopdf .
# docker run -d -p 3000:8080 -e PUID=1000 -e PGID=1000 bentopdf
ARG BASE_URL=
# Build stage (identical to main Dockerfile)
FROM mirror.gcr.io/library/node:26-alpine AS builder
WORKDIR /app
COPY package*.json ./
COPY vendor ./vendor
ENV HUSKY=0
RUN npm config set fetch-retries 5 && \
npm config set fetch-retry-mintimeout 60000 && \
npm config set fetch-retry-maxtimeout 300000 && \
npm config set fetch-timeout 600000 && \
npm ci
COPY . .
ARG SIMPLE_MODE=false
ENV SIMPLE_MODE=$SIMPLE_MODE
ARG DISABLE_GITHUB_STARS=false
ENV DISABLE_GITHUB_STARS=$DISABLE_GITHUB_STARS
ARG COMPRESSION_MODE=o
ENV COMPRESSION_MODE=$COMPRESSION_MODE
ARG BASE_URL
ENV BASE_URL=$BASE_URL
ARG VITE_WASM_PYMUPDF_URL
ARG VITE_WASM_GS_URL
ARG VITE_WASM_CPDF_URL
ENV VITE_WASM_PYMUPDF_URL=$VITE_WASM_PYMUPDF_URL
ENV VITE_WASM_GS_URL=$VITE_WASM_GS_URL
ENV VITE_WASM_CPDF_URL=$VITE_WASM_CPDF_URL
ARG VITE_TESSERACT_WORKER_URL
ARG VITE_TESSERACT_CORE_URL
ARG VITE_TESSERACT_LANG_URL
ARG VITE_TESSERACT_AVAILABLE_LANGUAGES
ARG VITE_OCR_FONT_BASE_URL
ENV VITE_TESSERACT_WORKER_URL=$VITE_TESSERACT_WORKER_URL
ENV VITE_TESSERACT_CORE_URL=$VITE_TESSERACT_CORE_URL
ENV VITE_TESSERACT_LANG_URL=$VITE_TESSERACT_LANG_URL
ENV VITE_TESSERACT_AVAILABLE_LANGUAGES=$VITE_TESSERACT_AVAILABLE_LANGUAGES
ENV VITE_OCR_FONT_BASE_URL=$VITE_OCR_FONT_BASE_URL
# Default UI language (e.g. en, fr, de, es, zh, ar)
ARG VITE_DEFAULT_LANGUAGE
ENV VITE_DEFAULT_LANGUAGE=$VITE_DEFAULT_LANGUAGE
# Custom branding (e.g. VITE_BRAND_NAME=MyCompany VITE_BRAND_LOGO=my-logo.svg)
ARG VITE_BRAND_NAME
ARG VITE_BRAND_LOGO
ARG VITE_FOOTER_TEXT
ENV VITE_BRAND_NAME=$VITE_BRAND_NAME
ENV VITE_BRAND_LOGO=$VITE_BRAND_LOGO
ENV VITE_FOOTER_TEXT=$VITE_FOOTER_TEXT
# Public-facing canonical site URL. See Dockerfile for details.
ARG SITE_URL=https://www.bentopdf.com
ENV SITE_URL=$SITE_URL
ARG ALLOW_INDEXING=false
ENV ALLOW_INDEXING=$ALLOW_INDEXING
ENV NODE_OPTIONS="--max-old-space-size=3072"
RUN --mount=type=secret,id=VITE_CORS_PROXY_URL,required=false \
--mount=type=secret,id=VITE_CORS_PROXY_SECRET,required=false \
VITE_CORS_PROXY_URL=$(cat /run/secrets/VITE_CORS_PROXY_URL 2>/dev/null || echo "") \
VITE_CORS_PROXY_SECRET=$(cat /run/secrets/VITE_CORS_PROXY_SECRET 2>/dev/null || echo "") \
npm run build:with-docs
# Production stage — uses standard nginx (starts as root, drops to PUID/PGID)
FROM nginx:alpine-slim
LABEL org.opencontainers.image.source="https://github.com/alam00000/bentopdf"
LABEL org.opencontainers.image.url="https://github.com/alam00000/bentopdf"
ARG BASE_URL
ENV PUID=1000
ENV PGID=1000
ENV DISABLE_IPV6=false
ENV PORT=8080
RUN apk upgrade --no-cache && apk add --no-cache su-exec
COPY --from=builder /app/dist /usr/share/nginx/html${BASE_URL%/}
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /app/security-headers.conf /etc/nginx/security-headers.conf
COPY --from=builder /app/security-headers-docs.conf /etc/nginx/security-headers-docs.conf
COPY --chmod=755 entrypoint.sh /entrypoint.sh
COPY --chmod=755 nginx-noindex.sh /usr/local/bin/bentopdf-noindex.sh
RUN mkdir -p /etc/nginx/tmp \
/var/cache/nginx/client_temp \
/var/cache/nginx/proxy_temp \
/var/cache/nginx/fastcgi_temp \
/var/cache/nginx/uwsgi_temp \
/var/cache/nginx/scgi_temp
EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
+100
View File
@@ -0,0 +1,100 @@
# BentoPDF Individual Contributor License Agreement (ICLA)
Thank you for your interest in contributing to BentoPDF. This Individual Contributor License Agreement ("Agreement") documents the rights granted by contributors to the Project.
By signing this Agreement, you accept and agree to the following terms and conditions for your present and future Contributions submitted to the Project.
## 1. Definitions
**"You" (or "Your")** means the individual who is signing this Agreement and submitting Contributions to the Project.
**"Contribution"** means any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Project for inclusion in, or documentation of, the Project. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Project or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of discussing and improving the Project.
**"Project"** means the BentoPDF software project and all associated repositories, documentation, and related materials maintained at https://github.com/alam00000/bentopdf.
**"Project Owner"** means the owners and maintainers of the Project.
## 2. Grant of Copyright License
Subject to the terms and conditions of this Agreement, You hereby grant to the Project Owner and to recipients of software distributed by the Project Owner a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to:
- Reproduce, prepare derivative works of, publicly display, publicly perform, and distribute Your Contributions and such derivative works
- Sublicense any or all of the foregoing rights to third parties
- **Relicense Your Contributions under any license**, including but not limited to proprietary licenses, commercial licenses, or any other open source license
This grant specifically enables the Project Owner to offer commercial licenses of the Project incorporating Your Contributions, consistent with the Project's dual licensing model (AGPL-3.0 for open source use, and a separate commercial license for proprietary use).
## 3. Grant of Patent License
Subject to the terms and conditions of this Agreement, You hereby grant to the Project Owner and to recipients of software distributed by the Project Owner a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Contribution, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Project to which such Contribution(s) was submitted.
If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that Your Contribution, or the Project to which You have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Project shall terminate as of the date such litigation is filed.
## 4. Representations and Warranties
You represent and warrant that:
a) **Authority**: You are legally entitled to grant the above licenses. If Your employer(s) has rights to intellectual property that You create, You represent that You have received permission to make Contributions on behalf of that employer, that Your employer has waived such rights for Your Contributions, or that Your employer has executed a separate Corporate CLA with the Project.
b) **Originality**: Each of Your Contributions is Your original creation. You represent that Your Contributions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which You are aware and which are associated with any part of Your Contributions.
c) **No Conflicting Obligations**: Your Contribution does not violate any agreement or obligation You have with any third party.
d) **Accuracy**: All information You provide in connection with this Agreement and Your Contributions is accurate and complete.
## 5. Moral Rights Waiver
To the fullest extent permitted under applicable law, You hereby waive, and agree not to assert, any and all moral rights You may have in or relating to Your Contributions, including without limitation:
- The right of attribution
- The right of integrity
- The right to object to derogatory treatment
- Any similar rights existing under the laws of any jurisdiction
You acknowledge that the Project Owner may modify, adapt, translate, or otherwise change Your Contributions without Your consent and without attribution.
## 6. No Revocation
**This license grant is irrevocable.** Once You have submitted a Contribution under this Agreement, You may not revoke or withdraw the licenses granted herein. The Project Owner and all downstream recipients may continue to use, distribute, modify, and sublicense Your Contribution indefinitely.
## 7. Retention of Copyright
You retain all right, title, and interest in and to the copyright of Your Contributions. Nothing in this Agreement is intended to transfer ownership of Your Contributions to the Project Owner. You are free to use Your Contributions for any other purpose.
## 8. No Obligation
You understand that the decision to include Your Contribution in any project or source repository is entirely at the discretion of the Project Owner. The Project Owner is under no obligation to accept, use, or include any Contribution.
## 9. Support and Warranty Disclaimer
Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all.
## 10. Notification
You agree to notify the Project Owner of any facts or circumstances of which You become aware that would make any of Your representations in this Agreement inaccurate in any respect.
## 11. Governing Law
This Agreement shall be governed by and construed in accordance with the laws of India, without regard to its conflict of law provisions.
---
## Signature
By submitting a pull request or other Contribution to the Project, and by typing your name and date below (or by signing electronically via CLA Assistant), you agree to the terms of this Individual Contributor License Agreement.
**Full Legal Name:** Stephan Paternotte
**GitHub Username:** Stephan-P
**Email Address:** stephan@paternottes.net
**Date:** 20-12-2025
**Signature:** ___________________________
---
*This CLA is based on the Apache Individual Contributor License Agreement and has been adapted for BentoPDF's dual licensing model.*
+1044 -167
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -38,7 +38,7 @@ npm run release:major # Major: 1.0.0 → 2.0.0 (breaking changes)
**What Happens:** **What Happens:**
- ✅ Your feature commit stays as-is - ✅ Your feature commit stays as-is
- ✅ Version gets bumped in `package.json` - ✅ Version gets bumped in `package.json` and `chart/Chart.yaml`
- ✅ New release commit is created - ✅ New release commit is created
- ✅ Git tag is created (e.g., `v1.0.1`) - ✅ Git tag is created (e.g., `v1.0.1`)
- ✅ Everything gets pushed to GitHub - ✅ Everything gets pushed to GitHub
@@ -215,16 +215,16 @@ git reset --hard HEAD~1
1. **GitHub Actions Triggered**: Workflow starts building Docker image 1. **GitHub Actions Triggered**: Workflow starts building Docker image
2. **Docker Build**: Multi-architecture image created 2. **Docker Build**: Multi-architecture image created
3. **Docker Push**: Images pushed to Docker Hub with tags: 3. **Docker Push**: Images pushed to Docker Hub with tags:
- `bentopdf/bentopdf:latest` - `bentopdfteam/bentopdf:latest`
- `bentopdf/bentopdf:1.0.1` - `bentopdfteam/bentopdf:1.0.1`
- `bentopdf/bentopdf:v1.0.1` - `bentopdfteam/bentopdf:v1.0.1`
### **End Result:** ### **End Result:**
Users can immediately pull your new version: Users can immediately pull your new version:
```bash ```bash
docker pull bentopdf/bentopdf:1.0.1 docker pull bentopdfteam/bentopdf:1.0.1
``` ```
--- ---
+110 -60
View File
@@ -1,21 +1,25 @@
# Simple Mode for BentoPDF # Simple Mode for BentoPDF (the Self-Hosted build)
Simple Mode is designed for internal organizational use where you want to hide all branding and marketing content, showing only the essential PDF tools for your users. Simple Mode is what powers the **Self-Hosted build** of BentoPDF (`bentopdf-simple`). It is **functionally identical** to the Commercial build that powers bentopdf.com — every PDF tool is present and behaves the same. It just hides the marketing chrome (hero, FAQ, testimonials, footer) that only makes sense on the public bentopdf.com site or on a commercial public-facing deployment.
## What Simple Mode Does > **Simple Mode is not a feature-reduced "lite" version.** Every PDF tool — merge, split, edit, sign, OCR, Office conversion, every other tool — works identically in both builds. The only difference is the marketing UI around the tools.
When enabled, Simple Mode will: The Commercial build (`ghcr.io/alam00000/bentopdf:latest`) is used by bentopdf.com itself and by commercial license holders running public-facing PDF deployments where the full marketing site makes sense.
- Hide the navigation bar ## What Simple Mode Hides
- Hide the hero section with marketing content
- Hide the features section When enabled, Simple Mode hides the following bentopdf.com-specific marketing UI:
- Hide the security/compliance section
- Hide the FAQ section - Navigation bar
- Hide the testimonials section - Hero section with marketing content
- Hide the support section - Features section
- Hide the footer - Security/compliance section
- Update the page title to "PDF Tools" - FAQ section
- Make the tools section more prominent - Testimonials section
- Support section
- Footer
It also updates the page title to "PDF Tools" and makes the tools section more prominent. **No PDF tools are removed or disabled.**
## How to Enable Simple Mode ## How to Enable Simple Mode
@@ -23,27 +27,35 @@ When enabled, Simple Mode will:
Use the pre-built Simple Mode image directly: Use the pre-built Simple Mode image directly:
**Using GitHub Container Registry (Recommended):**
```bash
# Docker
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
# Podman
podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
```
**Using Docker Hub:** **Using Docker Hub:**
```bash ```bash
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest # Docker
docker run -p 3000:8080 bentopdfteam/bentopdf-simple:latest
# Podman
podman run -p 3000:8080 docker.io/bentopdfteam/bentopdf-simple:latest
``` ```
**Using GitHub Container Registry:** Or with Docker Compose / Podman Compose:
```bash
docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
```
Or with Docker Compose:
```yaml ```yaml
services: services:
bentopdf: bentopdf:
# Using Docker Hub # Using GitHub Container Registry (Recommended)
image: bentopdf/bentopdf-simple:latest image: ghcr.io/alam00000/bentopdf-simple:latest
# Or using GitHub Container Registry # Or using Docker Hub
# image: ghcr.io/alam00000/bentopdf-simple:latest # image: bentopdfteam/bentopdf-simple:latest
container_name: bentopdf container_name: bentopdf
restart: unless-stopped restart: unless-stopped
ports: ports:
@@ -105,9 +117,13 @@ This automatically builds and serves Simple Mode on `http://localhost:3000`.
### Method 2: Using Pre-built Image (Easiest for Production) ### Method 2: Using Pre-built Image (Easiest for Production)
```bash ```bash
# Pull and run the Simple Mode image # Docker - Pull and run the Simple Mode image
docker pull bentopdf/bentopdf-simple:latest docker pull ghcr.io/alam00000/bentopdf-simple:latest
docker run -p 3000:8080 bentopdf/bentopdf-simple:latest docker run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
# Podman
podman pull ghcr.io/alam00000/bentopdf-simple:latest
podman run -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
``` ```
Open `http://localhost:3000` in your browser. Open `http://localhost:3000` in your browser.
@@ -124,18 +140,20 @@ npx serve dist -p 3000
Open `http://localhost:3000` in your browser. Open `http://localhost:3000` in your browser.
### Method 4: Compare Both Modes ### Method 4: Compare Both Builds Side-by-Side
```bash ```bash
# Test Normal Mode # Commercial build (the bentopdf.com look)
docker run -p 3000:8080 bentopdf/bentopdf:latest docker run -p 3000:8080 ghcr.io/alam00000/bentopdf:latest
# Test Simple Mode # Self-Hosted build (Simple Mode)
docker run -p 3001:8080 bentopdf/bentopdf-simple:latest docker run -p 3001:8080 ghcr.io/alam00000/bentopdf-simple:latest
# Podman users: replace 'docker' with 'podman'
``` ```
- Normal Mode: `http://localhost:3000` - Commercial build: `http://localhost:3000`
- Simple Mode: `http://localhost:3001` - Self-Hosted build: `http://localhost:3001`
## 🔍 What to Look For ## 🔍 What to Look For
@@ -149,52 +167,84 @@ When Simple Mode is working correctly, you should see:
- ❌ No hero section with "The PDF Toolkit built for privacy" - ❌ No hero section with "The PDF Toolkit built for privacy"
- ❌ No features, FAQ, testimonials, or footer sections - ❌ No features, FAQ, testimonials, or footer sections
## 📦 Available Docker Images ## 📦 Available Container Images
### Normal Mode (Full Branding) ### Self-Hosted build (Simple Mode) — recommended for self-hosting
**Docker Hub:** **GitHub Container Registry (Recommended):**
- `bentopdf/bentopdf:latest`
- `bentopdf/bentopdf:v1.0.0` (versioned)
**GitHub Container Registry:**
- `ghcr.io/alam00000/bentopdf:latest`
- `ghcr.io/alam00000/bentopdf:v1.0.0` (versioned)
### Simple Mode (Clean Interface)
**Docker Hub:**
- `bentopdf/bentopdf-simple:latest`
- `bentopdf/bentopdf-simple:v1.0.0` (versioned)
**GitHub Container Registry:**
- `ghcr.io/alam00000/bentopdf-simple:latest` - `ghcr.io/alam00000/bentopdf-simple:latest`
- `ghcr.io/alam00000/bentopdf-simple:v1.0.0` (versioned) - `ghcr.io/alam00000/bentopdf-simple:v1.0.0` (versioned)
**Docker Hub:**
- `bentopdfteam/bentopdf-simple:latest`
- `bentopdfteam/bentopdf-simple:v1.0.0` (versioned)
### Commercial build — used by bentopdf.com and commercial license holders
The full marketing site, including hero/FAQ/testimonials/footer. Pull this only if you specifically want the bentopdf.com look — for example, you're running a public-facing PDF deployment under a commercial license.
**GitHub Container Registry (Recommended):**
- `ghcr.io/alam00000/bentopdf:latest`
- `ghcr.io/alam00000/bentopdf:v1.0.0` (versioned)
**Docker Hub:**
- `bentopdfteam/bentopdf:latest`
- `bentopdfteam/bentopdf:v1.0.0` (versioned)
## 🚀 Production Deployment Examples ## 🚀 Production Deployment Examples
### Internal Company Tool ### Docker Compose / Podman Compose
```yaml ```yaml
services: services:
bentopdf: bentopdf:
image: bentopdf/bentopdf-simple:latest image: ghcr.io/alam00000/bentopdf-simple:latest # Recommended
# image: bentopdfteam/bentopdf-simple:latest # Alternative: Docker Hub
container_name: bentopdf container_name: bentopdf
restart: unless-stopped restart: unless-stopped
ports: ports:
- '80:80' - '80:8080'
environment: environment:
- PUID=1000 - PUID=1000
- PGID=1000 - PGID=1000
``` ```
### Podman Quadlet (Linux Systemd)
Create `~/.config/containers/systemd/bentopdf-simple.container`:
```ini
[Unit]
Description=BentoPDF Simple Mode
After=network-online.target
[Container]
Image=ghcr.io/alam00000/bentopdf-simple:latest
ContainerName=bentopdf-simple
PublishPort=80:8080
AutoUpdate=registry
[Service]
Restart=always
[Install]
WantedBy=default.target
```
Enable and start:
```bash
systemctl --user daemon-reload
systemctl --user enable --now bentopdf-simple
```
## ⚠️ Important Notes ## ⚠️ Important Notes
- **Pre-built images**: Use `bentopdf/bentopdf-simple:latest` for Simple Mode - **Pre-built images**: Use `ghcr.io/alam00000/bentopdf-simple:latest` for Simple Mode (recommended)
- **Environment variables**: `SIMPLE_MODE=true` only works during build, not runtime - **Environment variables**: `SIMPLE_MODE=true` only works during build, not runtime
- **Build-time optimization**: Simple Mode uses dead code elimination for smaller bundles - **Build-time optimization**: Simple Mode uses dead code elimination for smaller bundles
- **Same functionality**: All PDF tools work identically in both modes - **Same functionality**: All PDF tools work identically in both modes
+138
View File
@@ -0,0 +1,138 @@
# Hosting BentoPDF as a static website
As an alternative to running BentoPDF locally or in a Docker container, you can easily host it as a set of static web pages. Here are a few examples:
## Netlify
### Netlify - static deployment
One of the simplest ways to host BentoPDF is to create a project at [Netlify](https://www.netlify.com/) and create a static deployment. You can accomplish this by first downloading the pre-built distribution file from our [GitHub releases](https://github.com/alam00000/bentopdf/releases). Each release includes a `dist-{version}.zip` file that contains all necessary files for self-hosting.
1. Go to [BentoPDF Releases](https://github.com/alam00000/bentopdf/releases)
2. Download the latest `dist-{version}.zip` file
3. Next, if you have not already done so, create a Netlify account and log in.
4. From your Netlify projects page, add a new project and select "Deploy manually".
5. Drag and drop to upload the BentoPDF zip file you downloaded in step 2.
6. Your BentoPDF deployment should now be working! Optionally, you can go into Project Configuration and change the project name.
When a new BentoPDF release becomes available, you will need to repeat steps 1-3, then go into "Deploys" and upload the new release.
### Netlify - dynamic deployment
Alternatively, you can configure a Netlify project to automatically deploy whenever your BentoPDF is updated.
1. If you have not done so already, create a fork of BentoPDF into your own GitHub account.
2. If you have not already done so, create a Netlify account and log in.
3. From your Netlify projects page, add a new project and select 'Import an existing project'.
4. Select the GitHub button, authorize Netlify, then choose where to install the integration. You can choose 'All repositories' or 'Only select repositories' and choose your BentoPDF fork.
5. Select your repo and give it a project name. (add environment variables?) Then click the blue 'Deploy' button.
6. The Netlify build & deploy process will kick off. Once it finishes, you can click on the provided URL `https://[projectname]/netlify.app` to view your deployment of BentoPDF.
Whenever the BentoPDF source code is updated, you can sync the changes into your repo. This will kick off a new build and deploy within Netlify.
If you want to use BentoPDF's simple mode, go into Deploy Settings, then Environment Variables, and Add a variable. Add `SIMPLE_MODE` and set it to `true`. You will need to manually kick a new build to get this to take effect.
## Vercel
Vercel provides similar services to Netlify dynamic hosting.
1. If you have not done so already, create a fork of BentoPDF into your own GitHub account.
2. If you have not already done so, create a Vercel account and log in.
3. From your Vercel Overview page, select 'Add new project'
4. Under 'Import Git Repository' and then choose 'Add GitHub Account'. Follow the prompts to authorize Vercel integration. You can choose 'All repositories' or 'Only select repositories' and choose your BentoPDF fork.
5. Select 'Import' to import the repo into Vercel.
6. Under 'Framework Preset', select 'Vite' and save the settings.
7. The Vercel build & deploy process will kick off. Once it finishes, you can click on the provided link to view your deployment of BentoPDF.
Whenever the BentoPDF source code is updated, you can sync the changes into your repo. This will kick off a new build and deploy within Vercel.
If you want to use BentoPDF's simple mode, go into Project Settings, then Environment Variables, and Create a new variable. Add `SIMPLE_MODE` and set it to `true`. You will need to redeploy to get this to take effect.
## GitHub Pages
You can also host your own instance of BentoPDF using GitHub Pages. An advantage of this over the other options is you are able to do everything in GitHub without any third-party service.
1. If you have not done so already, create a fork of BentoPDF into your own GitHub account.
2. From your fork, go to `Settings->Pages`, and change the 'Source' to 'GitHub Actions'
3. Go to `Settings->Secrets and Variables > Actions`, then select 'Variables', and add the repository variable `BASE_URL`. Set the value to `/bentopdf`. _If you've renamed the repo to something other than bentopdf, put that here_.
4. Go to `Actions` in the top menu, and select 'I understand' to enable Actions
5. Within Actions, on the left, select 'Deploy static content to Pages', and then on the right select 'Run workflow', and in the dropdown, 'Run Workflow'. The action will now run to build BentoPDF and deploy it to GitHub Pages.
When the build completes, you can find the website at `https://[your-github-username]/bentopdf`
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. `npm run build` writes `dist/_headers` with `scripts/generate-security-headers.mjs`, 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. If you add your own `public/_headers`, the build ships yours instead. 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 the `dist/_headers` your build produces.
- **`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
hreflang/`x-default` set that point back to `https://www.bentopdf.com`. This
is intentional for two reasons:
1. **It consolidates SEO signals to the official site** so your instance
doesn't compete with bentopdf.com on brand searches like "bentopdf".
2. **It keeps your instance off public search results.** If you self-host
on a small VPS, a home server, or anywhere with limited bandwidth, you
probably don't want strangers from Google landing on it. With the
default canonical pointing back to the official site, search engines
treat your instance as a copy and won't surface it for organic traffic
and your bandwidth is reserved for the people you actually share the URL
with.
You have two clean overrides depending on what you want.
### Run your own SEO instance (claim canonical for yourself)
If you operate a public deployment and want it to be the indexed copy for
your audience, set `SITE_URL` at build time to your origin and also set
`ALLOW_INDEXING=true`. The build will emit canonicals, hreflang and
sitemap URLs pointing at your domain. Without `ALLOW_INDEXING=true`, a
build with a custom `SITE_URL` marks every page `noindex`.
- Docker:
```sh
docker build --build-arg SITE_URL=https://pdf.example.com --build-arg ALLOW_INDEXING=true -t bentopdf-self .
```
- Netlify, Vercel, GitHub Pages, or any other static host: set `SITE_URL`
and `ALLOW_INDEXING=true` in your project's environment variables and
re-deploy. The build script reads them during `npm run build`. For the
GitHub Pages workflow, add both as repository variables.
### Stay invisible to search engines (no SEO competition either way)
Set the runtime environment variable `ROBOTS_NOINDEX=true`. The container
then sends an `X-Robots-Tag: noindex, follow` header with every response.
The canonical link still points at the official site by default, so when
crawlers do follow internal links they still see bentopdf.com as the
authoritative source. `ROBOTS_NOINDEX` only works in the Docker image; if
you serve the files yourself, build with your own `SITE_URL` instead (see
above).
```sh
docker run -d -p 8080:8080 -e ROBOTS_NOINDEX=true ghcr.io/alam00000/bentopdf:latest
```
A build with your own `SITE_URL` and without `ALLOW_INDEXING=true` is
already `noindex`, so it neither competes with bentopdf.com nor advertises
itself. `ROBOTS_NOINDEX=true` does the same at runtime for the prebuilt
images.
### Note on Simple Mode
Simple Mode (`SIMPLE_MODE=true`) controls the **UI** — it ships a stripped-down
homepage suitable for company intranets and single-purpose deployments. It
does **not** by itself control whether your instance is indexed by search
engines. A public-facing simple-mode deployment is fully indexable by default,
just like the full-mode build. If you want a simple-mode deployment hidden
from search engines, combine `SIMPLE_MODE=true` at build time with
`ROBOTS_NOINDEX=true` at runtime.
+626
View File
@@ -0,0 +1,626 @@
# 🌍 Translation Guide for BentoPDF
This guide will help you add new languages or improve existing translations for BentoPDF.
## Table of Contents
- [Overview](#overview)
- [Quick Start](#quick-start)
- [Adding a New Language](#adding-a-new-language)
- [Translation File Structure](#translation-file-structure)
- [Where Translations Are Used](#where-translations-are-used)
- [Testing Your Translations](#testing-your-translations)
- [Translation Guidelines](#translation-guidelines)
- [Common Issues](#common-issues)
---
## Overview
BentoPDF uses **i18next** for internationalization (i18n). Currently supported languages:
- **English** (`en`) - Default
- **Belarusian** (`be`)
- **German** (`de`)
- **Spanish** (`es`)
- **French** (`fr`)
- **Italian** (`it`)
- **Portuguese** (`pt`)
- **Turkish** (`tr`)
- **Vietnamese** (`vi`)
- **Indonesian** (`id`)
- **Chinese** (`zh`)
- **Traditional Chinese (Taiwan)** (`zh-TW`)
- **Korean** (`ko`)
- **Russian** (`ru`)
- **Ukrainian** (`uk`)
- **Slovak** (`sk`)
- **Arabic** (`ar`)
- **Dutch** (`nl`)
- **Danish** (`da`)
- **Swedish** (`sv`)
- **Japanese** (`ja`)
- **Persian (Farsi)** (`fa`)
The app automatically detects the language from the URL path:
- `/` or `/en/` → English (default)
- `/de/` → German
- `/fr/` → French
- etc.
### Architecture
BentoPDF uses a **static pre-rendering** approach for SEO-optimized i18n:
1. **Build time**: `scripts/generate-i18n-pages.mjs` generates localized HTML files in `dist/{lang}/`
2. **Dev/Preview**: `languageRouterPlugin` in `vite.config.ts` handles URL rewriting
3. **Production**: Nginx serves static files directly from language directories
---
## Quick Start
**To improve existing translations:**
1. Navigate to `public/locales/{language}/common.json` and `public/locales/{language}/tools.json`
2. Find the key you want to update
3. Change the translation value
4. Save and test
**To add a new language (e.g., Japanese `ja`):**
1. Copy `public/locales/en/` to `public/locales/ja/`
2. Translate all values in both `ja/common.json` and `ja/tools.json`
3. Add Japanese to `supportedLanguages` and `languageNames` in `src/js/i18n/i18n.ts`
4. Add `'ja'` to `SUPPORTED_LANGUAGES` in `vite.config.ts`
5. Restart the dev server
6. Run `npm run build` to generate static language pages
7. Test thoroughly
---
## Adding a New Language
Let's add **Spanish** as an example:
### Step 1: Create Translation Files
```bash
# Create the directory
mkdir -p public/locales/es
# Copy the English template
cp public/locales/en/common.json public/locales/es/common.json
```
### Step 2: Translate the JSON Files
Open `public/locales/es/common.json` and translate all the values:
```json
{
"nav": {
"home": "Inicio",
"about": "Acerca de",
"contact": "Contacto",
"allTools": "Todas las herramientas"
},
"hero": {
"title": "Tu conjunto de herramientas PDF gratuito y seguro",
"subtitle": "Combina, divide, comprime y edita archivos PDF directamente en tu navegador."
}
// ... continue translating all keys
}
```
⚠️ **Important**: Only translate the **values**, NOT the keys!
✅ **Correct:**
```json
"home": "Inicio"
```
❌ **Wrong:**
```json
"inicio": "Inicio"
```
Then do the same for `public/locales/es/tools.json` to translate all tool names and descriptions.
### Step 3: Register the Language
Edit `src/js/i18n/i18n.ts`:
```typescript
// Add 'fr' to supported languages
export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi'] as const;
export type SupportedLanguage = (typeof supportedLanguages)[number];
// Add French display name
export const languageNames: Record<SupportedLanguage, string> = {
en: 'English',
de: 'Deutsch',
fr: 'Français', // ← Add this
};
```
### Step 4: Update Vite Configuration
In `vite.config.ts`, add your language to the `SUPPORTED_LANGUAGES` array:
```typescript
const SUPPORTED_LANGUAGES = [
'en',
'de',
'es',
'zh',
'zh-TW',
'vi',
'it',
'id',
'tr',
'fr',
'pt',
'ja',
] as const;
```
> **Important**: This is required for both dev server routing and the build-time i18n generation.
### Step 5: Test Your Translation
```bash
# Restart the dev server
npm run dev
# Visit the Japanese version
# http://localhost:5173/ja/
```
### Step 6: Build and Verify Static Files
```bash
# Run build (includes i18n page generation)
npm run build
# Verify files were created
ls dist/ja/
# Should show: index.html, merge-pdf.html, etc.
```
---
## Translation File Structure
The `common.json` file is organized into logical sections:
```json
{
"nav": {
// Navigation menu items
},
"hero": {
// Homepage hero section
},
"features": {
// Features section
},
"tools": {
// Tool names and descriptions
},
"upload": {
// File upload UI
},
"settings": {
// Settings modal and keyboard shortcuts
},
"faq": {
// FAQ section
},
"footer": {
// Footer links and text
},
"compliance": {
// Security compliance information
},
"testimonials": {
// User testimonials
},
"support": {
// Support section
},
"alert": {
// Alert and error messages
}
}
```
### Key Naming Convention
- Use **camelCase** for keys: `"deletePage"` not `"delete_page"`
- Use **nested objects** for organization: `"nav.home"` is represented as:
```json
{
"nav": {
"home": "Home"
}
}
```
- Be descriptive: `"shortcutsWarning"` is better than `"warning1"`
---
## Where Translations Are Used
### 1. HTML Templates (`data-i18n` attribute)
```html
<!-- Translation key: nav.home -->
<a href="/" data-i18n="nav.home">Home</a>
```
The `data-i18n` attribute tells i18next which translation to use.
### 2. Tool Definitions
Tool names and descriptions are defined in `src/js/config/tools.ts` and use a special namespace:
```typescript
{
name: 'Merge PDF', // Used for shortcuts only
subtitle: 'Combine multiple PDFs into one file.',
}
```
In translations:
```json
{
"tools": {
"mergePdf": {
"name": "PDF zusammenführen",
"subtitle": "Mehrere PDFs in eine Datei kombinieren."
}
}
}
```
### 3. Dynamic JavaScript (`t()` function)
For translations that need to be applied dynamically:
```typescript
import { t } from './i18n/i18n';
const message = t('alert.error');
console.log(message); // "Error" or "Fehler" depending on language
```
### 4. Placeholders
For input placeholders:
```html
<input
type="text"
placeholder="Search for a tool..."
data-i18n-placeholder="tools.searchPlaceholder"
/>
```
In `common.json`:
```json
{
"tools": {
"searchPlaceholder": "Nach einem Tool suchen..."
}
}
```
---
## Testing Your Translations
### Manual Testing
1. **Start development server:**
```bash
npm run dev
```
2. **Visit each language:**
- English: `http://localhost:5173/en/`
- German: `http://localhost:5173/de/`
- Vietnamese: `http://localhost:5173/vi/`
- Indonesian: `http://localhost:5173/id/`
- Chinese: `http://localhost:5173/zh/`
- Traditional Chinese (Taiwan): `http://localhost:5173/zh-TW/`
- French: `http://localhost:5173/fr/`
- Your new language: `http://localhost:5173/es/`
3. **Check these pages:**
- Homepage (`/`)
- About page (`/about.html`)
- Contact page (`/contact.html`)
- FAQ page (`/faq.html`)
- Tool pages (e.g., `/merge-pdf.html`)
4. **Test these interactions:**
- Click the language switcher in the footer
- Navigate between pages
- Open the settings modal (click gear icon next to search)
- Try a tool to see upload messages
### Automated Checks
Check for missing translations:
```bash
# This will show any missing keys
node scripts/check-translations.js
```
_(If this script doesn't exist, you may need to create it or manually compare JSON files)_
### Browser Testing
Test in different browsers:
- Chrome/Edge
- Firefox
- Safari
---
## Translation Guidelines
### 1. Keep the Tone Consistent
BentoPDF is **friendly, clear, and professional**. Match this tone in your translations.
✅ **Good:**
```json
"hero.title": "Ihr kostenloses und sicheres PDF-Toolkit"
```
❌ **Too formal:**
```json
"hero.title": "Ihr gebührenfreies und gesichertes Werkzeug für PDF-Dokumente"
```
### 2. Preserve Formatting
Some strings contain HTML or special characters:
```json
{
"faq.analytics.answer": "No. BentoPDF does not track you at all. We do not use cookies, analytics, or any tracking scripts, not even on the live website at bentopdf.com. We never know who you are or what you do with the tools."
}
```
When translating, **keep the HTML tags intact**:
```json
{
"faq.analytics.answer": "Nein. BentoPDF verfolgt Sie in keiner Weise. Wir verwenden keine Cookies, keine Analysetools und keine Tracking-Skripte – auch nicht auf der Live-Website bentopdf.com. Wir wissen nie, wer Sie sind oder was Sie mit den Tools tun."
}
```
### 3. Handle Plurals and Gender
If your language has complex plural rules or gender distinctions, consult the [i18next pluralization guide](https://www.i18next.com/translation-function/plurals).
Example:
```json
{
"pages": "page",
"pages_plural": "pages"
}
```
### 4. Don't Translate Brand Names or Legal Terms
Keep these as-is:
- BentoPDF
- PDF
- GitHub
- Discord
- Chrome, Firefox, Safari, etc.
- Terms and Conditions
- Privacy Policy
- Licensing
### 5. Technical Terms
For technical terms, use commonly accepted translations in your language:
- "Merge" → "Fusionner" (French), "Zusammenführen" (German)
- "Split" → "Diviser" (French), "Teilen" (German)
- "Compress" → "Compresser" (French), "Komprimieren" (German)
If unsure, check how other PDF tools translate these terms in your language.
### 6. String Length
Some UI elements have limited space. Try to keep translations **similar in length** to the English version.
If a translation is much longer, test it visually to ensure it doesn't break the layout.
---
## Common Issues
### Issue: Translations Not Showing Up
**Solution:**
1. Clear your browser cache
2. Hard refresh (Ctrl+F5 or Cmd+Shift+R)
3. Check browser console for errors
4. Verify the JSON file is valid (no syntax errors)
### Issue: Some Text Still in English
**Possible causes:**
1. Missing translation key in your language file
2. Missing `data-i18n` attribute in HTML
3. Hardcoded text in JavaScript
**Solution:**
- Compare your language file with `en/common.json` to find missing keys
- Search the codebase for hardcoded strings
### Issue: JSON Syntax Error
**Symptoms:**
```
SyntaxError: Unexpected token } in JSON at position 1234
```
**Solution:**
- Use a JSON validator: https://jsonlint.com/
- Common mistakes:
- Trailing comma after last item
- Missing or extra quotes
- Unescaped quotes inside strings (use `\"`)
### Issue: Language Switcher Not Showing New Language
**Solution:**
Make sure you added the language to both arrays in `i18n.ts`:
```typescript
export const supportedLanguages = ['en', 'de', 'es', 'fr', 'zh', 'vi']; // ← Add here
export const languageNames = {
en: 'English',
de: 'Deutsch',
es: 'Español',
fr: 'Français', // ← And here
zh: '中文',
vi: 'Tiếng Việt',
};
```
### Issue: 404 Error When Accessing Language Pages
**Symptoms:**
Visiting `http://localhost:5173/ja/about.html` shows a 404 error page.
**Solution:**
You need to add your language code to `SUPPORTED_LANGUAGES` in `vite.config.ts`:
```typescript
const SUPPORTED_LANGUAGES = [
'en',
'de',
'es',
'zh',
'zh-TW',
'vi',
'it',
'id',
'tr',
'fr',
'pt',
'ja',
] as const;
```
After updating, restart the dev server:
```bash
npm run dev
```
---
## File Checklist
When adding a new language, make sure these files are updated:
- [ ] `public/locales/{lang}/common.json` - Main translation file
- [ ] `public/locales/{lang}/tools.json` - Tools translation file
- [ ] `src/js/i18n/i18n.ts` - Add to `supportedLanguages` and `languageNames`
- [ ] `vite.config.ts` - Add to `SUPPORTED_LANGUAGES` array
- [ ] Test all pages: homepage, about, contact, FAQ, tool pages
- [ ] Test settings modal and shortcuts
- [ ] Test language switcher in footer
- [ ] Verify URL routing works (`/{lang}/`)
- [ ] Run `npm run build` and verify `dist/{lang}/` folder is created
- [ ] Test that all tools load correctly
---
## Getting Help
If you have questions or need help:
1. Check existing translations in `public/locales/de/common.json` for reference
2. Open an issue on [GitHub](https://github.com/alam00000/bentopdf/issues)
3. Join our [Discord server](https://discord.gg/Bgq3Ay3f2w)
---
## Contributing Your Translation
Once you've completed a translation:
1. **Test thoroughly** (see [Testing Your Translations](#testing-your-translations))
2. **Fork the repository** on GitHub
3. **Create a new branch**: `git checkout -b add-french-translation`
4. **Commit your changes**: `git commit -m "Add French translation"`
5. **Push to your fork**: `git push origin add-french-translation`
6. **Open a Pull Request** with:
- Description of the language added
- Screenshots showing the translation in action
- Confirmation that you've tested all pages
Thank you for contributing to BentoPDF! 🎉
---
## Translation Progress
Current translation coverage:
| Language | Code | Status | Maintainer |
| ------------------- | ------- | -------------- | ---------- |
| English | `en` | ✅ Complete | Core team |
| German | `de` | ✅ Complete | Community |
| Spanish | `es` | ✅ Complete | Community |
| French | `fr` | ✅ Complete | Community |
| Italian | `it` | ✅ Complete | Community |
| Portuguese | `pt` | ✅ Complete | Community |
| Turkish | `tr` | ✅ Complete | Community |
| Vietnamese | `vi` | ✅ Complete | Community |
| Indonesian | `id` | ✅ Complete | Community |
| Chinese | `zh` | ✅ Complete | Community |
| Traditional Chinese | `zh-TW` | ✅ Complete | Community |
| Korean | `ko` | ✅ Complete | Community |
| Russian | `ru` | ✅ Complete | Community |
| Ukrainian | `uk` | ✅ Complete | Community |
| Slovak | `sk` | ✅ Complete | Community |
| Arabic | `ar` | ✅ Complete | Community |
| Dutch | `nl` | ✅ Complete | Community |
| Danish | `da` | ✅ Complete | Community |
| Swedish | `sv` | ✅ Complete | Community |
| Japanese | `ja` | ✅ Complete | Community |
| Persian (Farsi) | `fa` | ✅ Complete | Community |
| Your Language | `??` | 🚧 In Progress | You? |
---
**Last Updated**: June 2026
+339 -298
View File
@@ -3,335 +3,376 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>About Bentopdf - Fast, Private, and Free PDF Tools</title>
<!-- Primary Meta Tags -->
<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."
/>
<meta
name="keywords"
content="about bentopdf, privacy-first pdf, free pdf tools, browser-based pdf, open source pdf"
/>
<meta name="author" content="BentoPDF" />
<meta name="robots" content="index, follow" />
<!-- Canonical URL -->
<link rel="canonical" href="https://www.bentopdf.com/about" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/about" />
<meta
property="og:title"
content="About BentoPDF - Privacy-First Free PDF Tools"
/>
<meta
property="og:description"
content="100% free PDF toolkit. Privacy-first, browser-based, no signups. Learn about our mission and values."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-about.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="About BentoPDF" />
<meta
name="twitter:description"
content="Privacy-first, free PDF tools that run in your browser."
/>
<meta
name="twitter:image"
content="https://www.bentopdf.com/images/twitter-about.png"
/>
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" /> <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> </head>
<body class="antialiased bg-gray-900 text-gray-300"> <body class="lp antialiased">
<nav class="bg-gray-800 border-b border-gray-700 sticky top-0 z-30"> {{> navbar }}
<div class="container mx-auto px-4">
<div class="flex justify-between items-center h-16">
<div
class="flex-shrink-0 flex items-center cursor-pointer"
id="home-logo"
>
<img
src="images/favicon.svg"
alt="Bento PDF Logo"
class="h-8 w-8"
/>
<span class="text-white font-bold text-xl ml-2">
<a href="index.html">BentoPDF</a>
</span>
</div>
<!-- Desktop Navigation --> <div id="app">
<div class="hidden md:flex items-center space-x-8"> <section id="story-section" class="lp-sec lp-sec--first">
<a href="index.html" class="nav-link">Home</a> <div class="lp-frame">
<a href="./about.html" class="nav-link">About</a> <div class="lp-story">
<a href="./contact.html" class="nav-link">Contact</a> <div class="lp-story-head">
<a href="index.html#tools-header" class="nav-link">All Tools</a> <h1 class="lp-h2">
</div> <span class="line">Hi, I'm Alam.</span>
<span class="line dim">I build BentoPDF.</span>
<!-- Mobile Hamburger Button --> </h1>
<div class="md:hidden flex items-center"> <div class="lp-story-by">
<button <img
id="mobile-menu-button" class="lp-avatar"
type="button" src="/images/author-alam.jpg"
class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 transition-colors" alt="Alam"
aria-controls="mobile-menu" width="44"
aria-expanded="false" height="44"
>
<span class="sr-only">Open main menu</span>
<!-- Hamburger Icon -->
<svg
id="menu-icon"
class="block h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/> />
</svg> <a
<!-- Close Icon --> href="https://github.com/alam00000"
<svg target="_blank"
id="close-icon" rel="me noopener noreferrer"
class="hidden h-6 w-6" >GitHub</a
xmlns="http://www.w3.org/2000/svg" >
fill="none" <a
viewBox="0 0 24 24" href="https://www.linkedin.com/in/abdullah-alam01/"
stroke="currentColor" target="_blank"
aria-hidden="true" rel="me noopener noreferrer"
> >LinkedIn</a
<path >
stroke-linecap="round" <a
stroke-linejoin="round" href="https://x.com/alamdraws"
stroke-width="2" target="_blank"
d="M6 18L18 6M6 6l12 12" rel="me noopener noreferrer"
/> >X</a
</svg> >
</button> </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>
</div> <div class="lp-grid lp-grid--4 lp-cross">
</div> <div class="lp-cell lp-stat lp-cell--accent lp-reveal">
<b>15K+</b><span>GitHub stars</span>
<!-- Mobile Menu Dropdown --> </div>
<div <div class="lp-cell lp-stat lp-cell--white lp-reveal">
id="mobile-menu" <b>10M+</b><span>Downloads</span>
class="hidden md:hidden bg-gray-800 border-t border-gray-700" </div>
> <div class="lp-cell lp-stat lp-cell--hatch lp-reveal">
<div class="px-2 pt-2 pb-3 space-y-1 text-center"> <b>1.3K+</b><span>Forks</span>
<a href="index.html" class="mobile-nav-link">Home</a> </div>
<a href="./about.html" class="mobile-nav-link">About</a> <a
<a href="./contact.html" class="mobile-nav-link">Contact</a> href="https://github.com/alam00000/bentopdf/graphs/contributors"
<a href="index.html#tools-header" class="mobile-nav-link" target="_blank"
>All Tools</a rel="noopener noreferrer"
> class="lp-cell lp-stat lp-cell--raised lp-reveal lp-stat-link"
</div>
</div>
</nav>
<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">
We believe PDF tools should be
<span class="marker-slanted">fast, private, and free.</span>
</h1>
<p class="text-lg md:text-xl text-gray-400">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">
Our Mission
</h2>
<p class="text-lg text-gray-400 leading-relaxed">
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"
>Our Core Philosophy</span
> >
<h2 class="text-3xl md:text-4xl font-bold text-white mt-2 mb-4"> <b>60+</b
Privacy First. Always. ><span>Contributors <i data-lucide="arrow-up-right"></i></span>
</h2> </a>
<p class="text-gray-400 leading-relaxed"> </div>
In an era where data is a commodity, we take a different approach. <div class="lp-story-outro">
All processing for Bentopdf tools happens locally in your browser. <p>
This means your files never touch our servers, we never see your I don't build BentoPDF alone anymore. More than 60 people have
documents, and we don't track what you do. Your documents remain contributed code, translations and fixes, and thousands more have
completely and unequivocally private. It's not just a feature; starred it, shared it, reported bugs and asked for features. Thank
it's our foundation. you.
</p> </p>
<p>Enough about me. Here's more about BentoPDF.</p>
</div> </div>
<div class="flex justify-center"> </div>
<div class="relative w-48 h-48"> </section>
<div
class="absolute inset-0 bg-indigo-500 rounded-full opacity-20 animate-pulse" <section id="mission-section" class="lp-sec lp-band">
></div> <div class="lp-frame">
<div <figure class="lp-manifesto lp-reveal">
class="absolute inset-4 bg-indigo-500 rounded-full opacity-30 animate-pulse delay-500" <h2 class="lp-h2">
></div> <span class="line" data-i18n="about.mission.title">Our</span>
<i <span class="line dim" data-i18n="about.mission.titleDim"
data-lucide="shield-check" >Mission</span
class="w-48 h-48 text-indigo-400" >
></i> </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>
</div> </div>
</div> </section>
<section id="why-Bentopdf" class="py-16"> <section id="why-bentopdf" class="lp-sec lp-band">
<h2 class="text-3xl md:text-4xl font-bold text-center text-white mb-12"> <div class="lp-frame">
Why <span class="marker-slanted">Bentopdf?</span> <div class="lp-head lp-head--center">
</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>
<div> <div>
<h3 class="text-xl font-bold text-white">Built for Speed</h3> <h2 class="lp-h2">
<p class="text-gray-400 mt-2"> <span class="line" data-i18n="about.whyBentopdf.title"
No waiting for uploads or downloads to a server. By processing >Why</span
files directly in your browser using modern web technologies >
like WebAssembly, we offer unparalleled speed for all our tools. <span class="line dim">BentoPDF?</span>
</p> </h2>
</div> </div>
</div> </div>
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4"> <div class="lp-grid lp-grid--2 lp-cross">
<i <div class="lp-cell lp-reveal">
data-lucide="badge-dollar-sign" <span class="lp-tile"><i data-lucide="zap"></i></span>
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1" <h3 data-i18n="about.whyBentopdf.speed.title">Built for Speed</h3>
></i> <p data-i18n="about.whyBentopdf.speed.description">
<div> There's no upload or download step. Files are processed right in
<h3 class="text-xl font-bold text-white">Completely Free</h3> your browser using WebAssembly, so you're never waiting on a
<p class="text-gray-400 mt-2"> server.
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.
</p> </p>
</div> </div>
</div> <div class="lp-cell lp-reveal">
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4"> <span class="lp-tile"
<i ><i data-lucide="badge-dollar-sign"></i
data-lucide="user-plus" ></span>
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1" <h3 data-i18n="about.whyBentopdf.free.title">Free to Use</h3>
></i> <p data-i18n="about.whyBentopdf.free.description">
<div> Every tool is free, with no trials, no subscriptions and no
<h3 class="text-xl font-bold text-white">No Account Required</h3> watermarks. Development is funded by commercial licenses.
<p class="text-gray-400 mt-2">
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> </p>
</div> </div>
</div> <div class="lp-cell lp-reveal">
<div class="bg-gray-800 p-6 rounded-lg flex items-start gap-4"> <span class="lp-tile"><i data-lucide="user-plus"></i></span>
<i <h3 data-i18n="about.whyBentopdf.noAccount.title">
data-lucide="code-2" No Account Required
class="w-10 h-10 text-indigo-400 flex-shrink-0 mt-1" </h3>
></i> <p data-i18n="about.whyBentopdf.noAccount.description">
<div> Open any tool and start right away. No email, no password, no
<h3 class="text-xl font-bold text-white">Open Source Spirit</h3> personal information.
<p class="text-gray-400 mt-2"> </p>
Built with transparency in mind. We leverage incredible </div>
open-source libraries like PDF-lib and PDF.js, and believe in <div class="lp-cell lp-reveal">
the community-driven effort to make powerful tools accessible to <span class="lp-tile"><i data-lucide="code-2"></i></span>
everyone. <h3 data-i18n="about.whyBentopdf.openSource.title">
Open Source
</h3>
<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> </p>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<div class="section-divider"></div> <section id="cta-section" class="lp-sec">
<div class="lp-frame">
<section id="cta-section" class="text-center py-16"> <div class="lp-cta">
<h2 class="text-3xl font-bold text-white mb-4"> <h2 class="lp-h2" data-i18n="about.cta.title">
Ready to get started? Ready to get started?
</h2> </h2>
<p class="text-lg text-gray-400 mb-8 max-w-2xl mx-auto"> <p data-i18n="about.cta.description">
Join thousands of users who trust Bentopdf for their daily document Join thousands of users who trust BentoPDF for their daily
needs. Experience the difference that privacy and performance can document needs. Experience the difference that privacy and
make. performance can make.
</p> </p>
<a <div class="lp-cta-actions">
href="index.html#tools-header" <span class="lp-brackets">
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" <a
> href="index.html#tools-header"
Explore All Tools class="lp-btn lp-btn--primary"
</a> >
<span data-i18n="about.cta.button">Explore All Tools</span>
<i data-lucide="arrow-right"></i>
</a>
</span>
<a
href="https://www.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> </section>
</div> </div>
<footer class="mt-16 border-t-2 border-gray-700 py-8"> {{> footer }}
<div class="container mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8 text-center md:text-left">
<div class="mb-8 md:mb-0">
<div class="flex items-center justify-center md:justify-start mb-4">
<img src="images/favicon.svg" alt="Bento PDF Logo" class="h-10 w-10 mr-3" />
<span class="text-xl font-bold text-white">BentoPDF</span>
</div>
<p class="text-gray-400 text-sm">
&copy; 2025 BentoPDF. All rights reserved.
</p>
<p class="text-gray-500 text-xs mt-2">
Version <span id="app-version">1.6.2</span>
</p>
</div>
<div>
<h3 class="font-bold text-white mb-4">Company</h3>
<ul class="space-y-2 text-gray-400">
<li>
<a href="./about.html" class="hover:text-indigo-400">About Us</a>
</li>
<li>
<a href="./faq.html" class="hover:text-indigo-400">FAQ</a>
</li>
<li>
<a href="./contact.html" class="hover:text-indigo-400">Contact Us</a>
</li>
</ul>
</div>
<div>
<h3 class="font-bold text-white mb-4">Legal</h3>
<ul class="space-y-2 text-gray-400">
<li>
<a href="./terms.html" class="hover:text-indigo-400">Terms and Conditions</a>
</li>
<li>
<a href="./privacy.html" class="hover:text-indigo-400">Privacy Policy</a>
</li>
</ul>
</div>
<div>
<h3 class="font-bold text-white mb-4">Follow Us</h3>
<div class="flex justify-center md:justify-start space-x-4">
<a href="https://github.com/alam00000/bentopdf" target="_blank" rel="noopener noreferrer"
class="text-gray-400 hover:text-indigo-400" title="GitHub">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fill-rule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clip-rule="evenodd" />
</svg>
</a>
<a href="https://discord.gg/q42xWQmJ" target="_blank" rel="noopener noreferrer"
class="text-gray-400 hover:text-indigo-400" title="Discord">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z" />
</svg>
</a>
<a href="https://www.instagram.com/thebentopdf/" class="text-gray-400 hover:text-indigo-400"
title="Instagram">
<i data-lucide="instagram"></i>
</a>
<a href="https://www.linkedin.com/company/bentopdf/" class="text-gray-400 hover:text-indigo-400"
title="LinkedIn">
<i data-lucide="linkedin"></i>
</a>
<a href="https://x.com/BentoPDF" class="text-gray-400 hover:text-indigo-400" title="X (Twitter)">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</a>
</div>
</div>
</div>
</div>
</footer>
<script type="module" src="src/js/utils/lucide-init.ts"></script> <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/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": "AboutPage",
"name": "About BentoPDF",
"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> </body>
</html> </html>
+399
View File
@@ -0,0 +1,399 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advertise on BentoPDF - Homepage Logo Ads | BentoPDF</title>
<meta
name="description"
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
/>
<meta name="author" content="BentoPDF" />
<meta name="robots" content="index, follow" />
<link rel="canonical" href="https://www.bentopdf.com/advertise" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/advertise" />
<meta
property="og:title"
content="Advertise on BentoPDF - Homepage Logo Ads | BentoPDF"
/>
<meta
property="og:description"
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
/>
<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" />
<meta
name="twitter:title"
content="Advertise on BentoPDF - Homepage Logo Ads | BentoPDF"
/>
<meta
name="twitter:description"
content="Put your logo on the BentoPDF homepage. Eight slots, a flat monthly price and no tracking. From $129 a month, cancel anytime."
/>
<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" />
<link rel="manifest" href="/site.webmanifest" />
<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="ad-paid" class="lp-sec" hidden>
<div class="lp-frame">
<div class="lp-pad--tight">
<div class="lp-note">
<i data-lucide="circle-check"></i>
<p>
<strong>Payment received, thanks.</strong>
We review every ad and put it live within 24 hours. To change
anything, email
<a
href="mailto:[email protected]?subject=Ad%20for%20BentoPDF"
class="text-indigo-400 hover:underline"
>[email protected]</a
>.
</p>
</div>
</div>
</div>
</section>
<section id="ad-failed" class="lp-sec" hidden>
<div class="lp-frame">
<div class="lp-pad--tight">
<div class="lp-note">
<i data-lucide="circle-alert"></i>
<p>
<strong>Checkout didn't go through.</strong>
Nothing was charged. Try again below or email
<a
href="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
class="text-indigo-400 hover:underline"
>[email protected]</a
>.
</p>
</div>
</div>
</div>
</section>
<section id="advertise-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">Advertise on</span>
<span class="line dim">BentoPDF</span>
</h1>
<p class="lp-head-p">
Put your logo on the BentoPDF homepage, right above the tools
people open to work on their PDFs. Eight slots, a flat monthly
price, and no tracking of any kind.
</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="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
class="lp-btn lp-btn--ghost"
>
<i data-lucide="mail"></i>
<span>Email us</span>
</a>
</div>
</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">Pick a</span>
<span class="line dim">row</span>
</h2>
<p class="lp-head-p">
Billed monthly. Cancel anytime and your ad stays up until the
end of the month you paid for.
</p>
</div>
</div>
<div class="lp-grid lp-grid--2">
<div class="lp-cell lp-tier lp-cell--accent lp-reveal">
<h3>Top row</h3>
<p class="lp-tier-for">
Four slots, first in line above the tools
</p>
<div class="lp-tier-price"><b>$199</b><span>/ month</span></div>
<ul>
<li><i data-lucide="check"></i>Larger tile in the first row</li>
<li><i data-lucide="check"></i>Your logo, name and link</li>
<li>
<i data-lucide="check"></i>On every language version of the
homepage
</li>
<li><i data-lucide="check"></i>Cancel anytime</li>
</ul>
<a
href="https://www.bentopdf.com/api/ad-checkout?row=top"
class="lp-btn lp-btn--primary lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Book the top row</a
>
</div>
<div class="lp-cell lp-tier lp-reveal">
<h3>Second row</h3>
<p class="lp-tier-for">Four slots, right below the top row</p>
<div class="lp-tier-price"><b>$129</b><span>/ month</span></div>
<ul>
<li>
<i data-lucide="check"></i>Standard tile in the second row
</li>
<li><i data-lucide="check"></i>Your logo, name and link</li>
<li>
<i data-lucide="check"></i>On every language version of the
homepage
</li>
<li><i data-lucide="check"></i>Cancel anytime</li>
</ul>
<a
href="https://www.bentopdf.com/api/ad-checkout?row=second"
class="lp-btn lp-btn--ghost lp-btn--sm"
target="_blank"
rel="noopener noreferrer"
>Book the second row</a
>
</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">How it</span>
<span class="line dim">works</span>
</h2>
</div>
</div>
<div class="lp-grid lp-grid--3">
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="credit-card"></i></span>
<h3>Book a row</h3>
<p>
Checkout is handled by Dodo Payments, our merchant of record, so
you get a proper invoice with sales tax taken care of.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="image"></i></span>
<h3>Add your ad</h3>
<p>
Checkout asks for the name to show, your link, and a link to
your logo as a square SVG or PNG of at least 128 by 128 pixels.
</p>
</div>
<div class="lp-cell lp-reveal">
<span class="lp-tile"><i data-lucide="rocket"></i></span>
<h3>Go live</h3>
<p>
We review every ad by hand and put it live within 24 hours. Need
a new logo or link later? Just email us.
</p>
</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="eye-off"></i>
<p>
<strong
>We don't track our visitors, so we don't track your ad
either.</strong
>
No pixels, no scripts, no impression or click counts. Your logo
is served from bentopdf.com and links straight to your site. To
measure visits, add UTM parameters to your link and read them in
your own analytics.
</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>What can I advertise?</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>
Software, services and products that are useful to people
who work with documents. We don't accept gambling, adult
content, malware, or anything misleading. If we turn your ad
down, we refund you in full.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>Where does my ad show?</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>
On the bentopdf.com homepage, in every language, directly
above the tool grid. Self-hosted copies of BentoPDF never
show ads.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>Can you tell me how many people saw my ad?</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. BentoPDF has no analytics, so there are no impression or
click numbers to share. Add UTM parameters to your link to
see the visits we send you in your own analytics.
</p>
</div>
</div>
<div class="faq-item">
<button
class="faq-question w-full flex justify-between items-center text-left"
type="button"
>
<span>How do I cancel?</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>
Email us and we'll cancel your subscription. Your ad stays
up until the end of the month you paid for.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="lp-sec">
<div class="lp-frame">
<div class="lp-cta">
<h2 class="lp-h2">Questions before you book?</h2>
<p>Email us about slots, pricing or anything else.</p>
<div class="lp-cta-actions">
<span class="lp-brackets">
<a
href="mailto:[email protected]?subject=Advertise%20on%20BentoPDF"
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>
<script type="module" src="src/js/advertise.ts"></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Advertise on BentoPDF - Homepage Logo Ads | BentoPDF",
"url": "https://www.bentopdf.com/advertise"
}
</script>
</body>
</html>
+92
View File
@@ -0,0 +1,92 @@
const MODES = {
live: {
api: 'https://live.dodopayments.com',
products: new Map([
['top', 'pdt_0Nqv9McKI1iCBXb7z4DB7'],
['second', 'pdt_0Nqv9OYDLwWZsu1hzpZ0c'],
]),
},
test: {
api: 'https://test.dodopayments.com',
products: new Map([
['top', 'pdt_0Nqt0672sYJEtrkIb2K6m'],
['second', 'pdt_0Nqt069LgdQFPo1tFS1yF'],
]),
},
};
const FIELDS = [
{
key: 'ad_name',
label: 'Name on the ad',
field_type: 'text',
placeholder: 'Acme Invoices',
required: true,
},
{
key: 'ad_link',
label: 'Link',
field_type: 'url',
placeholder: 'https://example.com',
required: true,
},
{
key: 'ad_logo',
label: 'Logo link (square SVG or PNG)',
field_type: 'url',
placeholder: 'https://example.com/logo.svg',
required: true,
},
];
function redirect(location) {
return new Response(null, {
status: 303,
headers: { Location: location, 'Cache-Control': 'no-store' },
});
}
async function createCheckout(key, api, productId, page) {
const response = await fetch(`${api}/checkouts`, {
method: 'POST',
headers: {
Authorization: `Bearer ${key}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
product_cart: [{ product_id: productId, quantity: 1 }],
custom_fields: FIELDS,
return_url: `${page}?paid=1`,
cancel_url: `${page}#pricing`,
}),
signal: AbortSignal.timeout(10000),
});
const body = await response.text();
if (!response.ok) {
throw new Error(`Dodo returned ${response.status}: ${body}`);
}
const { checkout_url } = JSON.parse(body);
if (
typeof checkout_url !== 'string' ||
!checkout_url.startsWith('https://')
) {
throw new Error('Dodo returned no checkout URL');
}
return checkout_url;
}
export async function GET(request) {
const url = new URL(request.url);
const page = `${url.origin}/advertise`;
const key = process.env.DODO_PAYMENTS_API_KEY ?? '';
const mode = key.startsWith('dodo_live_') ? MODES.live : MODES.test;
const productId = mode.products.get(url.searchParams.get('row'));
if (!productId) return redirect(`${page}#pricing`);
try {
return redirect(await createCheckout(key, mode.api, productId, page));
} catch (error) {
console.error(error);
return redirect(`${page}?checkout=failed`);
}
}
Binary file not shown.
+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>
+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.
+152
View File
@@ -0,0 +1,152 @@
---
{
"title": "iLovePDF Alternative With No Uploads: BentoPDF vs iLovePDF",
"h1": "BentoPDF vs iLovePDF: a free iLovePDF alternative that doesn't upload your files",
"ogTitle": "iLovePDF Alternative With No Uploads: BentoPDF vs iLovePDF",
"breadcrumb": "iLovePDF alternative",
"description": "BentoPDF vs iLovePDF compared. BentoPDF is free, has no file limits and runs in your browser, so your PDFs are never uploaded. See where each one wins.",
"card": "BentoPDF vs iLovePDF side by side: uploads, free plan limits, offline use, and the tools you get for free.",
"date": "2026-10-28",
"cta": {
"heading": "Try it on your own PDF",
"text": "Free, no signup. Your file stays on your device.",
"href": "/",
"label": "Open BentoPDF"
}
}
---
If you're looking for an iLovePDF alternative, the biggest difference with BentoPDF is where your file goes.
iLovePDF uploads your PDF and processes it on its servers. BentoPDF processes it in your browser, on your own device. It's free, there's no account, and there's no cap on file size or the number of files.
I build BentoPDF, so keep that in mind. Whenever I say what iLovePDF does, I've linked to iLovePDF's own pages so you can check.
## Why people look for an iLovePDF alternative
iLovePDF is a good tool. People usually switch for one of these reasons:
- **Your file gets uploaded.** Every task sends the document to iLovePDF's servers. That's a problem for contracts, payslips and ID scans.
- **The free plan has limits.** Word to PDF takes one file of up to 15 MB. Merge stops at 25 files. That's from iLovePDF's [pricing page](https://www.ilovepdf.com/pricing).
- **Some tools are Premium only.** PDF to PDF/A, Workflows and the apps are all paid.
- **It doesn't work offline.** The work happens on a server, so the website needs a connection.
## BentoPDF vs iLovePDF: side by side
Here's how BentoPDF compares with iLovePDF's free plan:
| Feature | iLovePDF (free plan) | BentoPDF |
| --- | --- | --- |
| Where your file is processed | Uploaded to iLovePDF's servers | In your browser, never uploaded |
| Price | Free with limits, Premium is paid | Free, every tool |
| Word to PDF | 1 file, up to 15 MB | No cap on files or size |
| Merge PDF | Up to 25 files, 100 MB | No cap on files or size |
| Compress PDF | 2 files at a time | No cap on files |
| Edit PDF | 1 file | No cap on files |
| PDF to PDF/A | Premium only | Free |
| Workflows | Premium only | Free |
| Works offline | No (web version) | Yes, once a tool has loaded |
| Open source | No | Yes, AGPL |
| Run it on your own server | No | Yes, with Docker or as static files |
| Desktop and mobile apps | Premium only | No, browser only |
| What happens to your files | Deleted within two hours, signed documents kept up to five years | Never uploaded in the first place |
iLovePDF's limits come from its [pricing page](https://www.ilovepdf.com/pricing), and the file deletion details from its [security page](https://www.ilovepdf.com/help/security).
The only real limit in BentoPDF is your device's memory. A 500-page scan needs a lot more of it than a two-page letter.
## Your files never leave your device
iLovePDF's security page says processed files are "automatically and permanently deleted within two hours." It also says signed documents are kept "for a maximum of 5 years in compliance with legal requirements."
Two hours is reasonable. But "we delete your file later" is a weaker promise than "we never get your file."
BentoPDF's tools run in your browser using WebAssembly, so your PDF doesn't go anywhere. You can check this yourself:
1. Open your browser's developer tools and go to the Network tab.
2. Process a file in BentoPDF.
3. Watch the requests. Your PDF isn't in them.
Or load a tool, turn off Wi-Fi, and use it anyway.
## BentoPDF tools for the iLovePDF tools you use
Switching is easy. These are the BentoPDF versions of iLovePDF's most used tools:
| iLovePDF tool | BentoPDF tool |
| --- | --- |
| Merge PDF | [Merge PDF](/merge-pdf) |
| Split PDF | [Split PDF](/split-pdf) |
| Compress PDF | [Compress PDF](/compress-pdf) |
| PDF to Word | [PDF to Word](/pdf-to-word) |
| Word to PDF | [Word to PDF](/word-to-pdf) |
| PDF to Excel | [PDF to Excel](/pdf-to-excel) |
| Excel to PDF | [Excel to PDF](/excel-to-pdf) |
| PowerPoint to PDF | [PowerPoint to PDF](/powerpoint-to-pdf) |
| PDF to JPG | [PDF to JPG](/pdf-to-jpg) |
| JPG to PDF | [JPG to PDF](/jpg-to-pdf) |
| Edit PDF and Redact PDF | [Edit PDF](/edit-pdf) |
| Sign PDF | [Sign PDF](/sign-pdf) |
| OCR PDF | [OCR PDF](/ocr-pdf) |
| Organize PDF | [Organize PDF](/organize-pdf) |
| Rotate PDF | [Rotate PDF](/rotate-pdf) |
| Crop PDF | [Crop PDF](/crop-pdf) |
| Add page numbers | [Page Numbers](/page-numbers) |
| Add watermark | [Add Watermark](/add-watermark) |
| Protect PDF | [Protect PDF](/protect-pdf) |
| Unlock PDF | [Unlock PDF](/unlock-pdf) |
| Repair PDF | [Repair PDF](/repair-pdf) |
| Compare PDF | [Compare PDFs](/compare-pdfs) |
| PDF to PDF/A | [PDF to PDF/A](/pdf-to-pdfa) |
## Free tools you won't find on iLovePDF
BentoPDF has over 100 tools. These ones aren't in the tool list on iLovePDF's pricing page:
- **More file types to PDF:** [EPUB](/epub-to-pdf), [MOBI](/mobi-to-pdf), [Apple Pages](/pages-to-pdf), [Visio](/vsd-to-pdf), [XPS](/xps-to-pdf) and [Markdown](/markdown-to-pdf).
- **Certificate signatures:** [Digital Signature](/digital-sign-pdf) signs with your own X.509 certificate, and [Validate Signature](/validate-signature-pdf) checks whether a signed PDF was changed.
- **Legal and office work:** [Bates numbering](/bates-numbering), [table of contents](/table-of-contents) and [PDF booklets](/pdf-booklet).
- **Privacy clean-up:** [Sanitize PDF](/sanitize-pdf) and [Remove Metadata](/remove-metadata) strip out hidden content before you share a file.
- **Your own forms:** [Create PDF Form](/form-creator) adds real fillable fields to any PDF.
- **Automation:** the [Workflow Builder](/pdf-workflow) chains tools together, so you can run the same steps on every file.
## BentoPDF for teams and companies
Because BentoPDF runs in the browser, you can [host your own copy](/docs/self-hosting) for your whole team. Run it inside your company network with Docker, and nobody has to send files to an outside website.
If you want to put your own branding on it, or build it into a closed-source product, there's a [commercial license](/licensing). That's also what pays for the project.
## When iLovePDF is the better pick
I'd rather tell you now than have you find out later:
- **You need an app.** iLovePDF has desktop and mobile apps with Premium. BentoPDF only runs in the browser.
- **You need PDF to PowerPoint, AI summaries or translation.** BentoPDF doesn't have those.
- **You need team accounts.** iLovePDF's Business plan has team management, single sign-on and an account manager.
## Is there a free alternative to iLovePDF?
Yes. BentoPDF is free, with no account, no watermark and no cap on file size or the number of files. That includes the tools that are Premium on iLovePDF, like PDF to PDF/A and Workflows.
## Is iLovePDF safe to use?
iLovePDF is a legitimate service. Its security page says it uses HTTPS and encryption, holds ISO/IEC 27001 certification, and deletes processed files within two hours. The thing to know is that your file is uploaded to its servers. If you'd rather a file never leaves your device, use a tool that works in your browser, like BentoPDF.
## Does iLovePDF keep your files?
According to its security page, processed files are deleted automatically within two hours, and you can delete them sooner from the download screen. Signed documents are the exception. iLovePDF keeps those for up to five years for legal reasons.
## Is there an iLovePDF alternative that works offline?
Yes. Once a BentoPDF tool has loaded, it works without an internet connection, because the processing happens in your browser.
## Is there an open source alternative to iLovePDF?
Yes. BentoPDF is [open source](https://github.com/alam00000/bentopdf) under the AGPL, and you can run your own copy.
## Which one should you use?
If you need the apps, PDF to PowerPoint or the AI tools, use iLovePDF.
For everything else, try BentoPDF. Your files stay on your device, and you won't hit a limit halfway through a job.
If I've got something wrong about iLovePDF, [open an issue](https://github.com/alam00000/bentopdf/issues). I'll fix it and add a note to the post.
+157
View File
@@ -0,0 +1,157 @@
---
{
"title": "PDF24 Alternative With No Uploads: BentoPDF vs PDF24",
"h1": "BentoPDF vs PDF24: a PDF24 alternative that doesn't upload your files",
"ogTitle": "PDF24 Alternative With No Uploads: BentoPDF vs PDF24",
"breadcrumb": "PDF24 alternative",
"description": "BentoPDF vs PDF24 compared. Both are free with no limits, but PDF24 uploads your files to its servers. BentoPDF runs in your browser on Mac, Windows and Linux.",
"card": "BentoPDF vs PDF24 side by side: uploads, offline use on any computer, open source, and the tools you get for free.",
"date": "2026-10-28",
"cta": {
"heading": "Try it on your own PDF",
"text": "Free, no signup. Your file stays on your device.",
"href": "/",
"label": "Open BentoPDF"
}
}
---
If you're looking for a PDF24 alternative, the biggest difference with BentoPDF is where your file goes.
PDF24's online tools upload your PDF and process it on PDF24's servers. BentoPDF processes it in your browser, on your own device. Both are free, and neither needs an account.
I build BentoPDF, so keep that in mind. Whenever I say what PDF24 does, I've linked to PDF24's own pages so you can check.
## Why people look for a PDF24 alternative
PDF24 is a good, free tool. People usually look elsewhere for one of these reasons:
- **Your file gets uploaded.** PDF24's [FAQ](https://tools.pdf24.org/en/faq) says its online tools process files on its servers, which are in EU data centers.
- **The offline version is Windows only.** PDF24 Creator keeps files on your PC, but the FAQ says "Users of other operating systems should continue to use PDF24 Tools." On a Mac, Linux machine or Chromebook, that means uploading.
- **It's paid for with ads.** PDF24's own [homepage](https://tools.pdf24.org/en/) says the free tools are financed by advertising on its pages.
- **It isn't open source.** You can't check the code or run PDF24's online tools on your own server.
## BentoPDF vs PDF24: side by side
Here's how BentoPDF compares with PDF24's online tools:
| Feature | PDF24 online tools | BentoPDF |
| --- | --- | --- |
| Where your file is processed | Uploaded to PDF24's servers | In your browser, never uploaded |
| What happens to your files | Deleted from the server after one hour | Never uploaded in the first place |
| Price | Free | Free |
| Account needed | No | No |
| How it's paid for | Advertising on its pages | Commercial licenses |
| Works offline | Only with PDF24 Creator, on Windows | Yes, in your browser, once a tool has loaded |
| No-upload use on Mac, Linux or Chromebook | No | Yes |
| Open source | No | Yes, AGPL |
| Run it on your own server | No | Yes, with Docker or as static files |
| Workflow automation | No | Yes, the free [Workflow Builder](/pdf-workflow) |
PDF24's details come from its [FAQ](https://tools.pdf24.org/en/faq) and its [Merge PDF page](https://tools.pdf24.org/en/merge-pdf), which says "Files are automatically deleted from the PDF24 server after one hour."
## Your files never leave your device
One hour on a server in the EU is a decent policy. But "we delete your file after an hour" is still a weaker promise than "we never get your file."
BentoPDF's tools run in your browser using WebAssembly, so your PDF doesn't go anywhere. You can check this yourself:
1. Open your browser's developer tools and go to the Network tab.
2. Process a file in BentoPDF.
3. Watch the requests. Your PDF isn't in them.
Or load a tool, turn off Wi-Fi, and use it anyway. That works on a Mac, a Linux laptop or a Chromebook, not only on Windows.
## BentoPDF tools for the PDF24 tools you use
Switching is easy. These are the BentoPDF versions of PDF24's most used tools:
| PDF24 tool | BentoPDF tool |
| --- | --- |
| Merge PDF | [Merge PDF](/merge-pdf) |
| Split PDF | [Split PDF](/split-pdf) |
| Compress PDF | [Compress PDF](/compress-pdf) |
| Edit PDF and Annotate PDF | [Edit PDF](/edit-pdf) |
| Sign PDF | [Sign PDF](/sign-pdf) |
| PDF to Word | [PDF to Word](/pdf-to-word) |
| Word to PDF | [Word to PDF](/word-to-pdf) |
| PDF to Excel | [PDF to Excel](/pdf-to-excel) |
| Excel to PDF | [Excel to PDF](/excel-to-pdf) |
| PowerPoint to PDF | [PowerPoint to PDF](/powerpoint-to-pdf) |
| Images to PDF | [Image to PDF](/image-to-pdf) |
| PDF to JPG | [PDF to JPG](/pdf-to-jpg) |
| PDF to PNG | [PDF to PNG](/pdf-to-png) |
| PDF OCR | [OCR PDF](/ocr-pdf) |
| Rearrange PDF pages | [Organize PDF](/organize-pdf) |
| Remove PDF pages | [Delete Pages](/delete-pages) |
| Extract PDF pages | [Extract Pages](/extract-pages) |
| Rotate PDF pages | [Rotate PDF](/rotate-pdf) |
| Crop PDF | [Crop PDF](/crop-pdf) |
| Add page numbers | [Page Numbers](/page-numbers) |
| Add watermark | [Add Watermark](/add-watermark) |
| PDF Overlay | [Overlay PDF](/overlay-pdf) |
| Pages per sheet | [N-Up PDF](/n-up-pdf) |
| Create booklet | [PDF Booklet](/pdf-booklet) |
| Protect PDF | [Protect PDF](/protect-pdf) |
| Unlock PDF | [Unlock PDF](/unlock-pdf) |
| Redact PDF | [Edit PDF](/edit-pdf) |
| Fill out PDF | [PDF Form Filler](/form-filler) |
| Make PDF fillable | [Create PDF Form](/form-creator) |
| Flatten PDF | [Flatten PDF](/flatten-pdf) |
| Repair PDF | [Repair PDF](/repair-pdf) |
| PDF to PDF/A | [PDF to PDF/A](/pdf-to-pdfa) |
| Compare PDFs | [Compare PDFs](/compare-pdfs) |
| Verify PDF signatures | [Validate Signature](/validate-signature-pdf) |
| Remove PDF metadata | [Remove Metadata](/remove-metadata) |
| Web optimize PDF | [Linearize PDF](/linearize-pdf) |
## Free tools you won't find on PDF24
BentoPDF has over 100 tools. These ones aren't in PDF24's [list of all tools](https://tools.pdf24.org/en/all-tools):
- **More file types to PDF:** [MOBI](/mobi-to-pdf), [FB2](/fb2-to-pdf), [CBZ comics](/cbz-to-pdf), [Apple Pages](/pages-to-pdf), [Visio](/vsd-to-pdf), [XPS](/xps-to-pdf), [Photoshop PSD](/psd-to-pdf), [emails](/email-to-pdf) and [CSV](/csv-to-pdf).
- **Certificate signatures:** [Digital Signature](/digital-sign-pdf) signs with your own X.509 certificate, and [Timestamp PDF](/timestamp-pdf) adds a trusted timestamp.
- **Legal and office work:** [Bates numbering](/bates-numbering) and [table extraction](/extract-tables) into CSV, JSON or Markdown.
- **Scans:** [Deskew PDF](/deskew-pdf) straightens crooked pages, and [Remove Blank Pages](/remove-blank-pages) drops empty ones.
- **Double-sided scans:** [Duplex Collate](/duplex-collate) and [Alternate Merge](/alternate-merge) put fronts and backs back in page order.
- **Privacy clean-up:** [Sanitize PDF](/sanitize-pdf) strips scripts, metadata and other hidden content before you share a file.
- **Attachments:** [add](/add-attachments), [edit](/edit-attachments) or [extract](/extract-attachments) files embedded in a PDF.
- **Automation:** the [Workflow Builder](/pdf-workflow) chains tools together, so you can run the same steps on every file.
## BentoPDF for teams and companies
Because BentoPDF runs in the browser, you can [host your own copy](/docs/self-hosting) for your whole team. Run it inside your company network with Docker, and nobody has to send files to an outside website. It works the same on every computer, whatever operating system your staff use.
If you want to put your own branding on it, or build it into a closed-source product, there's a [commercial license](/licensing). That's also what pays for the project.
## When PDF24 is the better pick
- **You want a Windows desktop app.** PDF24 Creator is free and works offline on Windows. BentoPDF runs in the browser.
- **You need a tool BentoPDF doesn't have.** PDF24 can convert PDF to PowerPoint, EPUB and HTML, and it has e-invoice and invoice tools. BentoPDF doesn't do those.
## Is there a PDF24 alternative for Mac?
Yes. PDF24 Creator only runs on Windows, so on a Mac you'd be uploading files to PDF24's online tools. BentoPDF runs in Safari, Chrome or Firefox on a Mac, processes files on the Mac itself, and keeps working offline once a tool has loaded.
## Is PDF24 safe to use?
PDF24 is a legitimate service run by Geek Software GmbH, a German company. Its FAQ says its processing servers are in EU data centers and that uploaded files are deleted after one hour. The thing to know is that your file is uploaded to those servers. If you'd rather a file never leaves your device, use a tool that works in your browser, like BentoPDF.
## Is PDF24 really free?
Yes. PDF24's homepage says its tools are free without restrictions, paid for by advertising on its pages. BentoPDF is free too, and it's paid for by commercial licenses for companies.
## Does PDF24 work offline?
Only PDF24 Creator, the Windows desktop app. The online tools need a connection because they process files on PDF24's servers. BentoPDF works offline in your browser once a tool has loaded, on any operating system.
## Is there an open source alternative to PDF24?
Yes. BentoPDF is [open source](https://github.com/alam00000/bentopdf) under the AGPL, and you can run your own copy.
## Which one should you use?
If you're on Windows and want a desktop app, or you need PDF to PowerPoint or e-invoices, use PDF24.
For everything else, try BentoPDF. Your files stay on your device, on any computer.
If I've got something wrong about PDF24, [open an issue](https://github.com/alam00000/bentopdf/issues). I'll fix it and add a note to the post.
+23
View File
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
+16
View File
@@ -0,0 +1,16 @@
apiVersion: v2
name: bentopdf
description: BentoPDF static frontend served by NGINX
icon: https://raw.githubusercontent.com/spwoodcock/bentopdf/refs/heads/main/public/favicon.ico
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.10
# 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.11'
+100
View File
@@ -0,0 +1,100 @@
# BentoPDF Helm Chart
Deploys **BentoPDF** as a **single NGINX container** serving the static frontend.
## Quickstart
### Option 1: Port-forward (testing)
```bash
helm install bentopdf ./chart
kubectl port-forward deploy/bentopdf 8080:8080
# open http://127.0.0.1:8080
```
### Option 2: Ingress
```yaml
ingress:
enabled: true
className: nginx
hosts:
- host: bentopdf.example.com
paths:
- path: /
pathType: Prefix
```
### Option 3: Gateway API (Gateway + HTTPRoute)
```yaml
gateway:
enabled: true
gatewayClassName: 'cloudflare' # or your gateway class
httpRoute:
enabled: true
hostnames:
- pdfs.example.com
```
**Note:** Both Gateway and HTTPRoute default to the release namespace. Omit `namespace` fields to use the release namespace automatically.
If you have an existing Gateway, set `gateway.enabled=false` and configure `httpRoute.parentRefs`:
```yaml
gateway:
enabled: false
httpRoute:
enabled: true
parentRefs:
- name: existing-gateway
namespace: gateway-namespace
sectionName: http
hostnames:
- pdfs.example.com
```
## Configuration
### Image
- **`image.repository`**: container image repo (default: `ghcr.io/alam00000/bentopdf-simple`)
- **`image.tag`**: image tag (default: `Chart.appVersion`)
- **`image.pullPolicy`**: default `IfNotPresent`
### Ports
- **`containerPort`**: container listen port (**8080** for the BentoPDF nginx image)
- **`service.port`**: Service port exposed in-cluster (default **80**)
### Environment Variables
```yaml
env:
- name: DISABLE_IPV6
value: 'true'
```
## Publish this chart to GHCR (OCI) for testing/deploying
### Build And Push OCI
```bash
echo "$GHCR_TOKEN" | helm registry login ghcr.io -u "$GHCR_USERNAME" --password-stdin
cd chart
helm package .
# produces bentopdf-<version>.tgz
helm push bentopdf-*.tgz oci://ghcr.io/$GHCR_USERNAME/charts
```
This could be automated as part of a GitHub workflow.
### Deploy
```bash
helm upgrade --install bentopdf oci://ghcr.io/$GHCR_USERNAME/charts/bentopdf --version 1.0.0
```
+47
View File
@@ -0,0 +1,47 @@
1. Get the application URL by running these commands:
{{- if .Values.httpRoute.enabled }}
{{- $defaultGatewayName := .Values.gateway.name -}}
{{- if not $defaultGatewayName -}}
{{- $defaultGatewayName = printf "%s-gateway" (include "bentopdf.name" .) -}}
{{- end -}}
{{- $defaultGatewayNs := .Release.Namespace -}}
{{- if .Values.gateway.enabled -}}
{{- $defaultGatewayNs = default .Release.Namespace .Values.gateway.namespace -}}
{{- end -}}
{{- $gatewayName := $defaultGatewayName -}}
{{- $gatewayNs := $defaultGatewayNs -}}
{{- if and .Values.httpRoute.parentRefs (first .Values.httpRoute.parentRefs) -}}
{{- $firstRef := first .Values.httpRoute.parentRefs -}}
{{- $gatewayName = default $defaultGatewayName $firstRef.name -}}
{{- $gatewayNs = default $defaultGatewayNs $firstRef.namespace -}}
{{- end -}}
{{- if .Values.httpRoute.hostnames }}
export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }}
echo "Visit http://$APP_HOSTNAME to use your application"
{{- else }}
echo "HTTPRoute is enabled. Configure httpRoute.hostnames to see your URL here."
{{- end }}
NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules.
The rules can be set for path, method, header and query parameters.
You can check the gateway configuration with 'kubectl get --namespace {{ $gatewayNs }} gateway/{{ $gatewayName }} -o yaml'
{{- else if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "bentopdf.name" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "bentopdf.name" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "bentopdf.name" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "bentopdf.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
+33
View File
@@ -0,0 +1,33 @@
{{/*
Expand the name of the bentopdf
*/}}
{{- define "bentopdf.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "bentopdf.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "bentopdf.labels" -}}
helm.sh/chart: {{ include "bentopdf.chart" . }}
{{ include "bentopdf.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "bentopdf.selectorLabels" -}}
app.kubernetes.io/name: {{ include "bentopdf.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
+80
View File
@@ -0,0 +1,80 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "bentopdf.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "bentopdf.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "bentopdf.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: {{ .Values.containerPort }}
protocol: TCP
{{- with .Values.env }}
env:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: nginx-tmp
mountPath: /etc/nginx/tmp
- name: nginx-cache
mountPath: /var/cache/nginx
- name: nginx-run
mountPath: /var/run
{{- if .Values.extraVolumeMounts }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
volumes:
- name: nginx-tmp
emptyDir: {}
- name: nginx-cache
emptyDir: {}
- name: nginx-run
emptyDir: {}
{{- if .Values.extraVolumes }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- end }}
+22
View File
@@ -0,0 +1,22 @@
{{- if .Values.gateway.enabled -}}
{{- $gatewayName := .Values.gateway.name -}}
{{- if not $gatewayName -}}
{{- $gatewayName = printf "%s-gateway" (include "bentopdf.name" .) -}}
{{- end -}}
{{- $gatewayNs := default .Release.Namespace .Values.gateway.namespace -}}
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ $gatewayName }}
namespace: {{ $gatewayNs }}
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
{{- with .Values.gateway.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
gatewayClassName: {{ required "values.gateway.gatewayClassName is required when gateway.enabled=true" .Values.gateway.gatewayClassName }}
listeners:
{{- toYaml .Values.gateway.listeners | nindent 4 }}
{{- end }}
+52
View File
@@ -0,0 +1,52 @@
{{- if .Values.httpRoute.enabled -}}
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ include "bentopdf.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
{{- with .Values.httpRoute.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
parentRefs:
{{- if .Values.httpRoute.parentRefs }}
{{- range $ref := .Values.httpRoute.parentRefs }}
- name: {{ $.Values.gateway.name | default $ref.name | quote }}
namespace: {{ $ref.namespace | default (default $.Release.Namespace $.Values.gateway.namespace) | quote }}
sectionName: {{ $ref.sectionName | default "http" | quote }}
{{- with $ref.kind }}
kind: {{ . | quote }}
{{- end }}
{{- with $ref.group }}
group: {{ . | quote }}
{{- end }}
{{- end }}
{{- else }}
# Default parentRef when parentRefs is empty or not set
- name: {{ .Values.gateway.name | default (printf "%s-gateway" (include "bentopdf.name" $)) | quote }}
namespace: {{ .Values.gateway.namespace | default .Release.Namespace | quote }}
sectionName: "http"
{{- end }}
{{- with .Values.httpRoute.hostnames }}
hostnames:
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
{{- range .Values.httpRoute.rules }}
- {{- with .matches }}
matches:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .filters }}
filters:
{{- toYaml . | nindent 8 }}
{{- end }}
backendRefs:
- name: {{ include "bentopdf.name" $ }}
port: {{ $.Values.service.port }}
weight: 1
{{- end }}
{{- end }}
+44
View File
@@ -0,0 +1,44 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "bentopdf.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.ingress.className }}
ingressClassName: {{ . }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- with .pathType }}
pathType: {{ . }}
{{- end }}
backend:
service:
name: {{ include "bentopdf.name" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
+16
View File
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "bentopdf.name" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "bentopdf.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "bentopdf.name" . }}-test-connection"
labels:
{{- include "bentopdf.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['-qO-', 'http://{{ include "bentopdf.name" . }}:{{ .Values.service.port }}/']
restartPolicy: Never
+94
View File
@@ -0,0 +1,94 @@
# Default values for the BentoPDF chart (single nginx static frontend).
replicaCount: 1
image:
# Image built from this repo's `Dockerfile` (nginx serving static frontend).
repository: ghcr.io/alam00000/bentopdf-simple
pullPolicy: IfNotPresent
tag: ''
imagePullSecrets: []
nameOverride: ''
podAnnotations: {}
podLabels: {}
service:
type: ClusterIP
port: 80
# Container listen port (BentoPDF nginx image listens on 8080).
containerPort: 8080
env: []
ingress:
enabled: false
className: ''
annotations: {}
hosts:
- host: bentopdf.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# Gateway API (optional)
gateway:
enabled: false
name: '' # default: release name + "-gateway" suffix
namespace: '' # to override the namespace
annotations: {}
gatewayClassName: '' # required when enabled=true
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same # Allow routes from the same namespace
httpRoute:
enabled: false
annotations: {}
# parentRefs: # Omit entirely to use default (auto-references gateway in same namespace)
# - name: "" # default: gateway.name or {release-name}-gateway
# namespace: "" # to override the namespace
# sectionName: "http"
hostnames:
- bentopdf.local
rules:
- matches:
- path:
type: PathPrefix
value: /
podSecurityContext:
runAsNonRoot: true
runAsUser: 101
runAsGroup: 101
fsGroup: 101
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
resources: {}
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
extraVolumes: []
extraVolumeMounts: []
+104
View File
@@ -0,0 +1,104 @@
# WASM Proxy Setup Guide
BentoPDF uses a Cloudflare Worker to proxy WASM library requests, bypassing CORS restrictions when loading AGPL-licensed components (PyMuPDF, Ghostscript, CoherentPDF) from external sources.
## Quick Start
### 1. Deploy the Worker
```bash
cd cloudflare
npx wrangler login
npx wrangler deploy -c wasm-wrangler.toml
```
### 2. Configure Source URLs
Set environment secrets with the base URLs for your WASM files:
```bash
# Option A: Interactive prompts
npx wrangler secret put PYMUPDF_SOURCE -c wasm-wrangler.toml
npx wrangler secret put GS_SOURCE -c wasm-wrangler.toml
npx wrangler secret put CPDF_SOURCE -c wasm-wrangler.toml
# Option B: Set via Cloudflare Dashboard
# Go to Workers & Pages > bentopdf-wasm-proxy > Settings > Variables
```
**Recommended Source URLs:**
- PYMUPDF_SOURCE: `https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/`
- GS_SOURCE: `https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm/assets/`
- CPDF_SOURCE: `https://cdn.jsdelivr.net/npm/coherentpdf/dist/`
> **Note:** You can use your own hosted WASM files instead of the recommended URLs. Just ensure your files match the expected directory structure and file names that BentoPDF expects for each module.
### 3. Configure BentoPDF
**Option A: Environment variables (recommended — zero-config for users)**
Set these in `.env.production` or pass as Docker build args:
```bash
VITE_WASM_PYMUPDF_URL=https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/pymupdf/
VITE_WASM_GS_URL=https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/gs/
VITE_WASM_CPDF_URL=https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/cpdf/
```
**Option B: Manual per-user configuration**
In BentoPDF's Advanced Settings (wasm-settings.html), enter:
| Module | URL |
| ----------- | ------------------------------------------------------------------- |
| PyMuPDF | `https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/pymupdf/` |
| Ghostscript | `https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/gs/` |
| CoherentPDF | `https://bentopdf-wasm-proxy.<your-subdomain>.workers.dev/cpdf/` |
## Custom Domain (Optional)
To use a custom domain like `wasm.bentopdf.com`:
1. Add route in `wasm-wrangler.toml`:
```toml
routes = [
{ pattern = "wasm.bentopdf.com/*", zone_name = "bentopdf.com" }
]
```
2. Add DNS record in Cloudflare:
- Type: AAAA
- Name: wasm
- Content: 100::
- Proxied: Yes
3. Redeploy:
```bash
npx wrangler deploy -c wasm-wrangler.toml
```
## Security Features
- **Origin validation**: Only allows requests from configured origins
- **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
## Self-Hosting Notes
1. Update `ALLOWED_ORIGINS` in `wasm-proxy-worker.js` to include your domain
2. Host your WASM files on any origin (R2, S3, or any CDN)
3. Set source URLs as secrets in your worker
## Endpoints
| Endpoint | Description |
| ------------ | -------------------------------------- |
| `/` | Health check, shows configured modules |
| `/pymupdf/*` | PyMuPDF WASM files |
| `/gs/*` | Ghostscript WASM files |
| `/cpdf/*` | CoherentPDF files |
+671
View File
@@ -0,0 +1,671 @@
/**
* BentoPDF CORS Proxy Worker
*
* This Cloudflare Worker proxies certificate requests for the digital signing tool.
* It fetches certificates from external CAs that don't have CORS headers enabled
* and returns them with proper CORS headers.
*
*
* Deploy: npx wrangler deploy
*
* Required Environment Variables (set in wrangler.toml or Cloudflare dashboard):
* - PROXY_SECRET: Shared secret for HMAC signature verification
*/
const ALLOWED_PATH_PATTERNS = [
/\.(crt|cer|pem|der|p7c|p7b)$/i,
/(^|\/)certs(\/|$)/i,
/(^|\/)ocsp(\/|$)/i,
/(^|\/)crl(\/|$)/i,
/(^|\/)caissuers(\/|$)/i,
];
const ALLOWED_TSA_HOSTS = new Set([
'timestamp.digicert.com',
'timestamp.sectigo.com',
'ts.ssl.com',
'freetsa.org',
'tsa.mesign.com',
]);
const ALLOWED_ORIGINS = ['https://www.bentopdf.com', 'https://bentopdf.com'];
const SAFE_CONTENT_TYPES = [
'application/x-x509-ca-cert',
'application/pkix-cert',
'application/x-pem-file',
'application/pkcs7-mime',
'application/octet-stream',
'application/timestamp-reply',
'text/plain',
];
const MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1000;
const RATE_LIMIT_MAX_REQUESTS = 60;
const RATE_LIMIT_WINDOW_MS = 60 * 1000;
const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
let warnedNoProxySecret = false;
async function verifySignature(message, signature, secret) {
try {
const encoder = new TextEncoder();
const key = await crypto.subtle.importKey(
'raw',
encoder.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
);
const signatureBytes = new Uint8Array(
signature.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
);
return await crypto.subtle.verify(
'HMAC',
key,
signatureBytes,
encoder.encode(message)
);
} catch (e) {
console.error('Signature verification error:', e);
return false;
}
}
function isAllowedOrigin(origin) {
if (!origin) return false;
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) {
const host = hostname
.toLowerCase()
.replace(/^\[|\]$/g, '')
.replace(/\.$/, '');
if (['localhost', 'localhost.localdomain'].includes(host)) {
return true;
}
return isIpLiteral(host) && isBlockedIp(host);
}
async function hostnameResolvesToPrivate(hostname) {
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 {
const res = await fetch(
`https://1.1.1.1/dns-query?name=${encodeURIComponent(clean)}&type=${type}`,
{ headers: { accept: 'application/dns-json' } }
);
if (!res.ok) return true;
const data = await res.json();
for (const ans of data.Answer || []) {
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) => isBlockedIp(ip));
}
function isValidCertificateUrl(urlString) {
try {
const url = new URL(urlString);
if (!['http:', 'https:'].includes(url.protocol)) {
return false;
}
if (isPrivateOrReservedHost(url.hostname)) {
return false;
}
return ALLOWED_PATH_PATTERNS.some((pattern) => pattern.test(url.pathname));
} catch {
return false;
}
}
function isValidTsaUrl(urlString) {
try {
const url = new URL(urlString);
if (!['http:', 'https:'].includes(url.protocol)) return false;
if (isPrivateOrReservedHost(url.hostname)) return false;
return ALLOWED_TSA_HOSTS.has(url.hostname);
} catch {
return false;
}
}
function getSafeContentType(upstreamContentType) {
if (!upstreamContentType) return 'application/octet-stream';
const match = SAFE_CONTENT_TYPES.find((ct) =>
upstreamContentType.startsWith(ct)
);
return match || 'application/octet-stream';
}
function corsHeaders(origin) {
return {
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Max-Age': '86400',
};
}
function handleOptions(request) {
const origin = request.headers.get('Origin');
if (!isAllowedOrigin(origin)) {
return new Response(null, { status: 403 });
}
return new Response(null, {
status: 204,
headers: corsHeaders(origin),
});
}
export default {
async fetch(request, env) {
const url = new URL(request.url);
const origin = request.headers.get('Origin');
if (request.method === 'OPTIONS') {
return handleOptions(request);
}
// NOTE: If you are selfhosting this proxy, you can remove this check, or can set it to only accept requests from your own domain
// SECURITY: The Origin allow-list and the optional PROXY_SECRET HMAC are anti-abuse controls, NOT a security boundary — the Origin
// header is forgeable by non-browser clients and the HMAC secret ships in the public client bundle. The real SSRF defense is the
// private/reserved-IP resolution check (hostnameResolvesToPrivate). Deployments running this off Cloudflare cannot fully close the
// DNS-rebinding gap in code and MUST add network egress filtering (see docs/self-hosting/cors-proxy.md).
if (!isAllowedOrigin(origin)) {
return new Response(
JSON.stringify({
error: 'Forbidden',
message: 'This proxy only accepts requests from allowed origins',
}),
{
status: 403,
headers: {
'Content-Type': 'application/json',
},
}
);
}
if (request.method !== 'GET' && request.method !== 'POST') {
return new Response('Method not allowed', {
status: 405,
headers: corsHeaders(origin),
});
}
const targetUrl = url.searchParams.get('url');
if (!targetUrl) {
return new Response(
JSON.stringify({
error: 'Missing url parameter',
usage: 'GET /?url=<certificate_url> or POST /?url=<tsa_url>',
}),
{
status: 400,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const requestContentType = request.headers.get('Content-Type') || '';
const isTsaQuery =
request.method === 'POST' &&
requestContentType === 'application/timestamp-query';
if (isTsaQuery) {
if (!isValidTsaUrl(targetUrl)) {
return new Response(
JSON.stringify({
error: 'Disallowed TSA host',
message: `Only known RFC 3161 TSA hosts are accepted: ${[...ALLOWED_TSA_HOSTS].join(', ')}`,
}),
{
status: 403,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
} else if (!isValidCertificateUrl(targetUrl)) {
return new Response(
JSON.stringify({
error: 'Invalid or disallowed URL',
message:
'Only certificate-related URLs are allowed (*.crt, *.cer, *.pem, /certs/, /ocsp, /crl)',
}),
{
status: 403,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
if (env.PROXY_SECRET) {
const timestamp = url.searchParams.get('t');
const signature = url.searchParams.get('sig');
if (!timestamp || !signature) {
return new Response(
JSON.stringify({
error: 'Missing authentication parameters',
message:
'Request must include timestamp (t) and signature (sig) parameters',
}),
{
status: 401,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const requestTime = parseInt(timestamp, 10);
const now = Date.now();
if (
isNaN(requestTime) ||
requestTime > now + 60000 ||
now - requestTime > MAX_TIMESTAMP_AGE_MS
) {
return new Response(
JSON.stringify({
error: 'Request expired or invalid timestamp',
message: 'Timestamp must be within 5 minutes of current time',
}),
{
status: 401,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const message = `${targetUrl}${timestamp}`;
const isValid = await verifySignature(
message,
signature,
env.PROXY_SECRET
);
if (!isValid) {
return new Response(
JSON.stringify({
error: 'Invalid signature',
message: 'Request signature verification failed',
}),
{
status: 401,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
} else if (!warnedNoProxySecret) {
warnedNoProxySecret = true;
console.warn(
'[CORS Proxy] PROXY_SECRET is not set — request signatures are not verified, so the proxy is callable by any client that can ' +
'send an allowed Origin header. Set PROXY_SECRET to deter casual abuse (note: it ships in the public client bundle, so it is ' +
'not a real authentication boundary), and add network egress filtering if running off Cloudflare.'
);
}
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown';
const rateLimitKey = `ratelimit:${getRateLimitKey(clientIP)}`;
const now = Date.now();
if (env.RATE_LIMIT_KV) {
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. 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(
(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
);
}
} else {
console.warn(
'[CORS Proxy] RATE_LIMIT_KV not configured — rate limiting is disabled'
);
}
let targetHostname;
try {
targetHostname = new URL(targetUrl).hostname;
} catch {
targetHostname = '';
}
if (!targetHostname || (await hostnameResolvesToPrivate(targetHostname))) {
return new Response(
JSON.stringify({
error: 'Forbidden destination',
message: 'The requested host is not permitted',
}),
{
status: 403,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
try {
const upstreamInit = {
method: request.method,
redirect: 'manual',
signal: AbortSignal.timeout(10000),
headers: {
'User-Agent': 'BentoPDF-CertProxy/1.0',
},
};
if (isTsaQuery) {
upstreamInit.headers['Content-Type'] = 'application/timestamp-query';
upstreamInit.body = await request.arrayBuffer();
}
const response = await fetch(targetUrl, upstreamInit);
if (response.status >= 300 && response.status < 400) {
return new Response(
JSON.stringify({
error: 'Redirect blocked',
message: 'Upstream redirects are not allowed',
}),
{
status: 502,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
if (!response.ok) {
return new Response(
JSON.stringify({
error: 'Failed to fetch certificate',
status: response.status,
}),
{
status: response.status,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
// Check Content-Length header first (fast reject for known-large responses)
const contentLength = parseInt(
response.headers.get('Content-Length') || '0',
10
);
if (contentLength > MAX_FILE_SIZE_BYTES) {
return new Response(
JSON.stringify({
error: 'File too large',
message: `Certificate file exceeds maximum size of ${MAX_FILE_SIZE_BYTES / 1024}KB`,
}),
{
status: 413,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const reader = response.body.getReader();
const chunks = [];
let totalSize = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
totalSize += value.byteLength;
if (totalSize > MAX_FILE_SIZE_BYTES) {
reader.cancel();
return new Response(
JSON.stringify({
error: 'File too large',
message: `Certificate file exceeds maximum size of ${MAX_FILE_SIZE_BYTES / 1024}KB`,
}),
{
status: 413,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
chunks.push(value);
}
const certData = new Uint8Array(totalSize);
let offset = 0;
for (const chunk of chunks) {
certData.set(chunk, offset);
offset += chunk.byteLength;
}
return new Response(certData, {
status: 200,
headers: {
...corsHeaders(origin),
'Content-Type': getSafeContentType(
response.headers.get('Content-Type')
),
'Content-Length': totalSize.toString(),
'Cache-Control': 'no-store',
'X-Content-Type-Options': 'nosniff',
},
});
} catch (error) {
console.error('Proxy fetch error:', error);
return new Response(
JSON.stringify({
error: 'Proxy error',
message: 'Failed to fetch the requested certificate',
}),
{
status: 500,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
},
};
+417
View File
@@ -0,0 +1,417 @@
/**
* BentoPDF WASM Proxy Worker
*
* This Cloudflare Worker proxies WASM module requests to bypass CORS restrictions.
* It fetches WASM libraries (PyMuPDF, Ghostscript, CoherentPDF) from configured sources
* and serves them with proper CORS headers.
*
* Endpoints:
* - /pymupdf/* - Proxies to PyMuPDF WASM source
* - /gs/* - Proxies to Ghostscript WASM source
* - /cpdf/* - Proxies to CoherentPDF WASM source
*
* Deploy: cd cloudflare && npx wrangler deploy -c wasm-wrangler.toml
*
* Required Environment Variables (set in Cloudflare dashboard):
* - PYMUPDF_SOURCE: Base URL for PyMuPDF WASM files (e.g., https://cdn.example.com/pymupdf)
* - GS_SOURCE: Base URL for Ghostscript WASM files (e.g., https://cdn.example.com/gs)
* - CPDF_SOURCE: Base URL for CoherentPDF files (e.g., https://cdn.example.com/cpdf)
*/
const ALLOWED_ORIGINS = ['https://www.bentopdf.com', 'https://bentopdf.com'];
const MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024;
const RATE_LIMIT_MAX_REQUESTS = 100;
const RATE_LIMIT_WINDOW_MS = 60 * 1000;
const CACHE_TTL_SECONDS = 604800;
const ALLOWED_EXTENSIONS = [
'.js',
'.mjs',
'.wasm',
'.data',
'.py',
'.so',
'.zip',
'.json',
'.mem',
'.asm.js',
'.worker.js',
'.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) =>
origin.startsWith(allowed.replace(/\/$/, ''))
);
}
function isAllowedFile(pathname) {
const ext = pathname.substring(pathname.lastIndexOf('.')).toLowerCase();
if (ALLOWED_EXTENSIONS.includes(ext)) return true;
if (!pathname.includes('.') || pathname.endsWith('/')) return true;
return false;
}
function corsHeaders(origin) {
return {
'Access-Control-Allow-Origin': origin || '*',
'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Range, Cache-Control',
'Access-Control-Expose-Headers':
'Content-Length, Content-Range, Content-Type',
'Access-Control-Max-Age': '86400',
'X-Content-Type-Options': 'nosniff',
};
}
function handleOptions(request) {
const origin = request.headers.get('Origin');
return new Response(null, {
status: 204,
headers: corsHeaders(origin),
});
}
function getContentType(pathname) {
const ext = pathname.substring(pathname.lastIndexOf('.')).toLowerCase();
const contentTypes = {
'.js': 'application/javascript',
'.mjs': 'application/javascript',
'.wasm': 'application/wasm',
'.json': 'application/json',
'.data': 'application/octet-stream',
'.py': 'text/x-python',
'.so': 'application/octet-stream',
'.zip': 'application/zip',
'.mem': 'application/octet-stream',
};
return contentTypes[ext] || 'application/octet-stream';
}
async function proxyRequest(request, env, sourceBaseUrl, subpath, origin) {
if (!sourceBaseUrl) {
return new Response(
JSON.stringify({
error: 'Source not configured',
message: 'This WASM module source URL has not been configured.',
}),
{
status: 503,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const normalizedBase = sourceBaseUrl.endsWith('/')
? sourceBaseUrl.slice(0, -1)
: sourceBaseUrl;
const normalizedPath = subpath.startsWith('/') ? subpath : `/${subpath}`;
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(
JSON.stringify({
error: 'Forbidden file type',
message: 'Only WASM-related file types are allowed.',
}),
{
status: 403,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
try {
const cacheKey = new Request(targetUrl, request);
const cache = caches.default;
let response = await cache.match(cacheKey);
if (!response) {
response = await fetch(targetUrl, {
headers: {
'User-Agent': 'BentoPDF-WASM-Proxy/1.0',
Accept: '*/*',
},
});
if (!response.ok) {
return new Response(
JSON.stringify({
error: 'Failed to fetch resource',
status: response.status,
}),
{
status: response.status,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
const contentLength = parseInt(
response.headers.get('Content-Length') || '0',
10
);
if (contentLength > MAX_FILE_SIZE_BYTES) {
return new Response(
JSON.stringify({
error: 'File too large',
message: `File exceeds maximum size of ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB`,
}),
{
status: 413,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
response = new Response(response.body, response);
response.headers.set(
'Cache-Control',
`public, max-age=${CACHE_TTL_SECONDS}`
);
if (response.status === 200) {
await cache.put(cacheKey, response.clone());
}
}
const bodyData = await response.arrayBuffer();
return new Response(bodyData, {
status: 200,
headers: {
...corsHeaders(origin),
'Content-Type': getContentType(normalizedPath),
'Content-Length': bodyData.byteLength.toString(),
'Cache-Control': `public, max-age=${CACHE_TTL_SECONDS}`,
},
});
} catch (error) {
console.error('[WASM Proxy] Fetch error:', error);
return new Response(
JSON.stringify({
error: 'Proxy error',
message: 'Failed to fetch the requested resource',
}),
{
status: 500,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
}
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const pathname = url.pathname;
const origin = request.headers.get('Origin');
if (request.method === 'OPTIONS') {
return handleOptions(request);
}
if (!isAllowedOrigin(origin)) {
return new Response(
JSON.stringify({
error: 'Forbidden',
message:
'Origin not allowed. Add your domain to ALLOWED_ORIGINS if self-hosting.',
}),
{
status: 403,
headers: {
'Content-Type': 'application/json',
...corsHeaders(origin),
},
}
);
}
if (request.method !== 'GET' && request.method !== 'HEAD') {
return new Response('Method not allowed', {
status: 405,
headers: corsHeaders(origin),
});
}
if (env.RATE_LIMIT_KV) {
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown';
const rateLimitKey = `wasm-ratelimit:${getRateLimitKey(clientIP)}`;
const now = Date.now();
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.`,
}),
{
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 }),
{
expirationTtl: 120,
}
);
} catch (error) {
console.error(
'[WASM Proxy] Rate limit KV error, allowing request:',
error
);
}
}
if (pathname.startsWith('/pymupdf/')) {
const subpath = pathname.replace('/pymupdf', '');
return proxyRequest(request, env, env.PYMUPDF_SOURCE, subpath, origin);
}
if (pathname.startsWith('/gs/')) {
const subpath = pathname.replace('/gs', '');
return proxyRequest(request, env, env.GS_SOURCE, subpath, origin);
}
if (pathname.startsWith('/cpdf/')) {
const subpath = pathname.replace('/cpdf', '');
return proxyRequest(request, env, env.CPDF_SOURCE, subpath, origin);
}
if (pathname === '/' || pathname === '/health') {
return new Response(
JSON.stringify({
service: 'BentoPDF WASM Proxy',
version: '1.0.0',
endpoints: {
pymupdf: '/pymupdf/*',
gs: '/gs/*',
cpdf: '/cpdf/*',
},
configured: {
pymupdf: !!env.PYMUPDF_SOURCE,
gs: !!env.GS_SOURCE,
cpdf: !!env.CPDF_SOURCE,
},
}),
{
status: 200,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
}
return new Response(
JSON.stringify({
error: 'Not Found',
message: 'Use /pymupdf/*, /gs/*, or /cpdf/* endpoints',
}),
{
status: 404,
headers: {
...corsHeaders(origin),
'Content-Type': 'application/json',
},
}
);
},
};
+69
View File
@@ -0,0 +1,69 @@
name = "bentopdf-wasm-proxy"
main = "wasm-proxy-worker.js"
compatibility_date = "2024-01-01"
# =============================================================================
# DEPLOYMENT
# =============================================================================
# Deploy this worker:
# cd cloudflare
# npx wrangler deploy -c wasm-wrangler.toml
#
# Set environment secrets (one of the following methods):
# Option A: Cloudflare Dashboard
# Go to Workers & Pages > bentopdf-wasm-proxy > Settings > Variables
# Add: PYMUPDF_SOURCE, GS_SOURCE, CPDF_SOURCE
#
# Option B: Wrangler CLI
# npx wrangler secret put PYMUPDF_SOURCE -c wasm-wrangler.toml
# npx wrangler secret put GS_SOURCE -c wasm-wrangler.toml
# npx wrangler secret put CPDF_SOURCE -c wasm-wrangler.toml
# =============================================================================
# WASM SOURCE URLS
# =============================================================================
# Set these as secrets in the Cloudflare dashboard or via wrangler:
#
# PYMUPDF_SOURCE: Base URL to PyMuPDF WASM files
# Example: https://cdn.jsdelivr.net/npm/@bentopdf/pymupdf-wasm/assets
# https://your-bucket.r2.cloudflarestorage.com/pymupdf
#
# GS_SOURCE: Base URL to Ghostscript WASM files
# Example: https://cdn.jsdelivr.net/npm/@bentopdf/gs-wasm/assets
# https://your-bucket.r2.cloudflarestorage.com/gs
#
# CPDF_SOURCE: Base URL to CoherentPDF files
# Example: https://cdn.jsdelivr.net/npm/coherentpdf/cpdf
# https://your-bucket.r2.cloudflarestorage.com/cpdf
# =============================================================================
# USAGE FROM BENTOPDF
# =============================================================================
# In BentoPDF's WASM Settings page, configure URLs like:
# PyMuPDF: https://wasm.bentopdf.com/pymupdf/
# Ghostscript: https://wasm.bentopdf.com/gs/
# CoherentPDF: https://wasm.bentopdf.com/cpdf/
# =============================================================================
# RATE LIMITING (Optional but recommended)
# =============================================================================
# Create KV namespace:
# npx wrangler kv namespace create "RATE_LIMIT_KV"
#
# Then uncomment and update the ID below:
# [[kv_namespaces]]
# binding = "RATE_LIMIT_KV"
# id = "<YOUR_KV_NAMESPACE_ID>"
# Use the same KV namespace as the CORS proxy if you want shared rate limiting
[[kv_namespaces]]
binding = "RATE_LIMIT_KV"
id = "b88e030b308941118cd484e3fcb3ae49"
# =============================================================================
# CUSTOM DOMAIN (Optional)
# =============================================================================
# If you want a custom domain like wasm.bentopdf.com:
# routes = [
# { pattern = "wasm.bentopdf.com/*", zone_name = "bentopdf.com" }
# ]
+45
View File
@@ -0,0 +1,45 @@
name = "bentopdf-cors-proxy"
main = "cors-proxy-worker.js"
compatibility_date = "2024-01-01"
# Deploy to Cloudflare's global network
# If you are self-hosting, change the name to your worker name
# Run: npx wrangler deploy
# =============================================================================
# SECURITY FEATURES
# =============================================================================
#
# 1. SIGNATURE VERIFICATION (Optional - for anti-spoofing)
# - Generate secret: openssl rand -hex 32
# - Set secret: npx wrangler secret put PROXY_SECRET
# - Note: Secret is visible in frontend JS, so provides limited protection
#
# 2. RATE LIMITING (Recommended - requires KV)
# - Create KV namespace: npx wrangler kv namespace create "RATE_LIMIT_KV"
# - Uncomment the kv_namespaces section below with the returned ID
# - Limits: 60 requests per IP per minute
#
# 3. FILE SIZE LIMIT
# - Automatic: Rejects files larger than 1MB
# - Certificates are typically <10KB, so this prevents abuse
#
# 4. URL RESTRICTIONS
# - Only certificate URLs allowed (*.crt, *.cer, *.pem, /certs/, etc.)
# - Blocks private IPs (localhost, 10.x, 192.168.x, 172.16-31.x)
# =============================================================================
# KV NAMESPACE FOR RATE LIMITING
# =============================================================================
[[kv_namespaces]]
binding = "RATE_LIMIT_KV"
id = "b88e030b308941118cd484e3fcb3ae49"
# Optional: Custom domain routing
# routes = [
# { pattern = "cors-proxy.bentopdf.com/*", zone_name = "bentopdf.com" }
# ]
# Optional: Environment variables (for non-secret config)
# [vars]
# ALLOWED_ORIGINS = "https://www.bentopdf.com,https://bentopdf.com"
+146 -186
View File
@@ -3,207 +3,167 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contact Us - BentoPDF</title> <!-- Primary Meta Tags -->
<title>Contact BentoPDF - Get in Touch | Support</title>
<meta
name="description"
content="Contact BentoPDF for support, questions, or feedback. Reach us at [email protected] - we're here to help with your PDF needs."
/>
<meta name="author" content="BentoPDF" />
<meta name="robots" content="index, follow" />
<!-- Canonical URL -->
<link rel="canonical" href="https://www.bentopdf.com/contact" />
<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.bentopdf.com/contact" />
<meta
property="og:title"
content="Contact BentoPDF - Get in Touch | Support"
/>
<meta
property="og:description"
content="Contact BentoPDF for support, questions, or feedback. Reach us at [email protected] - we're here to help with your PDF needs."
/>
<meta
property="og:image"
content="https://www.bentopdf.com/images/og-contact.png"
/>
<meta property="og:site_name" content="BentoPDF" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content="Contact BentoPDF - Get in Touch | Support"
/>
<meta
name="twitter:description"
content="Contact BentoPDF for support, questions, or feedback. Reach us at [email protected] - we're here to help with your PDF needs."
/>
<meta
name="twitter:image"
content="https://www.bentopdf.com/images/twitter-contact.png"
/>
<meta name="twitter:site" content="@BentoPDF" />
<link href="/src/css/styles.css" rel="stylesheet" /> <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> </head>
<body class="antialiased bg-gray-900 text-gray-300"> <body class="lp antialiased">
<nav class="bg-gray-800 border-b border-gray-700 sticky top-0 z-30"> {{> navbar }}
<div class="container mx-auto px-4">
<div class="flex justify-between items-center h-16">
<div
class="flex-shrink-0 flex items-center cursor-pointer"
id="home-logo"
>
<img
src="images/favicon.svg"
alt="Bento PDF Logo"
class="h-8 w-8"
/>
<span class="text-white font-bold text-xl ml-2">
<a href="index.html">BentoPDF</a>
</span>
</div>
<!-- Desktop Navigation --> <div id="app">
<div class="hidden md:flex items-center space-x-8"> <section id="contact-hero" class="lp-sec lp-sec--first">
<a href="index.html" class="nav-link">Home</a> <div class="lp-frame">
<a href="./about.html" class="nav-link">About</a> <div class="lp-cta">
<a href="./contact.html" class="nav-link">Contact</a> <div>
<a href="index.html#tools-header" class="nav-link">All Tools</a> <h1 class="lp-h2">
</div> <span class="line" data-i18n="contact.title">Get in Touch</span>
</h1>
<!-- Mobile Hamburger Button --> <p class="lp-head-p" data-i18n="contact.subtitle">
<div class="md:hidden flex items-center"> We'd love to hear from you. Whether you have a question,
<button feedback, or a feature request, please don't hesitate to reach
id="mobile-menu-button" out.
type="button" </p>
class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 transition-colors" </div>
aria-controls="mobile-menu"
aria-expanded="false"
>
<span class="sr-only">Open main menu</span>
<!-- Hamburger Icon -->
<svg
id="menu-icon"
class="block h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
<!-- Close Icon -->
<svg
id="close-icon"
class="hidden h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div> </div>
</div> </div>
</div>
<!-- Mobile Menu Dropdown -->
<div
id="mobile-menu"
class="hidden md:hidden bg-gray-800 border-t border-gray-700"
>
<div class="px-2 pt-2 pb-3 space-y-1 text-center">
<a href="index.html" class="mobile-nav-link">Home</a>
<a href="./about.html" class="mobile-nav-link">About</a>
<a href="./contact.html" class="mobile-nav-link">Contact</a>
<a href="index.html#tools-header" class="mobile-nav-link"
>All Tools</a
>
</div>
</div>
</nav>
<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">
Get in Touch
</h1>
<p class="text-lg md:text-xl text-gray-400 max-w-3xl mx-auto">
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>
</section> </section>
<div class="max-w-2xl mx-auto text-center py-8"> <section id="contact-channels" class="lp-sec lp-band">
<p class="text-lg text-gray-400"> <div class="lp-frame">
You can reach us directly by email at: <div class="lp-grid lp-grid--2 lp-cross">
<a <a class="lp-cell lp-reveal" href="mailto:[email protected]">
href="mailto:[email protected]" <span class="lp-tile"><i data-lucide="mail"></i></span>
class="text-indigo-400 underline hover:text-indigo-300" <h3 data-i18n="contact.emailTitle">Email</h3>
>[email protected]</a <p data-i18n="contact.email">
> You can reach us directly by email at:
</p> </p>
</div> <b>[email protected]</b>
</div> </a>
<footer class="mt-16 border-t-2 border-gray-700 py-8"> <a
<div class="container mx-auto px-4"> class="lp-cell lp-reveal"
<div class="grid grid-cols-1 md:grid-cols-4 gap-8 text-center md:text-left"> href="https://github.com/alam00000/bentopdf/issues"
<div class="mb-8 md:mb-0"> target="_blank"
<div class="flex items-center justify-center md:justify-start mb-4"> rel="noopener noreferrer"
<img src="images/favicon.svg" alt="Bento PDF Logo" class="h-10 w-10 mr-3" /> >
<span class="text-xl font-bold text-white">BentoPDF</span> <span class="lp-tile"><i data-lucide="github"></i></span>
</div> <h3>GitHub</h3>
<p class="text-gray-400 text-sm"> <p data-i18n="contact.githubText">
&copy; 2025 BentoPDF. All rights reserved. Report a bug, request a feature, or read the source.
</p> </p>
<p class="text-gray-500 text-xs mt-2"> <b>github.com/alam00000/bentopdf</b>
Version <span id="app-version">1.6.2</span> </a>
</p>
</div>
<div> <a
<h3 class="font-bold text-white mb-4">Company</h3> class="lp-cell lp-reveal"
<ul class="space-y-2 text-gray-400"> href="https://discord.gg/Bgq3Ay3f2w"
<li> target="_blank"
<a href="./about.html" class="hover:text-indigo-400">About Us</a> rel="noopener noreferrer"
</li> >
<li> <span class="lp-tile"><i data-lucide="message-circle"></i></span>
<a href="./faq.html" class="hover:text-indigo-400">FAQ</a> <h3>Discord</h3>
</li> <p data-i18n="contact.discordText">
<li> Join the community to chat with us and other users.
<a href="./contact.html" class="hover:text-indigo-400">Contact Us</a> </p>
</li> <b>discord.gg/Bgq3Ay3f2w</b>
</ul> </a>
</div>
<div> <a class="lp-cell lp-reveal" href="faq.html">
<h3 class="font-bold text-white mb-4">Legal</h3> <span class="lp-tile"><i data-lucide="help-circle"></i></span>
<ul class="space-y-2 text-gray-400"> <h3 data-i18n="footer.faqLink">FAQ</h3>
<li> <p data-i18n="contact.faqText">
<a href="./terms.html" class="hover:text-indigo-400">Terms and Conditions</a> Find quick answers to the questions we get most often.
</li> </p>
<li> <b data-i18n="contact.faqLink">Read the FAQ</b>
<a href="./privacy.html" class="hover:text-indigo-400">Privacy Policy</a> </a>
</li>
</ul>
</div>
<div>
<h3 class="font-bold text-white mb-4">Follow Us</h3>
<div class="flex justify-center md:justify-start space-x-4">
<a href="https://github.com/alam00000/bentopdf" target="_blank" rel="noopener noreferrer"
class="text-gray-400 hover:text-indigo-400" title="GitHub">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fill-rule="evenodd"
d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
clip-rule="evenodd" />
</svg>
</a>
<a href="https://discord.gg/q42xWQmJ" target="_blank" rel="noopener noreferrer"
class="text-gray-400 hover:text-indigo-400" title="Discord">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z" />
</svg>
</a>
<a href="https://www.instagram.com/thebentopdf/" class="text-gray-400 hover:text-indigo-400"
title="Instagram">
<i data-lucide="instagram"></i>
</a>
<a href="https://www.linkedin.com/company/bentopdf/" class="text-gray-400 hover:text-indigo-400"
title="LinkedIn">
<i data-lucide="linkedin"></i>
</a>
<a href="https://x.com/BentoPDF" class="text-gray-400 hover:text-indigo-400" title="X (Twitter)">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</a>
</div>
</div> </div>
</div> </div>
</div> </section>
</footer> </div>
{{> footer }}
<script type="module" src="src/js/utils/lucide-init.ts"></script> <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/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": "ContactPage",
"name": "Contact BentoPDF - Get in Touch | Support",
"url": "https://www.bentopdf.com/contact"
}
</script>
</body> </body>
</html> </html>
+3
View File
@@ -9,3 +9,6 @@ services:
ports: ports:
- '8080:8080' - '8080:8080'
restart: unless-stopped restart: unless-stopped
# For IPv4-only environments
#environment:
# - DISABLE_IPV6=true
+10 -3
View File
@@ -1,9 +1,16 @@
services: services:
bentopdf: bentopdf:
# simple mode - bentopdf/bentopdf-simple:latest # GitHub Container Registry (Recommended)
# default mode - bentopdf/bentopdf:latest # Self-Hosted build - ghcr.io/alam00000/bentopdf-simple:latest
image: bentopdf/bentopdf-simple:latest # Commercial build - ghcr.io/alam00000/bentopdf:latest
# Docker Hub (Alternative)
# Self-Hosted build - bentopdfteam/bentopdf-simple:latest
# Commercial build - bentopdfteam/bentopdf:latest
image: ghcr.io/alam00000/bentopdf-simple:latest
container_name: bentopdf container_name: bentopdf
restart: unless-stopped restart: unless-stopped
ports: ports:
- '8080:8080' - '8080:8080'
# For IPv4-only environments
#environment:
# - DISABLE_IPV6=true
+228
View File
@@ -0,0 +1,228 @@
import { defineConfig } from 'vitepress'
import type { DefaultTheme } from 'vitepress'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { nav, sidebar } from './navigation.mjs'
import { DESCRIPTION, FOOTER_MESSAGE } from './i18n/theme-labels.mjs'
import { completeDocsLanguages } from '../../scripts/docs-languages.mjs'
const SITE_URL = 'https://www.bentopdf.com'
const docsDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const labelsDir = path.join(docsDir, '.vitepress', 'i18n')
const LANGUAGE_NAMES: Record<string, string> = {
ar: 'العربية',
be: 'Беларуская',
ca: 'Català',
da: 'Dansk',
de: 'Deutsch',
es: 'Español',
fa: 'فارسی',
fr: 'Français',
id: 'Bahasa Indonesia',
it: 'Italiano',
ja: '日本語',
ko: '한국어',
nl: 'Nederlands',
pl: 'Polski',
pt: 'Português',
ru: 'Русский',
sk: 'Slovenčina',
sv: 'Svenska',
tr: 'Türkçe',
uk: 'Українська',
vi: 'Tiếng Việt',
zh: '简体中文',
'zh-TW': '繁體中文'
}
const RTL_LANGUAGES = new Set(['ar', 'fa'])
const ENGLISH_ONLY_DOCS = new Set(['licensing'])
const { enabled, incomplete } = completeDocsLanguages(
docsDir,
Object.keys(LANGUAGE_NAMES),
process.env.DOCS_LANGUAGES
)
for (const { lang, missing, total } of incomplete) {
console.warn(`[docs] Skipping "${lang}": ${missing} of ${total} pages are not translated yet`)
}
const excluded = Object.keys(LANGUAGE_NAMES)
.filter((lang) => !enabled.includes(lang))
.map((lang) => `${lang}/**`)
type Labels = Record<string, string>
function readLabels(lang: string): Labels {
const file = path.join(labelsDir, `${lang}.json`)
return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : {}
}
function localizedLink(link: string | undefined, lang: string) {
return link && link.startsWith('/') ? `/${lang}${link}` : link
}
type LocalizableItem = {
text?: string
link?: string
items?: LocalizableItem[]
}
function localizeItems<T extends LocalizableItem>(
items: T[],
lang: string,
translate: (text: string) => string
): T[] {
return items.map((item) => ({
...item,
...(item.text ? { text: translate(item.text) } : {}),
...(item.link ? { link: localizedLink(item.link, lang) } : {}),
...(item.items ? { items: localizeItems(item.items, lang, translate) } : {})
}))
}
function localeThemeConfig(lang: string): DefaultTheme.Config {
const labels = readLabels(lang)
const translate = (text: string) => labels[text] || text
return {
nav: localizeItems(nav, lang, translate),
sidebar: Object.fromEntries(
Object.entries(sidebar).map(([base, items]) => [
`/${lang}${base}`,
localizeItems(items as DefaultTheme.SidebarItem[], lang, translate)
])
),
footer: {
message: translate(FOOTER_MESSAGE),
copyright: 'Copyright © 2026 BentoPDF'
},
outline: { label: translate('On this page') },
docFooter: {
prev: translate('Previous page'),
next: translate('Next page')
},
returnToTopLabel: translate('Return to top'),
sidebarMenuLabel: translate('Menu'),
darkModeSwitchLabel: translate('Appearance'),
lightModeSwitchTitle: translate('Switch to light theme'),
darkModeSwitchTitle: translate('Switch to dark theme'),
skipToContentLabel: translate('Skip to content'),
langMenuLabel: translate('Change language')
}
}
function localeSearch(lang: string) {
const labels = readLabels(lang)
const translate = (text: string) => labels[text] || text
return {
translations: {
button: {
buttonText: translate('Search'),
buttonAriaLabel: translate('Search')
},
modal: {
displayDetails: translate('Display detailed list'),
resetButtonTitle: translate('Reset search'),
backButtonTitle: translate('Close search'),
noResultsText: translate('No results for'),
footer: {
selectText: translate('to select'),
navigateText: translate('to navigate'),
closeText: translate('to close')
}
}
}
}
}
const locales = Object.fromEntries(
enabled.map((lang) => {
const labels = readLabels(lang)
return [
lang,
{
label: LANGUAGE_NAMES[lang],
lang,
dir: RTL_LANGUAGES.has(lang) ? 'rtl' : 'ltr',
link: `/${lang}/`,
title: 'BentoPDF Docs',
description: labels[DESCRIPTION] || DESCRIPTION,
themeConfig: localeThemeConfig(lang)
}
]
})
)
function pageUrl(lang: string, pagePath: string) {
const prefix = lang === 'en' ? '' : `/${lang}`
const suffix = pagePath === 'index' ? '' : `/${pagePath.replace(/\/index$/, '')}`
return `${SITE_URL}/docs${prefix}${suffix}`
}
export default defineConfig({
title: "BentoPDF Docs",
description: DESCRIPTION,
base: '/docs/',
cleanUrls: true,
metaChunk: true,
srcExclude: excluded,
locales: {
root: { label: 'English', lang: 'en-US' },
...locales
},
transformPageData(pageData) {
const relPath = pageData.relativePath.replace(/\.md$/, '')
const pageLang = enabled.find((lang) => relPath.startsWith(`${lang}/`))
const pagePath = pageLang ? relPath.slice(pageLang.length + 1) : relPath
const englishOnly = ENGLISH_ONLY_DOCS.has(pagePath)
const canonicalPath = englishOnly ? pagePath : relPath
const slug = canonicalPath === 'index' ? '' : canonicalPath.replace(/\/index$/, '')
const canonicalUrl = slug ? `${SITE_URL}/docs/${slug}` : `${SITE_URL}/docs`
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push(['link', { rel: 'canonical', href: canonicalUrl }])
if (enabled.length === 0 || englishOnly) return
for (const lang of ['en', ...enabled]) {
const source = lang === 'en' ? pagePath : `${lang}/${pagePath}`
if (!fs.existsSync(path.join(docsDir, `${source}.md`))) continue
pageData.frontmatter.head.push([
'link',
{ rel: 'alternate', hreflang: lang, href: pageUrl(lang, pagePath) }
])
}
pageData.frontmatter.head.push([
'link',
{ rel: 'alternate', hreflang: 'x-default', href: pageUrl('en', pagePath) }
])
},
themeConfig: {
logo: '/images/favicon-no-bg.svg',
nav,
sidebar,
socialLinks: [
{ icon: 'github', link: 'https://github.com/alam00000/bentopdf' },
{ icon: 'discord', link: 'https://discord.gg/Bgq3Ay3f2w' }
],
footer: {
message: FOOTER_MESSAGE,
copyright: 'Copyright © 2026 BentoPDF'
},
search: {
provider: 'local',
options: {
locales: Object.fromEntries(
enabled.map((lang) => [lang, localeSearch(lang)])
)
}
}
}
})
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "إضافة مرفقات",
"Add Blank Page": "إضافة صفحة فارغة",
"Add Page Labels": "إضافة تسميات الصفحات",
"Add Stamps": "إضافة أختام",
"Add Watermark": "إضافة علامة مائية",
"Adjust Colors": "ضبط الألوان",
"Alternate & Mix Pages": "تبديل ومزج الصفحات",
"Apache": "Apache",
"Appearance": "المظهر",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "لون الخلفية",
"Bates Numbering": "ترقيم بيتس",
"BMP to PDF": "BMP إلى PDF",
"CBZ to PDF": "CBZ إلى PDF",
"Change language": "تغيير اللغة",
"Change Permissions": "تغيير الأذونات",
"Change Text Color": "تغيير لون النص",
"Close search": "إغلاق البحث",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "دمج في صفحة واحدة",
"Commercial License": "الترخيص التجاري",
"Compare PDFs": "مقارنة ملفات PDF",
"Compress PDF": "ضغط PDF",
"Contributing": "المساهمة",
"Convert from PDF": "التحويل من PDF",
"Convert to PDF": "التحويل إلى PDF",
"Create PDF Form": "إنشاء نموذج PDF",
"Crop PDF": "قص PDF",
"CSV to PDF": "CSV إلى PDF",
"Delete Pages": "حذف الصفحات",
"Deskew PDF": "تصحيح انحراف PDF",
"Digital Signature": "التوقيع الرقمي",
"Display detailed list": "عرض القائمة التفصيلية",
"Divide Pages": "تقسيم الصفحات",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "توثيق BentoPDF، مجموعة أدوات PDF المجانية ومفتوحة المصدر والمصممة للخصوصية",
"Dual-licensed under AGPL-3.0 and Commercial License.": "مرخّص بترخيصين: AGPL-3.0 والترخيص التجاري.",
"Duplex Collate": "ترتيب المسح على الوجهين",
"Edit & Annotate": "تعديل وتعليق",
"Edit Attachments": "تعديل المرفقات",
"Edit Bookmarks": "تعديل الإشارات المرجعية",
"Edit Metadata": "تعديل البيانات الوصفية",
"Email to PDF": "بريد إلكتروني إلى PDF",
"EPUB to PDF": "EPUB إلى PDF",
"Excel to PDF": "Excel إلى PDF",
"Extract Attachments": "استخراج المرفقات",
"Extract Images": "استخراج الصور",
"Extract Pages": "استخراج الصفحات",
"Extract Tables": "استخراج الجداول",
"FB2 to PDF": "FB2 إلى PDF",
"Fix Page Size": "توحيد حجم الصفحة",
"Flatten PDF": "تسطيح PDF",
"Font to Outline": "تحويل الخطوط إلى مخططات",
"Getting Started": "البدء",
"Guide": "الدليل",
"Header & Footer": "رأس وتذييل",
"HEIC to PDF": "HEIC إلى PDF",
"Home": "الرئيسية",
"Hostinger": "Hostinger",
"Images to PDF": "صور إلى PDF",
"Invert Colors": "عكس الألوان",
"JPG to PDF": "JPG إلى PDF",
"JSON to PDF": "JSON إلى PDF",
"Linearize PDF": "تحسين PDF للويب",
"Markdown to PDF": "Markdown إلى PDF",
"Menu": "القائمة",
"Merge PDF": "دمج PDF",
"MOBI to PDF": "MOBI إلى PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "الصفحة التالية",
"Nginx": "Nginx",
"No results for": "لا توجد نتائج لـ",
"OCR PDF": "التعرف الضوئي على PDF",
"ODG to PDF": "ODG إلى PDF",
"ODP to PDF": "ODP إلى PDF",
"ODS to PDF": "ODS إلى PDF",
"ODT to PDF": "ODT إلى PDF",
"On this page": "في هذه الصفحة",
"Optimize & Repair": "التحسين والإصلاح",
"Organize & Duplicate": "تكرار وتنظيم",
"Organize & Manage": "التنظيم والإدارة",
"Overview": "نظرة عامة",
"Page Dimensions": "أبعاد الصفحة",
"Page Numbers": "أرقام الصفحات",
"PDF Booklet": "كتيّب PDF",
"PDF Editor": "محرر PDF",
"PDF Form Filler": "ملء نماذج PDF",
"PDF Multi Tool": "أداة PDF المتعددة",
"PDF OCG": "طبقات PDF OCG",
"PDF to BMP": "PDF إلى BMP",
"PDF to CBZ": "PDF إلى CBZ",
"PDF to CSV": "PDF إلى CSV",
"PDF to Excel": "PDF إلى Excel",
"PDF to Greyscale": "PDF إلى تدرج الرمادي",
"PDF to JPG": "PDF إلى JPG",
"PDF to JSON": "PDF إلى JSON",
"PDF to Markdown": "PDF إلى Markdown",
"PDF to PDF/A": "PDF إلى PDF/A",
"PDF to PNG": "PDF إلى PNG",
"PDF to SVG": "PDF إلى SVG",
"PDF to Text": "PDF إلى نص",
"PDF to TIFF": "PDF إلى TIFF",
"PDF to WebP": "PDF إلى WebP",
"PDF to Word": "PDF إلى Word",
"PDF Workflow Builder": "منشئ سير عمل PDF",
"PDFs to ZIP": "PDF إلى ZIP",
"PNG to PDF": "PNG إلى PDF",
"Posterize PDF": "تقسيم PDF إلى ملصقات",
"PowerPoint to PDF": "PowerPoint إلى PDF",
"Prepare PDF for AI": "تحضير PDF للذكاء الاصطناعي",
"Previous page": "الصفحة السابقة",
"Protect PDF": "حماية PDF",
"PSD to PDF": "PSD إلى PDF",
"PUB to PDF": "PUB إلى PDF",
"Rasterize PDF": "تحويل PDF إلى صور نقطية",
"Remove Annotations": "إزالة التعليقات",
"Remove Blank Pages": "إزالة الصفحات الفارغة",
"Remove Metadata": "إزالة البيانات الوصفية",
"Remove Restrictions": "إزالة القيود",
"Repair PDF": "إصلاح PDF",
"Reset search": "إعادة تعيين البحث",
"Return to top": "العودة إلى الأعلى",
"Reverse Pages": "عكس الصفحات",
"Rotate by Custom Degrees": "تدوير بزاوية مخصصة",
"Rotate PDF": "تدوير PDF",
"RTF to PDF": "RTF إلى PDF",
"Sanitize PDF": "تنظيف PDF",
"Scanner Effect": "تأثير الماسح الضوئي",
"Search": "بحث",
"Secure PDF": "تأمين PDF",
"Self-Hosting": "الاستضافة الذاتية",
"Self-Hosting Guide": "دليل الاستضافة الذاتية",
"Sign PDF": "توقيع PDF",
"Skip to content": "انتقل إلى المحتوى",
"Split PDF": "تقسيم PDF",
"SVG to PDF": "SVG إلى PDF",
"Switch to dark theme": "التبديل إلى المظهر الداكن",
"Switch to light theme": "التبديل إلى المظهر الفاتح",
"Table of Contents": "جدول المحتويات",
"Text to PDF": "نص إلى PDF",
"TIFF to PDF": "TIFF إلى PDF",
"to close": "للإغلاق",
"to navigate": "للتنقل",
"to select": "للاختيار",
"Tools": "الأدوات",
"Tools Reference": "مرجع الأدوات",
"Unlock PDF": "إلغاء قفل PDF",
"Validate Signature": "التحقق من توقيع PDF",
"Vercel": "Vercel",
"View Metadata": "عرض البيانات الوصفية",
"VSD to PDF": "VSD إلى PDF",
"WebP to PDF": "WebP إلى PDF",
"Word to PDF": "Word إلى PDF",
"WPD to PDF": "WPD إلى PDF",
"WPS to PDF": "WPS إلى PDF",
"XML to PDF": "XML إلى PDF",
"XPS to PDF": "XPS إلى PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Дадаць далучэнні",
"Add Blank Page": "Дадаць пустую старонку",
"Add Page Labels": "Дадаць пазнакі старонак",
"Add Stamps": "Дадаць штампы",
"Add Watermark": "Дадаць вадзяны знак",
"Adjust Colors": "Наладзіць колеры",
"Alternate & Mix Pages": "Чаргаваць і змяшаць старонкі",
"Apache": "Apache",
"Appearance": "Знешні выгляд",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Колер фону",
"Bates Numbering": "Нумарацыя Бейтса",
"BMP to PDF": "BMP у PDF",
"CBZ to PDF": "CBZ у PDF",
"Change language": "Змяніць мову",
"Change Permissions": "Змяніць дазволы",
"Change Text Color": "Змяніць колер тэксту",
"Close search": "Закрыць пошук",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Аб'яднаць у адну старонку",
"Commercial License": "Камерцыйная ліцэнзія",
"Compare PDFs": "Параўнаць PDF",
"Compress PDF": "Сціснуць PDF",
"Contributing": "Удзел у распрацоўцы",
"Convert from PDF": "Канвертацыя з PDF",
"Convert to PDF": "Канвертацыя ў PDF",
"Create PDF Form": "Стварыць форму PDF",
"Crop PDF": "Абрэзаць PDF",
"CSV to PDF": "CSV у PDF",
"Delete Pages": "Выдаліць старонкі",
"Deskew PDF": "Выпрастаць PDF",
"Digital Signature": "Лічбавы подпіс",
"Display detailed list": "Паказаць падрабязны спіс",
"Divide Pages": "Падзяліць старонкі",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Дакументацыя BentoPDF: бясплатны набор інструментаў PDF з адкрытым кодам і пашанай да прыватнасці",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Двайная ліцэнзія: AGPL-3.0 і камерцыйная ліцэнзія.",
"Duplex Collate": "Сартаванне двухбаковага сканавання",
"Edit & Annotate": "Рэдагаванне і анатацыі",
"Edit Attachments": "Рэдагаваць далучэнні",
"Edit Bookmarks": "Рэдагаваць закладкі",
"Edit Metadata": "Рэдагаваць метаданыя",
"Email to PDF": "Email у PDF",
"EPUB to PDF": "EPUB у PDF",
"Excel to PDF": "Excel у PDF",
"Extract Attachments": "Выняць далучэнні",
"Extract Images": "Выняць відарысы",
"Extract Pages": "Выняць старонкі",
"Extract Tables": "Выняць табліцы",
"FB2 to PDF": "FB2 у PDF",
"Fix Page Size": "Уніфікаваць памер старонак",
"Flatten PDF": "Звесці PDF",
"Font to Outline": "Шрыфт у контуры",
"Getting Started": "Пачатак працы",
"Guide": "Кіраўніцтва",
"Header & Footer": "Верхні і ніжні калантытул",
"HEIC to PDF": "HEIC у PDF",
"Home": "Галоўная",
"Hostinger": "Hostinger",
"Images to PDF": "Відарысы ў PDF",
"Invert Colors": "Інвертаваць колеры",
"JPG to PDF": "JPG у PDF",
"JSON to PDF": "JSON у PDF",
"Linearize PDF": "Зрабіць лінейны PDF",
"Markdown to PDF": "Markdown у PDF",
"Menu": "Меню",
"Merge PDF": "Аб'яднаць PDF",
"MOBI to PDF": "MOBI у PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Наступная старонка",
"Nginx": "Nginx",
"No results for": "Няма вынікаў для",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG у PDF",
"ODP to PDF": "ODP у PDF",
"ODS to PDF": "ODS у PDF",
"ODT to PDF": "ODT у PDF",
"On this page": "На гэтай старонцы",
"Optimize & Repair": "Аптымізацыя і аднаўленне",
"Organize & Duplicate": "Арганізацыя і дубліраванне",
"Organize & Manage": "Арганізацыя і кіраванне",
"Overview": "Агляд",
"Page Dimensions": "Памеры старонкі",
"Page Numbers": "Нумары старонак",
"PDF Booklet": "Буклет PDF",
"PDF Editor": "Рэдактар PDF",
"PDF Form Filler": "Запоўніць форму PDF",
"PDF Multi Tool": "Мультыінструмент PDF",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF у BMP",
"PDF to CBZ": "PDF у CBZ",
"PDF to CSV": "PDF у CSV",
"PDF to Excel": "PDF у Excel",
"PDF to Greyscale": "PDF у градацыі шэрага",
"PDF to JPG": "PDF у JPG",
"PDF to JSON": "PDF у JSON",
"PDF to Markdown": "PDF у Markdown",
"PDF to PDF/A": "PDF у PDF/A",
"PDF to PNG": "PDF у PNG",
"PDF to SVG": "PDF у SVG",
"PDF to Text": "PDF у тэкст",
"PDF to TIFF": "PDF у TIFF",
"PDF to WebP": "PDF у WebP",
"PDF to Word": "PDF у Word",
"PDF Workflow Builder": "Канструктар рабочага працэсу PDF",
"PDFs to ZIP": "PDF у ZIP",
"PNG to PDF": "PNG у PDF",
"Posterize PDF": "Пераўтварыць у постэр",
"PowerPoint to PDF": "PowerPoint у PDF",
"Prepare PDF for AI": "Падрыхтаваць PDF для ШI",
"Previous page": "Папярэдняя старонка",
"Protect PDF": "Абараніць PDF",
"PSD to PDF": "PSD у PDF",
"PUB to PDF": "PUB у PDF",
"Rasterize PDF": "Растарызаваць PDF",
"Remove Annotations": "Выдаліць анатацыі",
"Remove Blank Pages": "Выдаліць пустыя старонкі",
"Remove Metadata": "Выдаліць метаданыя",
"Remove Restrictions": "Выдаліць абмежаванні",
"Repair PDF": "Аднавіць PDF",
"Reset search": "Скінуць пошук",
"Return to top": "Вярнуцца ўгару",
"Reverse Pages": "Адваротны парадак старонак",
"Rotate by Custom Degrees": "Павярнуць на зададзены вугал",
"Rotate PDF": "Павярнуць PDF",
"RTF to PDF": "RTF у PDF",
"Sanitize PDF": "Ачысціць PDF",
"Scanner Effect": "Эфект сканера",
"Search": "Пошук",
"Secure PDF": "Бяспека PDF",
"Self-Hosting": "Уласны хостынг",
"Self-Hosting Guide": "Кіраўніцтва па ўласным хостынгу",
"Sign PDF": "Падпісаць PDF",
"Skip to content": "Перайсці да зместу",
"Split PDF": "Падзяліць PDF",
"SVG to PDF": "SVG у PDF",
"Switch to dark theme": "Уключыць цёмную тэму",
"Switch to light theme": "Уключыць светлую тэму",
"Table of Contents": "Змест",
"Text to PDF": "Тэкст у PDF",
"TIFF to PDF": "TIFF у PDF",
"to close": "каб закрыць",
"to navigate": "для навігацыі",
"to select": "каб выбраць",
"Tools": "Інструменты",
"Tools Reference": "Даведнік па інструментах",
"Unlock PDF": "Разблакаваць PDF",
"Validate Signature": "Праверыць подпіс",
"Vercel": "Vercel",
"View Metadata": "Праглядзець метаданыя",
"VSD to PDF": "VSD у PDF",
"WebP to PDF": "WebP у PDF",
"Word to PDF": "Word у PDF",
"WPD to PDF": "WPD у PDF",
"WPS to PDF": "WPS у PDF",
"XML to PDF": "XML у PDF",
"XPS to PDF": "XPS у PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Afegeix fitxers adjunts",
"Add Blank Page": "Afegeix una pàgina en blanc",
"Add Page Labels": "Afegeix etiquetes de pàgina",
"Add Stamps": "Afegeix segells",
"Add Watermark": "Afegeix una marca d'aigua",
"Adjust Colors": "Ajusta els colors",
"Alternate & Mix Pages": "Alterna i barreja pàgines",
"Apache": "Apache",
"Appearance": "Aparença",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Color de fons",
"Bates Numbering": "Numeració Bates",
"BMP to PDF": "BMP a PDF",
"CBZ to PDF": "CBZ a PDF",
"Change language": "Canvia l'idioma",
"Change Permissions": "Canvia els permisos",
"Change Text Color": "Canvia el color del text",
"Close search": "Tanca la cerca",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combina en una única pàgina",
"Commercial License": "Llicència comercial",
"Compare PDFs": "Compara PDF",
"Compress PDF": "Comprimeix PDF",
"Contributing": "Contribuir",
"Convert from PDF": "Converteix des de PDF",
"Convert to PDF": "Converteix a PDF",
"Create PDF Form": "Crea un formulari PDF",
"Crop PDF": "Retalla PDF",
"CSV to PDF": "CSV a PDF",
"Delete Pages": "Suprimeix pàgines",
"Deskew PDF": "Redreça PDF",
"Digital Signature": "Signatura digital de PDF",
"Display detailed list": "Mostra la llista detallada",
"Divide Pages": "Divideix pàgines",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentació de BentoPDF: el conjunt d'eines PDF gratuït, de codi obert i pensat per protegir la privadesa",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Doble llicència: AGPL-3.0 i llicència comercial.",
"Duplex Collate": "Ordena les cares d'un escaneig a doble cara",
"Edit & Annotate": "Edita i anota",
"Edit Attachments": "Edita els fitxers adjunts",
"Edit Bookmarks": "Edita els marcadors",
"Edit Metadata": "Edita les metadades",
"Email to PDF": "Correu electrònic a PDF",
"EPUB to PDF": "EPUB a PDF",
"Excel to PDF": "Excel a PDF",
"Extract Attachments": "Extreu fitxers adjunts",
"Extract Images": "Extreu imatges",
"Extract Pages": "Extreu pàgines",
"Extract Tables": "Extreu taules de PDF",
"FB2 to PDF": "FB2 a PDF",
"Fix Page Size": "Uniformitza la mida de pàgina",
"Flatten PDF": "Aplana PDF",
"Font to Outline": "Converteix tipus de lletra en contorns",
"Getting Started": "Primers passos",
"Guide": "Guia",
"Header & Footer": "Capçalera i peu de pàgina",
"HEIC to PDF": "HEIC a PDF",
"Home": "Inici",
"Hostinger": "Hostinger",
"Images to PDF": "Imatges a PDF",
"Invert Colors": "Inverteix els colors",
"JPG to PDF": "JPG a PDF",
"JSON to PDF": "JSON a PDF",
"Linearize PDF": "Linealitza PDF",
"Markdown to PDF": "Markdown a PDF",
"Menu": "Menú",
"Merge PDF": "Fusiona PDF",
"MOBI to PDF": "MOBI a PDF",
"N-Up PDF": "PDF amb diverses pàgines per full",
"Netlify": "Netlify",
"Next page": "Pàgina següent",
"Nginx": "Nginx",
"No results for": "Cap resultat per a",
"OCR PDF": "Reconeixement OCR de PDF",
"ODG to PDF": "ODG a PDF",
"ODP to PDF": "ODP a PDF",
"ODS to PDF": "ODS a PDF",
"ODT to PDF": "ODT a PDF",
"On this page": "En aquesta pàgina",
"Optimize & Repair": "Optimitza i repara",
"Organize & Duplicate": "Duplica i organitza",
"Organize & Manage": "Organitza i gestiona",
"Overview": "Visió general",
"Page Dimensions": "Dimensions de pàgina",
"Page Numbers": "Números de pàgina",
"PDF Booklet": "Fullet PDF",
"PDF Editor": "Editor de PDF",
"PDF Form Filler": "Emplena formularis PDF",
"PDF Multi Tool": "Eina PDF multifunció",
"PDF OCG": "Capes OCG del PDF",
"PDF to BMP": "PDF a BMP",
"PDF to CBZ": "PDF a CBZ",
"PDF to CSV": "PDF a CSV",
"PDF to Excel": "PDF a Excel",
"PDF to Greyscale": "PDF a escala de grisos",
"PDF to JPG": "PDF a JPG",
"PDF to JSON": "PDF a JSON",
"PDF to Markdown": "PDF a Markdown",
"PDF to PDF/A": "PDF a PDF/A",
"PDF to PNG": "PDF a PNG",
"PDF to SVG": "PDF a SVG",
"PDF to Text": "PDF a text",
"PDF to TIFF": "PDF a TIFF",
"PDF to WebP": "PDF a WebP",
"PDF to Word": "PDF a Word",
"PDF Workflow Builder": "Creador de fluxos de treball PDF",
"PDFs to ZIP": "PDF a ZIP",
"PNG to PDF": "PNG a PDF",
"Posterize PDF": "Divideix PDF en format pòster",
"PowerPoint to PDF": "PowerPoint a PDF",
"Prepare PDF for AI": "Prepara PDF per a IA",
"Previous page": "Pàgina anterior",
"Protect PDF": "Protegeix PDF",
"PSD to PDF": "PSD a PDF",
"PUB to PDF": "PUB a PDF",
"Rasterize PDF": "Rasteritza PDF",
"Remove Annotations": "Elimina les anotacions",
"Remove Blank Pages": "Elimina les pàgines en blanc",
"Remove Metadata": "Elimina les metadades",
"Remove Restrictions": "Elimina les restriccions",
"Repair PDF": "Repara PDF",
"Reset search": "Restableix la cerca",
"Return to top": "Torna a dalt",
"Reverse Pages": "Inverteix l'ordre de les pàgines",
"Rotate by Custom Degrees": "Gira amb un angle personalitzat",
"Rotate PDF": "Gira PDF",
"RTF to PDF": "RTF a PDF",
"Sanitize PDF": "Neteja PDF",
"Scanner Effect": "Efecte d'escàner",
"Search": "Cerca",
"Secure PDF": "Xifra PDF",
"Self-Hosting": "Autoallotjament",
"Self-Hosting Guide": "Guia d'autoallotjament",
"Sign PDF": "Signa PDF",
"Skip to content": "Vés al contingut",
"Split PDF": "Divideix PDF",
"SVG to PDF": "SVG a PDF",
"Switch to dark theme": "Canvia al tema fosc",
"Switch to light theme": "Canvia al tema clar",
"Table of Contents": "Taula de continguts",
"Text to PDF": "Text a PDF",
"TIFF to PDF": "TIFF a PDF",
"to close": "per tancar",
"to navigate": "per navegar",
"to select": "per seleccionar",
"Tools": "Eines",
"Tools Reference": "Referència d'eines",
"Unlock PDF": "Desbloqueja PDF",
"Validate Signature": "Valida la signatura d'un PDF",
"Vercel": "Vercel",
"View Metadata": "Visualitza les metadades",
"VSD to PDF": "VSD a PDF",
"WebP to PDF": "WebP a PDF",
"Word to PDF": "Word a PDF",
"WPD to PDF": "WPD a PDF",
"WPS to PDF": "WPS a PDF",
"XML to PDF": "XML a PDF",
"XPS to PDF": "XPS a PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Tilføj vedhæftninger",
"Add Blank Page": "Tilføj tom side",
"Add Page Labels": "Tilføj sideetiketter",
"Add Stamps": "Tilføj stempler",
"Add Watermark": "Tilføj vandmærke",
"Adjust Colors": "Justér farver",
"Alternate & Mix Pages": "Alternér og miks sider",
"Apache": "Apache",
"Appearance": "Udseende",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Baggrundsfarve",
"Bates Numbering": "Bates-nummerering",
"BMP to PDF": "BMP til PDF",
"CBZ to PDF": "CBZ til PDF",
"Change language": "Skift sprog",
"Change Permissions": "Skift tilladelser",
"Change Text Color": "Skift tekstfarve",
"Close search": "Luk søgning",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Kombinér til én side",
"Commercial License": "Kommerciel licens",
"Compare PDFs": "Sammenlign PDF’er",
"Compress PDF": "Komprimer PDF",
"Contributing": "Bidrag",
"Convert from PDF": "Konvertér fra PDF",
"Convert to PDF": "Konvertér til PDF",
"Create PDF Form": "Opret PDF-formular",
"Crop PDF": "Beskær PDF",
"CSV to PDF": "CSV til PDF",
"Delete Pages": "Slet sider",
"Deskew PDF": "Ret skæve sider",
"Digital Signature": "Digital signatur",
"Display detailed list": "Vis detaljeret liste",
"Divide Pages": "Opdel sider",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentation for BentoPDF: Den gratis, open source PDF-værktøjskasse med privatliv i første række",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Dobbelt licenseret under AGPL-3.0 og Kommerciel licens.",
"Duplex Collate": "Sortér dupleks-scanning",
"Edit & Annotate": "Redigér og annotér",
"Edit Attachments": "Redigér vedhæftninger",
"Edit Bookmarks": "Redigér bogmærker",
"Edit Metadata": "Redigér metadata",
"Email to PDF": "E-mail til PDF",
"EPUB to PDF": "EPUB til PDF",
"Excel to PDF": "Excel til PDF",
"Extract Attachments": "Udtræk vedhæftninger",
"Extract Images": "Udtræk billeder",
"Extract Pages": "Udtræk sider",
"Extract Tables": "Udtræk tabeller",
"FB2 to PDF": "FB2 til PDF",
"Fix Page Size": "Ret sidestørrelse",
"Flatten PDF": "Fladgør PDF",
"Font to Outline": "Skrifttype til kontur",
"Getting Started": "Kom i gang",
"Guide": "Guide",
"Header & Footer": "Sidehoved og sidefod",
"HEIC to PDF": "HEIC til PDF",
"Home": "Hjem",
"Hostinger": "Hostinger",
"Images to PDF": "Billeder til PDF",
"Invert Colors": "Invertér farver",
"JPG to PDF": "JPG til PDF",
"JSON to PDF": "JSON til PDF",
"Linearize PDF": "Lineariser PDF",
"Markdown to PDF": "Markdown til PDF",
"Menu": "Menu",
"Merge PDF": "Flet PDF",
"MOBI to PDF": "MOBI til PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Næste side",
"Nginx": "Nginx",
"No results for": "Ingen resultater for",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG til PDF",
"ODP to PDF": "ODP til PDF",
"ODS to PDF": "ODS til PDF",
"ODT to PDF": "ODT til PDF",
"On this page": "På denne side",
"Optimize & Repair": "Optimér og reparér",
"Organize & Duplicate": "Organisér og dupliker",
"Organize & Manage": "Organisér og administrér",
"Overview": "Oversigt",
"Page Dimensions": "Sidestørrelser",
"Page Numbers": "Sidetal",
"PDF Booklet": "PDF-hæfte",
"PDF Editor": "PDF-editor",
"PDF Form Filler": "PDF-formularudfylder",
"PDF Multi Tool": "PDF-multiværktøj",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF til BMP",
"PDF to CBZ": "PDF til CBZ",
"PDF to CSV": "PDF til CSV",
"PDF to Excel": "PDF til Excel",
"PDF to Greyscale": "PDF til gråtoner",
"PDF to JPG": "PDF til JPG",
"PDF to JSON": "PDF til JSON",
"PDF to Markdown": "PDF til Markdown",
"PDF to PDF/A": "PDF til PDF/A",
"PDF to PNG": "PDF til PNG",
"PDF to SVG": "PDF til SVG",
"PDF to Text": "PDF til tekst",
"PDF to TIFF": "PDF til TIFF",
"PDF to WebP": "PDF til WebP",
"PDF to Word": "PDF til Word",
"PDF Workflow Builder": "PDF-workflowbygger",
"PDFs to ZIP": "PDF’er til ZIP",
"PNG to PDF": "PNG til PDF",
"Posterize PDF": "Posterisér PDF",
"PowerPoint to PDF": "PowerPoint til PDF",
"Prepare PDF for AI": "Forbered PDF til AI",
"Previous page": "Forrige side",
"Protect PDF": "Beskyt PDF",
"PSD to PDF": "PSD til PDF",
"PUB to PDF": "PUB til PDF",
"Rasterize PDF": "Rasterisér PDF",
"Remove Annotations": "Fjern annotationer",
"Remove Blank Pages": "Fjern tomme sider",
"Remove Metadata": "Fjern metadata",
"Remove Restrictions": "Fjern begrænsninger",
"Repair PDF": "Reparér PDF",
"Reset search": "Nulstil søgning",
"Return to top": "Tilbage til toppen",
"Reverse Pages": "Vend sider",
"Rotate by Custom Degrees": "Roter med brugerdefineret vinkel",
"Rotate PDF": "Roter PDF",
"RTF to PDF": "RTF til PDF",
"Sanitize PDF": "Rens PDF",
"Scanner Effect": "Scannereffekt",
"Search": "Søg",
"Secure PDF": "Sikr PDF",
"Self-Hosting": "Selvhosting",
"Self-Hosting Guide": "Guide til selvhosting",
"Sign PDF": "Underskriv PDF",
"Skip to content": "Gå til indhold",
"Split PDF": "Opdel PDF",
"SVG to PDF": "SVG til PDF",
"Switch to dark theme": "Skift til mørkt tema",
"Switch to light theme": "Skift til lyst tema",
"Table of Contents": "Indholdsfortegnelse",
"Text to PDF": "Tekst til PDF",
"TIFF to PDF": "TIFF til PDF",
"to close": "for at lukke",
"to navigate": "for at navigere",
"to select": "for at vælge",
"Tools": "Værktøjer",
"Tools Reference": "Værktøjsreference",
"Unlock PDF": "Lås PDF op",
"Validate Signature": "Validér signatur",
"Vercel": "Vercel",
"View Metadata": "Vis metadata",
"VSD to PDF": "VSD til PDF",
"WebP to PDF": "WebP til PDF",
"Word to PDF": "Word til PDF",
"WPD to PDF": "WPD til PDF",
"WPS to PDF": "WPS til PDF",
"XML to PDF": "XML til PDF",
"XPS to PDF": "XPS til PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Anhänge hinzufügen",
"Add Blank Page": "Leere Seite hinzufügen",
"Add Page Labels": "Seitenbeschriftungen hinzufügen",
"Add Stamps": "Stempel hinzufügen",
"Add Watermark": "Wasserzeichen hinzufügen",
"Adjust Colors": "Farben anpassen",
"Alternate & Mix Pages": "Seiten abwechselnd mischen",
"Apache": "Apache",
"Appearance": "Darstellung",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Hintergrundfarbe",
"Bates Numbering": "Bates-Nummerierung",
"BMP to PDF": "BMP zu PDF",
"CBZ to PDF": "CBZ zu PDF",
"Change language": "Sprache ändern",
"Change Permissions": "Berechtigungen ändern",
"Change Text Color": "Textfarbe ändern",
"Close search": "Suche schließen",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Zu einer Seite kombinieren",
"Commercial License": "Kommerzielle Lizenz",
"Compare PDFs": "PDFs vergleichen",
"Compress PDF": "PDF komprimieren",
"Contributing": "Mitwirken",
"Convert from PDF": "Aus PDF konvertieren",
"Convert to PDF": "In PDF konvertieren",
"Create PDF Form": "PDF-Formular erstellen",
"Crop PDF": "PDF zuschneiden",
"CSV to PDF": "CSV zu PDF",
"Delete Pages": "Seiten löschen",
"Deskew PDF": "PDF entzerren",
"Digital Signature": "Digitale PDF-Signatur",
"Display detailed list": "Detaillierte Liste anzeigen",
"Divide Pages": "Seiten teilen",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentation für BentoPDF: das kostenlose Open-Source-PDF-Toolkit mit Fokus auf Privatsphäre",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Doppelt lizenziert unter AGPL-3.0 und kommerzieller Lizenz.",
"Duplex Collate": "Duplex-Zusammenführung",
"Edit & Annotate": "Bearbeiten & Annotieren",
"Edit Attachments": "Anhänge bearbeiten",
"Edit Bookmarks": "Lesezeichen bearbeiten",
"Edit Metadata": "Metadaten bearbeiten",
"Email to PDF": "E-Mail zu PDF",
"EPUB to PDF": "EPUB zu PDF",
"Excel to PDF": "Excel zu PDF",
"Extract Attachments": "Anhänge extrahieren",
"Extract Images": "Bilder extrahieren",
"Extract Pages": "Seiten extrahieren",
"Extract Tables": "PDF-Tabellen extrahieren",
"FB2 to PDF": "FB2 zu PDF",
"Fix Page Size": "Seitengröße reparieren",
"Flatten PDF": "PDF reduzieren",
"Font to Outline": "Schriftart zu Umriss",
"Getting Started": "Erste Schritte",
"Guide": "Anleitung",
"Header & Footer": "Kopf- & Fußzeile",
"HEIC to PDF": "HEIC zu PDF",
"Home": "Startseite",
"Hostinger": "Hostinger",
"Images to PDF": "Bilder zu PDF",
"Invert Colors": "Farben invertieren",
"JPG to PDF": "JPG zu PDF",
"JSON to PDF": "JSON zu PDF",
"Linearize PDF": "PDF linearisieren",
"Markdown to PDF": "Markdown zu PDF",
"Menu": "Menü",
"Merge PDF": "PDF zusammenführen",
"MOBI to PDF": "MOBI zu PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Nächste Seite",
"Nginx": "Nginx",
"No results for": "Keine Ergebnisse für",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG zu PDF",
"ODP to PDF": "ODP zu PDF",
"ODS to PDF": "ODS zu PDF",
"ODT to PDF": "ODT zu PDF",
"On this page": "Auf dieser Seite",
"Optimize & Repair": "Optimieren & Reparieren",
"Organize & Duplicate": "Duplizieren & Organisieren",
"Organize & Manage": "Organisieren & Verwalten",
"Overview": "Übersicht",
"Page Dimensions": "Seitenmaße",
"Page Numbers": "Seitenzahlen",
"PDF Booklet": "PDF-Broschüre",
"PDF Editor": "PDF-Editor",
"PDF Form Filler": "PDF-Formular ausfüllen",
"PDF Multi Tool": "PDF-Multitool",
"PDF OCG": "PDF-Ebenen (OCG)",
"PDF to BMP": "PDF zu BMP",
"PDF to CBZ": "PDF zu CBZ",
"PDF to CSV": "PDF zu CSV",
"PDF to Excel": "PDF zu Excel",
"PDF to Greyscale": "PDF zu Graustufen",
"PDF to JPG": "PDF zu JPG",
"PDF to JSON": "PDF zu JSON",
"PDF to Markdown": "PDF zu Markdown",
"PDF to PDF/A": "PDF zu PDF/A",
"PDF to PNG": "PDF zu PNG",
"PDF to SVG": "PDF zu SVG",
"PDF to Text": "PDF zu Text",
"PDF to TIFF": "PDF zu TIFF",
"PDF to WebP": "PDF zu WebP",
"PDF to Word": "PDF zu Word",
"PDF Workflow Builder": "PDF-Workflow-Builder",
"PDFs to ZIP": "PDFs zu ZIP",
"PNG to PDF": "PNG zu PDF",
"Posterize PDF": "PDF posterisieren",
"PowerPoint to PDF": "PowerPoint zu PDF",
"Prepare PDF for AI": "PDF für KI vorbereiten",
"Previous page": "Vorherige Seite",
"Protect PDF": "PDF schützen",
"PSD to PDF": "PSD zu PDF",
"PUB to PDF": "PUB zu PDF",
"Rasterize PDF": "PDF rastern",
"Remove Annotations": "Annotationen entfernen",
"Remove Blank Pages": "Leere Seiten entfernen",
"Remove Metadata": "Metadaten entfernen",
"Remove Restrictions": "Beschränkungen entfernen",
"Repair PDF": "PDF reparieren",
"Reset search": "Suche zurücksetzen",
"Return to top": "Zurück nach oben",
"Reverse Pages": "Seiten umkehren",
"Rotate by Custom Degrees": "Um benutzerdefinierte Grad drehen",
"Rotate PDF": "PDF drehen",
"RTF to PDF": "RTF zu PDF",
"Sanitize PDF": "PDF bereinigen",
"Scanner Effect": "Scanner-Effekt",
"Search": "Suchen",
"Secure PDF": "PDF sichern",
"Self-Hosting": "Selbst hosten",
"Self-Hosting Guide": "Anleitung zum Selbst-Hosting",
"Sign PDF": "PDF unterschreiben",
"Skip to content": "Zum Inhalt springen",
"Split PDF": "PDF teilen",
"SVG to PDF": "SVG zu PDF",
"Switch to dark theme": "Zum dunklen Design wechseln",
"Switch to light theme": "Zum hellen Design wechseln",
"Table of Contents": "Inhaltsverzeichnis",
"Text to PDF": "Text zu PDF",
"TIFF to PDF": "TIFF zu PDF",
"to close": "zum Schließen",
"to navigate": "zum Navigieren",
"to select": "zum Auswählen",
"Tools": "Werkzeuge",
"Tools Reference": "Werkzeugübersicht",
"Unlock PDF": "PDF entsperren",
"Validate Signature": "PDF-Signatur überprüfen",
"Vercel": "Vercel",
"View Metadata": "Metadaten anzeigen",
"VSD to PDF": "VSD zu PDF",
"WebP to PDF": "WebP zu PDF",
"Word to PDF": "Word zu PDF",
"WPD to PDF": "WPD zu PDF",
"WPS to PDF": "WPS zu PDF",
"XML to PDF": "XML zu PDF",
"XPS to PDF": "XPS zu PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Agregar adjuntos",
"Add Blank Page": "Agregar página en blanco",
"Add Page Labels": "Agregar etiquetas de página",
"Add Stamps": "Agregar sellos",
"Add Watermark": "Agregar marca de agua",
"Adjust Colors": "Ajustar colores",
"Alternate & Mix Pages": "Alternar y mezclar páginas",
"Apache": "Apache",
"Appearance": "Apariencia",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Color de fondo",
"Bates Numbering": "Numeración Bates",
"BMP to PDF": "BMP a PDF",
"CBZ to PDF": "CBZ a PDF",
"Change language": "Cambiar idioma",
"Change Permissions": "Cambiar permisos",
"Change Text Color": "Cambiar color de texto",
"Close search": "Cerrar búsqueda",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combinar en una sola página",
"Commercial License": "Licencia comercial",
"Compare PDFs": "Comparar PDFs",
"Compress PDF": "Comprimir PDF",
"Contributing": "Contribuir",
"Convert from PDF": "Convertir desde PDF",
"Convert to PDF": "Convertir a PDF",
"Create PDF Form": "Crear formulario PDF",
"Crop PDF": "Recortar PDF",
"CSV to PDF": "CSV a PDF",
"Delete Pages": "Eliminar páginas",
"Deskew PDF": "Enderezar PDF",
"Digital Signature": "Firma Digital PDF",
"Display detailed list": "Mostrar lista detallada",
"Divide Pages": "Dividir páginas",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentación de BentoPDF: el kit de herramientas PDF gratuito, de código abierto y centrado en la privacidad",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Con doble licencia: AGPL-3.0 y licencia comercial.",
"Duplex Collate": "Intercalar escaneo a doble cara",
"Edit & Annotate": "Editar y anotar",
"Edit Attachments": "Editar adjuntos",
"Edit Bookmarks": "Editar marcadores",
"Edit Metadata": "Editar metadatos",
"Email to PDF": "Email a PDF",
"EPUB to PDF": "EPUB a PDF",
"Excel to PDF": "Excel a PDF",
"Extract Attachments": "Extraer adjuntos",
"Extract Images": "Extraer imágenes",
"Extract Pages": "Extraer páginas",
"Extract Tables": "Extraer Tablas de PDF",
"FB2 to PDF": "FB2 a PDF",
"Fix Page Size": "Ajustar tamaño de página",
"Flatten PDF": "Aplanar PDF",
"Font to Outline": "Fuente a contorno",
"Getting Started": "Primeros pasos",
"Guide": "Guía",
"Header & Footer": "Encabezado y pie de página",
"HEIC to PDF": "HEIC a PDF",
"Home": "Inicio",
"Hostinger": "Hostinger",
"Images to PDF": "Imágenes a PDF",
"Invert Colors": "Invertir colores",
"JPG to PDF": "JPG a PDF",
"JSON to PDF": "JSON a PDF",
"Linearize PDF": "Linealizar PDF",
"Markdown to PDF": "Markdown a PDF",
"Menu": "Menú",
"Merge PDF": "Fusionar PDF",
"MOBI to PDF": "MOBI a PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Página siguiente",
"Nginx": "Nginx",
"No results for": "Sin resultados para",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG a PDF",
"ODP to PDF": "ODP a PDF",
"ODS to PDF": "ODS a PDF",
"ODT to PDF": "ODT a PDF",
"On this page": "En esta página",
"Optimize & Repair": "Optimizar y reparar",
"Organize & Duplicate": "Duplicar y Organizar",
"Organize & Manage": "Organizar y gestionar",
"Overview": "Resumen",
"Page Dimensions": "Dimensiones de página",
"Page Numbers": "Números de página",
"PDF Booklet": "Folleto PDF",
"PDF Editor": "Editor PDF",
"PDF Form Filler": "Rellenar formularios PDF",
"PDF Multi Tool": "Multiherramienta PDF",
"PDF OCG": "Capas PDF (OCG)",
"PDF to BMP": "PDF a BMP",
"PDF to CBZ": "PDF a CBZ",
"PDF to CSV": "PDF a CSV",
"PDF to Excel": "PDF a Excel",
"PDF to Greyscale": "PDF a escala de grises",
"PDF to JPG": "PDF a JPG",
"PDF to JSON": "PDF a JSON",
"PDF to Markdown": "PDF a Markdown",
"PDF to PDF/A": "PDF a PDF/A",
"PDF to PNG": "PDF a PNG",
"PDF to SVG": "PDF a SVG",
"PDF to Text": "PDF a texto",
"PDF to TIFF": "PDF a TIFF",
"PDF to WebP": "PDF a WebP",
"PDF to Word": "PDF a Word",
"PDF Workflow Builder": "Constructor de flujos de trabajo PDF",
"PDFs to ZIP": "PDFs a ZIP",
"PNG to PDF": "PNG a PDF",
"Posterize PDF": "Posterizar PDF",
"PowerPoint to PDF": "PowerPoint a PDF",
"Prepare PDF for AI": "Preparar PDF para IA",
"Previous page": "Página anterior",
"Protect PDF": "Proteger PDF",
"PSD to PDF": "PSD a PDF",
"PUB to PDF": "PUB a PDF",
"Rasterize PDF": "Rasterizar PDF",
"Remove Annotations": "Eliminar anotaciones",
"Remove Blank Pages": "Eliminar páginas en blanco",
"Remove Metadata": "Eliminar metadatos",
"Remove Restrictions": "Eliminar restricciones",
"Repair PDF": "Reparar PDF",
"Reset search": "Restablecer búsqueda",
"Return to top": "Volver arriba",
"Reverse Pages": "Invertir páginas",
"Rotate by Custom Degrees": "Rotar por grados personalizados",
"Rotate PDF": "Rotar PDF",
"RTF to PDF": "RTF a PDF",
"Sanitize PDF": "Sanear PDF",
"Scanner Effect": "Efecto escáner",
"Search": "Buscar",
"Secure PDF": "Proteger PDF",
"Self-Hosting": "Autoalojamiento",
"Self-Hosting Guide": "Guía de autoalojamiento",
"Sign PDF": "Firmar PDF",
"Skip to content": "Saltar al contenido",
"Split PDF": "Dividir PDF",
"SVG to PDF": "SVG a PDF",
"Switch to dark theme": "Cambiar al tema oscuro",
"Switch to light theme": "Cambiar al tema claro",
"Table of Contents": "Índice",
"Text to PDF": "Texto a PDF",
"TIFF to PDF": "TIFF a PDF",
"to close": "para cerrar",
"to navigate": "para navegar",
"to select": "para seleccionar",
"Tools": "Herramientas",
"Tools Reference": "Referencia de herramientas",
"Unlock PDF": "Desbloquear PDF",
"Validate Signature": "Validar Firma PDF",
"Vercel": "Vercel",
"View Metadata": "Ver metadatos",
"VSD to PDF": "VSD a PDF",
"WebP to PDF": "WebP a PDF",
"Word to PDF": "Word a PDF",
"WPD to PDF": "WPD a PDF",
"WPS to PDF": "WPS a PDF",
"XML to PDF": "XML a PDF",
"XPS to PDF": "XPS a PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "افزودن پیوست",
"Add Blank Page": "افزودن صفحهٔ خالی",
"Add Page Labels": "افزودن برچسب صفحه",
"Add Stamps": "افزودن مهر",
"Add Watermark": "افزودن واترمارک",
"Adjust Colors": "تنظیم رنگ‌ها",
"Alternate & Mix Pages": "ادغام یک‌درمیان صفحات",
"Apache": "Apache",
"Appearance": "ظاهر",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "رنگ پس‌زمینه",
"Bates Numbering": "شماره‌گذاری Bates",
"BMP to PDF": "BMP به PDF",
"CBZ to PDF": "CBZ به PDF",
"Change language": "تغییر زبان",
"Change Permissions": "تغییر مجوزها",
"Change Text Color": "تغییر رنگ متن",
"Close search": "بستن جستجو",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "ترکیب در یک صفحه",
"Commercial License": "مجوز تجاری",
"Compare PDFs": "مقایسهٔ PDFها",
"Compress PDF": "فشرده‌سازی PDF",
"Contributing": "مشارکت",
"Convert from PDF": "تبدیل از PDF",
"Convert to PDF": "تبدیل به PDF",
"Create PDF Form": "ساخت فرم PDF",
"Crop PDF": "برش PDF",
"CSV to PDF": "CSV به PDF",
"Delete Pages": "حذف صفحات",
"Deskew PDF": "صاف‌کردن PDF",
"Digital Signature": "امضای دیجیتال",
"Display detailed list": "نمایش فهرست تفصیلی",
"Divide Pages": "تقسیم صفحات",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "مستندات BentoPDF، مجموعه ابزار PDF رایگان، متن‌باز و حریم‌خصوصی‌محور",
"Dual-licensed under AGPL-3.0 and Commercial License.": "دارای مجوز دوگانه: AGPL-3.0 و مجوز تجاری.",
"Duplex Collate": "تلفیق دورو",
"Edit & Annotate": "ویرایش و حاشیه‌نویسی",
"Edit Attachments": "ویرایش پیوست‌ها",
"Edit Bookmarks": "ویرایش نشانک‌ها",
"Edit Metadata": "ویرایش فراداده",
"Email to PDF": "ایمیل به PDF",
"EPUB to PDF": "EPUB به PDF",
"Excel to PDF": "Excel به PDF",
"Extract Attachments": "استخراج پیوست‌ها",
"Extract Images": "استخراج تصاویر",
"Extract Pages": "استخراج صفحات",
"Extract Tables": "استخراج جدول‌های PDF",
"FB2 to PDF": "FB2 به PDF",
"Fix Page Size": "اصلاح اندازهٔ صفحه",
"Flatten PDF": "مسطح‌سازی PDF",
"Font to Outline": "تبدیل قلم به خطوط برداری",
"Getting Started": "شروع کار",
"Guide": "راهنما",
"Header & Footer": "سرصفحه و پاصفحه",
"HEIC to PDF": "HEIC به PDF",
"Home": "خانه",
"Hostinger": "Hostinger",
"Images to PDF": "تصاویر به PDF",
"Invert Colors": "وارونه‌سازی رنگ‌ها",
"JPG to PDF": "JPG به PDF",
"JSON to PDF": "JSON به PDF",
"Linearize PDF": "خطی‌سازی PDF",
"Markdown to PDF": "Markdown به PDF",
"Menu": "منو",
"Merge PDF": "ادغام PDF",
"MOBI to PDF": "MOBI به PDF",
"N-Up PDF": "N-Up کردن PDF",
"Netlify": "Netlify",
"Next page": "صفحهٔ بعد",
"Nginx": "Nginx",
"No results for": "نتیجه‌ای یافت نشد برای",
"OCR PDF": "OCR روی PDF",
"ODG to PDF": "ODG به PDF",
"ODP to PDF": "ODP به PDF",
"ODS to PDF": "ODS به PDF",
"ODT to PDF": "ODT به PDF",
"On this page": "در این صفحه",
"Optimize & Repair": "بهینه‌سازی و ترمیم",
"Organize & Duplicate": "تکثیر و سازماندهی",
"Organize & Manage": "سازماندهی و مدیریت",
"Overview": "نمای کلی",
"Page Dimensions": "ابعاد صفحه",
"Page Numbers": "شماره‌گذاری صفحات",
"PDF Booklet": "دفترچهٔ PDF",
"PDF Editor": "ویرایشگر PDF",
"PDF Form Filler": "پرکنندهٔ فرم PDF",
"PDF Multi Tool": "ابزار چندکارهٔ PDF",
"PDF OCG": "لایه‌های OCG در PDF",
"PDF to BMP": "PDF به BMP",
"PDF to CBZ": "PDF به CBZ",
"PDF to CSV": "PDF به CSV",
"PDF to Excel": "PDF به Excel",
"PDF to Greyscale": "PDF به خاکستری",
"PDF to JPG": "PDF به JPG",
"PDF to JSON": "PDF به JSON",
"PDF to Markdown": "PDF به Markdown",
"PDF to PDF/A": "PDF به PDF/A",
"PDF to PNG": "PDF به PNG",
"PDF to SVG": "PDF به SVG",
"PDF to Text": "PDF به متن",
"PDF to TIFF": "PDF به TIFF",
"PDF to WebP": "PDF به WebP",
"PDF to Word": "PDF به Word",
"PDF Workflow Builder": "سازندهٔ گردش کار PDF",
"PDFs to ZIP": "PDFها به ZIP",
"PNG to PDF": "PNG به PDF",
"Posterize PDF": "پوستری‌کردن PDF",
"PowerPoint to PDF": "PowerPoint به PDF",
"Prepare PDF for AI": "آماده‌سازی PDF برای هوش مصنوعی",
"Previous page": "صفحهٔ قبل",
"Protect PDF": "محافظت از PDF",
"PSD to PDF": "PSD به PDF",
"PUB to PDF": "PUB به PDF",
"Rasterize PDF": "رستر کردن PDF",
"Remove Annotations": "حذف حاشیه‌نویسی‌ها",
"Remove Blank Pages": "حذف صفحات خالی",
"Remove Metadata": "حذف فراداده",
"Remove Restrictions": "حذف محدودیت‌ها",
"Repair PDF": "ترمیم PDF",
"Reset search": "بازنشانی جستجو",
"Return to top": "بازگشت به بالا",
"Reverse Pages": "وارونه‌سازی ترتیب صفحات",
"Rotate by Custom Degrees": "چرخاندن با زاویهٔ دلخواه",
"Rotate PDF": "چرخاندن PDF",
"RTF to PDF": "RTF به PDF",
"Sanitize PDF": "پاک‌سازی PDF",
"Scanner Effect": "جلوهٔ اسکنر",
"Search": "جستجو",
"Secure PDF": "ایمن‌سازی PDF",
"Self-Hosting": "میزبانی شخصی",
"Self-Hosting Guide": "راهنمای میزبانی شخصی",
"Sign PDF": "امضای PDF",
"Skip to content": "رفتن به محتوا",
"Split PDF": "تقسیم PDF",
"SVG to PDF": "SVG به PDF",
"Switch to dark theme": "تغییر به پوستهٔ تیره",
"Switch to light theme": "تغییر به پوستهٔ روشن",
"Table of Contents": "فهرست مطالب",
"Text to PDF": "متن به PDF",
"TIFF to PDF": "TIFF به PDF",
"to close": "برای بستن",
"to navigate": "برای پیمایش",
"to select": "برای انتخاب",
"Tools": "ابزارها",
"Tools Reference": "مرجع ابزارها",
"Unlock PDF": "باز کردن قفل PDF",
"Validate Signature": "اعتبارسنجی امضا",
"Vercel": "Vercel",
"View Metadata": "مشاهدهٔ فراداده",
"VSD to PDF": "VSD به PDF",
"WebP to PDF": "WebP به PDF",
"Word to PDF": "Word به PDF",
"WPD to PDF": "WPD به PDF",
"WPS to PDF": "WPS به PDF",
"XML to PDF": "XML به PDF",
"XPS to PDF": "XPS به PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Ajouter des pièces jointes",
"Add Blank Page": "Ajouter une page vierge",
"Add Page Labels": "Ajouter des étiquettes de page",
"Add Stamps": "Ajouter des tampons",
"Add Watermark": "Ajouter un filigrane",
"Adjust Colors": "Ajuster les couleurs",
"Alternate & Mix Pages": "Alterner et mélanger les pages",
"Apache": "Apache",
"Appearance": "Apparence",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Couleur de fond",
"Bates Numbering": "Numérotation Bates",
"BMP to PDF": "BMP vers PDF",
"CBZ to PDF": "CBZ vers PDF",
"Change language": "Changer de langue",
"Change Permissions": "Modifier les autorisations",
"Change Text Color": "Changer la couleur du texte",
"Close search": "Fermer la recherche",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combiner en une seule page",
"Commercial License": "Licence commerciale",
"Compare PDFs": "Comparer des PDF",
"Compress PDF": "Compresser un PDF",
"Contributing": "Contribuer",
"Convert from PDF": "Convertir depuis PDF",
"Convert to PDF": "Convertir vers PDF",
"Create PDF Form": "Créer un formulaire PDF",
"Crop PDF": "Rogner un PDF",
"CSV to PDF": "CSV vers PDF",
"Delete Pages": "Supprimer des pages",
"Deskew PDF": "Redresser un PDF",
"Digital Signature": "Signature numérique PDF",
"Display detailed list": "Afficher la liste détaillée",
"Divide Pages": "Diviser les pages",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentation de BentoPDF : la boîte à outils PDF gratuite, open source et axée sur la confidentialité",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Double licence : AGPL-3.0 et licence commerciale.",
"Duplex Collate": "Assembler un scan recto/verso",
"Edit & Annotate": "Modifier et annoter",
"Edit Attachments": "Gérer les pièces jointes",
"Edit Bookmarks": "Modifier les signets",
"Edit Metadata": "Modifier les métadonnées",
"Email to PDF": "Email vers PDF",
"EPUB to PDF": "EPUB vers PDF",
"Excel to PDF": "Excel vers PDF",
"Extract Attachments": "Extraire les pièces jointes",
"Extract Images": "Extraire les images",
"Extract Pages": "Extraire des pages",
"Extract Tables": "Extraire les tableaux PDF",
"FB2 to PDF": "FB2 vers PDF",
"Fix Page Size": "Uniformiser la taille des pages",
"Flatten PDF": "Aplatir le PDF",
"Font to Outline": "Polices en contours",
"Getting Started": "Premiers pas",
"Guide": "Guide",
"Header & Footer": "En-tête et pied de page",
"HEIC to PDF": "HEIC vers PDF",
"Home": "Accueil",
"Hostinger": "Hostinger",
"Images to PDF": "Images vers PDF",
"Invert Colors": "Inverser les couleurs",
"JPG to PDF": "JPG vers PDF",
"JSON to PDF": "JSON vers PDF",
"Linearize PDF": "Optimiser pour le web",
"Markdown to PDF": "Markdown vers PDF",
"Menu": "Menu",
"Merge PDF": "Fusionner des PDF",
"MOBI to PDF": "MOBI vers PDF",
"N-Up PDF": "PDF N-up",
"Netlify": "Netlify",
"Next page": "Page suivante",
"Nginx": "Nginx",
"No results for": "Aucun résultat pour",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG vers PDF",
"ODP to PDF": "ODP vers PDF",
"ODS to PDF": "ODS vers PDF",
"ODT to PDF": "ODT vers PDF",
"On this page": "Sur cette page",
"Optimize & Repair": "Optimiser et réparer",
"Organize & Duplicate": "Dupliquer et organiser",
"Organize & Manage": "Organiser et gérer",
"Overview": "Vue d’ensemble",
"Page Dimensions": "Dimensions des pages",
"Page Numbers": "Numéros de page",
"PDF Booklet": "Livret PDF",
"PDF Editor": "Éditeur PDF",
"PDF Form Filler": "Remplir un formulaire PDF",
"PDF Multi Tool": "Outil PDF tout-en-un",
"PDF OCG": "Calques PDF (OCG)",
"PDF to BMP": "PDF vers BMP",
"PDF to CBZ": "PDF vers CBZ",
"PDF to CSV": "PDF vers CSV",
"PDF to Excel": "PDF vers Excel",
"PDF to Greyscale": "PDF en niveaux de gris",
"PDF to JPG": "PDF vers JPG",
"PDF to JSON": "PDF vers JSON",
"PDF to Markdown": "PDF vers Markdown",
"PDF to PDF/A": "PDF vers PDF/A",
"PDF to PNG": "PDF vers PNG",
"PDF to SVG": "PDF vers SVG",
"PDF to Text": "PDF vers texte",
"PDF to TIFF": "PDF vers TIFF",
"PDF to WebP": "PDF vers WebP",
"PDF to Word": "PDF vers Word",
"PDF Workflow Builder": "Constructeur de workflow PDF",
"PDFs to ZIP": "PDF vers ZIP",
"PNG to PDF": "PNG vers PDF",
"Posterize PDF": "Posteriser un PDF",
"PowerPoint to PDF": "PowerPoint vers PDF",
"Prepare PDF for AI": "Préparer le PDF pour l'IA",
"Previous page": "Page précédente",
"Protect PDF": "Protéger un PDF",
"PSD to PDF": "PSD vers PDF",
"PUB to PDF": "PUB vers PDF",
"Rasterize PDF": "Rastériser le PDF",
"Remove Annotations": "Supprimer les annotations",
"Remove Blank Pages": "Supprimer les pages blanches",
"Remove Metadata": "Supprimer les métadonnées",
"Remove Restrictions": "Supprimer les restrictions",
"Repair PDF": "Réparer un PDF",
"Reset search": "Réinitialiser la recherche",
"Return to top": "Retour en haut",
"Reverse Pages": "Inverser l’ordre des pages",
"Rotate by Custom Degrees": "Rotation par angle personnalisé",
"Rotate PDF": "Faire pivoter un PDF",
"RTF to PDF": "RTF vers PDF",
"Sanitize PDF": "Nettoyer un PDF",
"Scanner Effect": "Effet scanner",
"Search": "Rechercher",
"Secure PDF": "Sécuriser un PDF",
"Self-Hosting": "Auto-hébergement",
"Self-Hosting Guide": "Guide d’auto-hébergement",
"Sign PDF": "Signer un PDF",
"Skip to content": "Aller au contenu",
"Split PDF": "Scinder un PDF",
"SVG to PDF": "SVG vers PDF",
"Switch to dark theme": "Passer au thème sombre",
"Switch to light theme": "Passer au thème clair",
"Table of Contents": "Table des matières",
"Text to PDF": "Texte vers PDF",
"TIFF to PDF": "TIFF vers PDF",
"to close": "pour fermer",
"to navigate": "pour naviguer",
"to select": "pour sélectionner",
"Tools": "Outils",
"Tools Reference": "Référence des outils",
"Unlock PDF": "Déverrouiller un PDF",
"Validate Signature": "Valider la signature PDF",
"Vercel": "Vercel",
"View Metadata": "Afficher les métadonnées",
"VSD to PDF": "VSD vers PDF",
"WebP to PDF": "WebP vers PDF",
"Word to PDF": "Word vers PDF",
"WPD to PDF": "WPD vers PDF",
"WPS to PDF": "WPS vers PDF",
"XML to PDF": "XML vers PDF",
"XPS to PDF": "XPS vers PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Tambah Lampiran",
"Add Blank Page": "Tambah Halaman Kosong",
"Add Page Labels": "Tambahkan label halaman",
"Add Stamps": "Tambah Stempel",
"Add Watermark": "Tambah Watermark",
"Adjust Colors": "Sesuaikan Warna",
"Alternate & Mix Pages": "Selang-seling & Campur Halaman",
"Apache": "Apache",
"Appearance": "Tampilan",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Warna Latar Belakang",
"Bates Numbering": "Penomoran Bates",
"BMP to PDF": "BMP ke PDF",
"CBZ to PDF": "CBZ ke PDF",
"Change language": "Ubah bahasa",
"Change Permissions": "Ubah Izin",
"Change Text Color": "Ubah Warna Teks",
"Close search": "Tutup pencarian",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Gabung ke Halaman Tunggal",
"Commercial License": "Lisensi Komersial",
"Compare PDFs": "Bandingkan PDF",
"Compress PDF": "Kompres PDF",
"Contributing": "Berkontribusi",
"Convert from PDF": "Konversi dari PDF",
"Convert to PDF": "Konversi ke PDF",
"Create PDF Form": "Buat Formulir PDF",
"Crop PDF": "Potong PDF",
"CSV to PDF": "CSV ke PDF",
"Delete Pages": "Hapus Halaman",
"Deskew PDF": "Luruskan PDF",
"Digital Signature": "Tanda Tangan Digital",
"Display detailed list": "Tampilkan daftar terperinci",
"Divide Pages": "Bagi Halaman",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentasi BentoPDF - Toolkit PDF gratis, sumber terbuka, dan mengutamakan privasi",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Berlisensi ganda di bawah AGPL-3.0 dan Lisensi Komersial.",
"Duplex Collate": "Susun Ulang Pindaian Dupleks",
"Edit & Annotate": "Edit & Anotasi",
"Edit Attachments": "Edit Lampiran",
"Edit Bookmarks": "Edit Bookmark",
"Edit Metadata": "Edit Metadata",
"Email to PDF": "Email ke PDF",
"EPUB to PDF": "EPUB ke PDF",
"Excel to PDF": "Excel ke PDF",
"Extract Attachments": "Ekstrak Lampiran",
"Extract Images": "Ekstrak Gambar",
"Extract Pages": "Ekstrak Halaman",
"Extract Tables": "Ekstrak Tabel PDF",
"FB2 to PDF": "FB2 ke PDF",
"Fix Page Size": "Perbaiki Ukuran Halaman",
"Flatten PDF": "Ratakan PDF",
"Font to Outline": "Font ke Garis Tepi",
"Getting Started": "Memulai",
"Guide": "Panduan",
"Header & Footer": "Kepala & Kaki Halaman",
"HEIC to PDF": "HEIC ke PDF",
"Home": "Beranda",
"Hostinger": "Hostinger",
"Images to PDF": "Gambar ke PDF",
"Invert Colors": "Balik Warna",
"JPG to PDF": "JPG ke PDF",
"JSON to PDF": "JSON ke PDF",
"Linearize PDF": "Linierisasi PDF",
"Markdown to PDF": "Markdown ke PDF",
"Menu": "Menu",
"Merge PDF": "Gabung PDF",
"MOBI to PDF": "MOBI ke PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Halaman berikutnya",
"Nginx": "Nginx",
"No results for": "Tidak ada hasil untuk",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG ke PDF",
"ODP to PDF": "ODP ke PDF",
"ODS to PDF": "ODS ke PDF",
"ODT to PDF": "ODT ke PDF",
"On this page": "Di halaman ini",
"Optimize & Repair": "Optimalkan & Perbaiki",
"Organize & Duplicate": "Duplikat & Atur",
"Organize & Manage": "Atur & Kelola",
"Overview": "Ringkasan",
"Page Dimensions": "Dimensi Halaman",
"Page Numbers": "Nomor Halaman",
"PDF Booklet": "Buku Kecil PDF",
"PDF Editor": "Editor PDF",
"PDF Form Filler": "Pengisi Formulir PDF",
"PDF Multi Tool": "Alat Multi PDF",
"PDF OCG": "Lapisan PDF (OCG)",
"PDF to BMP": "PDF ke BMP",
"PDF to CBZ": "PDF ke CBZ",
"PDF to CSV": "PDF ke CSV",
"PDF to Excel": "PDF ke Excel",
"PDF to Greyscale": "PDF ke Skala Abu-abu",
"PDF to JPG": "PDF ke JPG",
"PDF to JSON": "PDF ke JSON",
"PDF to Markdown": "PDF ke Markdown",
"PDF to PDF/A": "PDF ke PDF/A",
"PDF to PNG": "PDF ke PNG",
"PDF to SVG": "PDF ke SVG",
"PDF to Text": "PDF ke Teks",
"PDF to TIFF": "PDF ke TIFF",
"PDF to WebP": "PDF ke WebP",
"PDF to Word": "PDF ke Word",
"PDF Workflow Builder": "Pembangun Alur Kerja PDF",
"PDFs to ZIP": "PDF ke ZIP",
"PNG to PDF": "PNG ke PDF",
"Posterize PDF": "Posterisasi PDF",
"PowerPoint to PDF": "PowerPoint ke PDF",
"Prepare PDF for AI": "Siapkan PDF untuk AI",
"Previous page": "Halaman sebelumnya",
"Protect PDF": "Lindungi PDF",
"PSD to PDF": "PSD ke PDF",
"PUB to PDF": "PUB ke PDF",
"Rasterize PDF": "Rasterisasi PDF",
"Remove Annotations": "Hapus Anotasi",
"Remove Blank Pages": "Hapus Halaman Kosong",
"Remove Metadata": "Hapus Metadata",
"Remove Restrictions": "Hapus Pembatasan",
"Repair PDF": "Perbaiki PDF",
"Reset search": "Atur ulang pencarian",
"Return to top": "Kembali ke atas",
"Reverse Pages": "Balik Halaman",
"Rotate by Custom Degrees": "Putar dengan Derajat Kustom",
"Rotate PDF": "Putar PDF",
"RTF to PDF": "RTF ke PDF",
"Sanitize PDF": "Sanitasi PDF",
"Scanner Effect": "Efek Pemindai",
"Search": "Cari",
"Secure PDF": "Amankan PDF",
"Self-Hosting": "Hosting Mandiri",
"Self-Hosting Guide": "Panduan Hosting Mandiri",
"Sign PDF": "Tanda Tangan PDF",
"Skip to content": "Lewati ke konten",
"Split PDF": "Pisah PDF",
"SVG to PDF": "SVG ke PDF",
"Switch to dark theme": "Beralih ke tema gelap",
"Switch to light theme": "Beralih ke tema terang",
"Table of Contents": "Daftar Isi",
"Text to PDF": "Teks ke PDF",
"TIFF to PDF": "TIFF ke PDF",
"to close": "untuk menutup",
"to navigate": "untuk bernavigasi",
"to select": "untuk memilih",
"Tools": "Alat",
"Tools Reference": "Referensi Alat",
"Unlock PDF": "Buka Kunci PDF",
"Validate Signature": "Validasi Tanda Tangan PDF",
"Vercel": "Vercel",
"View Metadata": "Lihat Metadata",
"VSD to PDF": "VSD ke PDF",
"WebP to PDF": "WebP ke PDF",
"Word to PDF": "Word ke PDF",
"WPD to PDF": "WPD ke PDF",
"WPS to PDF": "WPS ke PDF",
"XML to PDF": "XML ke PDF",
"XPS to PDF": "XPS ke PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Aggiungi allegati",
"Add Blank Page": "Aggiungi pagina vuota",
"Add Page Labels": "Aggiungi etichette di pagina",
"Add Stamps": "Aggiungi timbri",
"Add Watermark": "Aggiungi filigrana",
"Adjust Colors": "Regola colori",
"Alternate & Mix Pages": "Alterna e mescola pagine",
"Apache": "Apache",
"Appearance": "Aspetto",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Colore di sfondo",
"Bates Numbering": "Numerazione Bates",
"BMP to PDF": "BMP in PDF",
"CBZ to PDF": "CBZ in PDF",
"Change language": "Cambia lingua",
"Change Permissions": "Modifica permessi",
"Change Text Color": "Cambia colore testo",
"Close search": "Chiudi la ricerca",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combina in una pagina",
"Commercial License": "Licenza commerciale",
"Compare PDFs": "Confronta PDF",
"Compress PDF": "Comprimi PDF",
"Contributing": "Contribuire",
"Convert from PDF": "Converti da PDF",
"Convert to PDF": "Converti in PDF",
"Create PDF Form": "Crea modulo PDF",
"Crop PDF": "Ritaglia PDF",
"CSV to PDF": "CSV in PDF",
"Delete Pages": "Elimina pagine",
"Deskew PDF": "Raddrizza PDF",
"Digital Signature": "Firma digitale",
"Display detailed list": "Mostra elenco dettagliato",
"Divide Pages": "Dividi pagine",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentazione di BentoPDF: il toolkit PDF gratuito, open source e attento alla privacy",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Doppia licenza: AGPL-3.0 e Licenza commerciale.",
"Duplex Collate": "Fascicola scansione fronte/retro",
"Edit & Annotate": "Modifica e annota",
"Edit Attachments": "Modifica allegati",
"Edit Bookmarks": "Modifica segnalibri",
"Edit Metadata": "Modifica metadati",
"Email to PDF": "Email in PDF",
"EPUB to PDF": "EPUB in PDF",
"Excel to PDF": "Excel in PDF",
"Extract Attachments": "Estrai allegati",
"Extract Images": "Estrai immagini",
"Extract Pages": "Estrai pagine",
"Extract Tables": "Estrai tabelle",
"FB2 to PDF": "FB2 in PDF",
"Fix Page Size": "Correggi dimensione pagina",
"Flatten PDF": "Appiattisci PDF",
"Font to Outline": "Font in contorni",
"Getting Started": "Per iniziare",
"Guide": "Guida",
"Header & Footer": "Intestazione e piè di pagina",
"HEIC to PDF": "HEIC in PDF",
"Home": "Home",
"Hostinger": "Hostinger",
"Images to PDF": "Immagini in PDF",
"Invert Colors": "Inverti colori",
"JPG to PDF": "JPG in PDF",
"JSON to PDF": "JSON in PDF",
"Linearize PDF": "Linearizza PDF",
"Markdown to PDF": "Markdown in PDF",
"Menu": "Menu",
"Merge PDF": "Unisci PDF",
"MOBI to PDF": "MOBI in PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Pagina successiva",
"Nginx": "Nginx",
"No results for": "Nessun risultato per",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG in PDF",
"ODP to PDF": "ODP in PDF",
"ODS to PDF": "ODS in PDF",
"ODT to PDF": "ODT in PDF",
"On this page": "In questa pagina",
"Optimize & Repair": "Ottimizza e ripara",
"Organize & Duplicate": "Organizza e duplica",
"Organize & Manage": "Organizza e gestisci",
"Overview": "Panoramica",
"Page Dimensions": "Dimensioni pagina",
"Page Numbers": "Numeri di pagina",
"PDF Booklet": "Opuscolo PDF",
"PDF Editor": "Editor PDF",
"PDF Form Filler": "Compilatore moduli PDF",
"PDF Multi Tool": "Strumento PDF multifunzione",
"PDF OCG": "Livelli PDF (OCG)",
"PDF to BMP": "PDF in BMP",
"PDF to CBZ": "PDF in CBZ",
"PDF to CSV": "PDF in CSV",
"PDF to Excel": "PDF in Excel",
"PDF to Greyscale": "PDF in scala di grigi",
"PDF to JPG": "PDF in JPG",
"PDF to JSON": "PDF in JSON",
"PDF to Markdown": "PDF in Markdown",
"PDF to PDF/A": "PDF in PDF/A",
"PDF to PNG": "PDF in PNG",
"PDF to SVG": "PDF in SVG",
"PDF to Text": "PDF in Testo",
"PDF to TIFF": "PDF in TIFF",
"PDF to WebP": "PDF in WebP",
"PDF to Word": "PDF in Word",
"PDF Workflow Builder": "Costruttore di workflow PDF",
"PDFs to ZIP": "PDF in ZIP",
"PNG to PDF": "PNG in PDF",
"Posterize PDF": "Posterizza PDF",
"PowerPoint to PDF": "PowerPoint in PDF",
"Prepare PDF for AI": "Prepara PDF per IA",
"Previous page": "Pagina precedente",
"Protect PDF": "Proteggi PDF",
"PSD to PDF": "PSD in PDF",
"PUB to PDF": "PUB in PDF",
"Rasterize PDF": "Rasterizza PDF",
"Remove Annotations": "Rimuovi annotazioni",
"Remove Blank Pages": "Rimuovi pagine vuote",
"Remove Metadata": "Rimuovi metadati",
"Remove Restrictions": "Rimuovi restrizioni",
"Repair PDF": "Ripara PDF",
"Reset search": "Reimposta la ricerca",
"Return to top": "Torna su",
"Reverse Pages": "Inverti pagine",
"Rotate by Custom Degrees": "Ruota di gradi personalizzati",
"Rotate PDF": "Ruota PDF",
"RTF to PDF": "RTF in PDF",
"Sanitize PDF": "Sanitizza PDF",
"Scanner Effect": "Effetto scanner",
"Search": "Cerca",
"Secure PDF": "Proteggi PDF",
"Self-Hosting": "Self-hosting",
"Self-Hosting Guide": "Guida al self-hosting",
"Sign PDF": "Firma PDF",
"Skip to content": "Vai al contenuto",
"Split PDF": "Dividi PDF",
"SVG to PDF": "SVG in PDF",
"Switch to dark theme": "Passa al tema scuro",
"Switch to light theme": "Passa al tema chiaro",
"Table of Contents": "Indice",
"Text to PDF": "Testo in PDF",
"TIFF to PDF": "TIFF in PDF",
"to close": "per chiudere",
"to navigate": "per navigare",
"to select": "per selezionare",
"Tools": "Strumenti",
"Tools Reference": "Riferimento degli strumenti",
"Unlock PDF": "Sblocca PDF",
"Validate Signature": "Convalida firma",
"Vercel": "Vercel",
"View Metadata": "Visualizza metadati",
"VSD to PDF": "VSD in PDF",
"WebP to PDF": "WebP in PDF",
"Word to PDF": "Word in PDF",
"WPD to PDF": "WPD in PDF",
"WPS to PDF": "WPS in PDF",
"XML to PDF": "XML in PDF",
"XPS to PDF": "XPS in PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "添付ファイルの追加",
"Add Blank Page": "空白ページの追加",
"Add Page Labels": "ページラベルの追加",
"Add Stamps": "スタンプの追加",
"Add Watermark": "透かしの追加",
"Adjust Colors": "色の調整",
"Alternate & Mix Pages": "ページの交互結合と混合",
"Apache": "Apache",
"Appearance": "外観",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "背景色",
"Bates Numbering": "通し番号付け",
"BMP to PDF": "BMPからPDF",
"CBZ to PDF": "CBZからPDF",
"Change language": "言語を変更",
"Change Permissions": "権限の変更",
"Change Text Color": "テキストの色の変更",
"Close search": "検索を閉じる",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "単一ページに結合",
"Commercial License": "商用ライセンス",
"Compare PDFs": "PDFの比較",
"Compress PDF": "PDFの圧縮",
"Contributing": "コントリビュート",
"Convert from PDF": "PDFから変換",
"Convert to PDF": "PDFに変換",
"Create PDF Form": "PDFフォームの作成",
"Crop PDF": "PDFのトリミング",
"CSV to PDF": "CSVからPDF",
"Delete Pages": "ページの削除",
"Deskew PDF": "PDFの傾き補正",
"Digital Signature": "PDFへの電子署名",
"Display detailed list": "詳細リストを表示",
"Divide Pages": "ページの分割",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "BentoPDFのドキュメント: 無料でオープンソース、プライバシーを第一に考えたPDFツールキット",
"Dual-licensed under AGPL-3.0 and Commercial License.": "AGPL-3.0と商用ライセンスのデュアルライセンスです。",
"Duplex Collate": "両面スキャンの並べ替え",
"Edit & Annotate": "編集と注釈",
"Edit Attachments": "添付ファイルの編集",
"Edit Bookmarks": "しおりの編集",
"Edit Metadata": "メタデータの編集",
"Email to PDF": "電子メールからPDF",
"EPUB to PDF": "EPUBからPDF",
"Excel to PDF": "ExcelからPDF",
"Extract Attachments": "添付ファイルの抽出",
"Extract Images": "画像の抽出",
"Extract Pages": "ページの抽出",
"Extract Tables": "PDFテーブルの抽出",
"FB2 to PDF": "FB2からPDF",
"Fix Page Size": "ページサイズを固定",
"Flatten PDF": "PDFの平坦化",
"Font to Outline": "フォントをアウトライン化",
"Getting Started": "はじめに",
"Guide": "ガイド",
"Header & Footer": "ヘッダーとフッター",
"HEIC to PDF": "HEICからPDF",
"Home": "ホーム",
"Hostinger": "Hostinger",
"Images to PDF": "画像からPDF",
"Invert Colors": "色の反転",
"JPG to PDF": "JPGからPDF",
"JSON to PDF": "JSONからPDF",
"Linearize PDF": "PDFの線形化",
"Markdown to PDF": "マークダウンからPDF",
"Menu": "メニュー",
"Merge PDF": "PDFの結合",
"MOBI to PDF": "MOBIからPDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "次のページ",
"Nginx": "Nginx",
"No results for": "次の検索結果はありません:",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODGからPDF",
"ODP to PDF": "ODPからPDF",
"ODS to PDF": "ODSからPDF",
"ODT to PDF": "ODTからPDF",
"On this page": "このページの内容",
"Optimize & Repair": "最適化と修復",
"Organize & Duplicate": "複製と整理",
"Organize & Manage": "整理と管理",
"Overview": "概要",
"Page Dimensions": "ページ寸法",
"Page Numbers": "ページ番号",
"PDF Booklet": "PDFブックレット",
"PDF Editor": "PDFエディター",
"PDF Form Filler": "PDFフォーム入力機能",
"PDF Multi Tool": "PDFマルチツール",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDFからBMP",
"PDF to CBZ": "PDFからCBZ",
"PDF to CSV": "PDFからCSV",
"PDF to Excel": "PDFからExcel",
"PDF to Greyscale": "PDFのグレースケール化",
"PDF to JPG": "PDFからJPG",
"PDF to JSON": "PDFからJSON",
"PDF to Markdown": "PDFからマークダウン",
"PDF to PDF/A": "PDFからPDF/A",
"PDF to PNG": "PDFからPNG",
"PDF to SVG": "PDFからSVG",
"PDF to Text": "PDFからテキスト",
"PDF to TIFF": "PDFからTIFF",
"PDF to WebP": "PDFからWebP",
"PDF to Word": "PDFからWord",
"PDF Workflow Builder": "PDFワークフロービルダー",
"PDFs to ZIP": "PDFからZIP",
"PNG to PDF": "PNGからPDF",
"Posterize PDF": "PDFのポスタライズ",
"PowerPoint to PDF": "PowerPointからPDF",
"Prepare PDF for AI": "AI用のPDFを準備する",
"Previous page": "前のページ",
"Protect PDF": "PDFの保護",
"PSD to PDF": "PSDからPDF",
"PUB to PDF": "PUBからPDF",
"Rasterize PDF": "PDFの画像化",
"Remove Annotations": "注釈の削除",
"Remove Blank Pages": "空白ページの削除",
"Remove Metadata": "メタデータの削除",
"Remove Restrictions": "制限の解除",
"Repair PDF": "PDFの修復",
"Reset search": "検索をリセット",
"Return to top": "トップに戻る",
"Reverse Pages": "ページの反転",
"Rotate by Custom Degrees": "任意の角度で回転",
"Rotate PDF": "PDFの回転",
"RTF to PDF": "RTFからPDF",
"Sanitize PDF": "PDFをサニタイズ",
"Scanner Effect": "スキャナー効果",
"Search": "検索",
"Secure PDF": "PDFのセキュリティ",
"Self-Hosting": "セルフホスティング",
"Self-Hosting Guide": "セルフホスティングガイド",
"Sign PDF": "PDFへ署名",
"Skip to content": "コンテンツへスキップ",
"Split PDF": "PDFの分割",
"SVG to PDF": "SVGからPDF",
"Switch to dark theme": "ダークテーマに切り替え",
"Switch to light theme": "ライトテーマに切り替え",
"Table of Contents": "目次",
"Text to PDF": "テキストからPDF",
"TIFF to PDF": "TIFFからPDF",
"to close": "閉じる",
"to navigate": "移動",
"to select": "選択",
"Tools": "ツール",
"Tools Reference": "ツールリファレンス",
"Unlock PDF": "PDFのロック解除",
"Validate Signature": "PDF署名を検証する",
"Vercel": "Vercel",
"View Metadata": "メタデータの表示",
"VSD to PDF": "VSDからPDF",
"WebP to PDF": "WebPからPDF",
"Word to PDF": "WordからPDF",
"WPD to PDF": "WPDからPDF",
"WPS to PDF": "WPSからPDF",
"XML to PDF": "XMLからPDF",
"XPS to PDF": "XPSからPDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "첨부파일 추가",
"Add Blank Page": "빈 페이지 추가",
"Add Page Labels": "페이지 레이블 추가",
"Add Stamps": "도장 추가",
"Add Watermark": "워터마크 추가",
"Adjust Colors": "색상 조정",
"Alternate & Mix Pages": "페이지 교차 병합",
"Apache": "Apache",
"Appearance": "모양",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "배경색 변경",
"Bates Numbering": "베이츠 번호 매기기",
"BMP to PDF": "BMP를 PDF로",
"CBZ to PDF": "CBZ를 PDF로",
"Change language": "언어 변경",
"Change Permissions": "권한 변경",
"Change Text Color": "텍스트 색상 변경",
"Close search": "검색 닫기",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "한 페이지로 합치기",
"Commercial License": "상용 라이선스",
"Compare PDFs": "PDF 비교",
"Compress PDF": "PDF 압축",
"Contributing": "기여하기",
"Convert from PDF": "PDF에서 변환",
"Convert to PDF": "PDF로 변환",
"Create PDF Form": "PDF 양식 만들기",
"Crop PDF": "PDF 자르기",
"CSV to PDF": "CSV를 PDF로",
"Delete Pages": "페이지 삭제",
"Deskew PDF": "PDF 기울기 보정",
"Digital Signature": "PDF 디지털 서명",
"Display detailed list": "자세한 목록 표시",
"Divide Pages": "페이지 분할",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "BentoPDF 문서 - 무료 오픈소스, 개인정보 보호 중심 PDF 도구 모음",
"Dual-licensed under AGPL-3.0 and Commercial License.": "AGPL-3.0과 상용 라이선스의 이중 라이선스로 제공됩니다.",
"Duplex Collate": "양면 스캔 정렬",
"Edit & Annotate": "편집 및 주석",
"Edit Attachments": "첨부파일 편집",
"Edit Bookmarks": "북마크 편집",
"Edit Metadata": "메타데이터 편집",
"Email to PDF": "이메일을 PDF로",
"EPUB to PDF": "EPUB를 PDF로",
"Excel to PDF": "Excel을 PDF로",
"Extract Attachments": "첨부파일 추출",
"Extract Images": "이미지 추출",
"Extract Pages": "페이지 추출",
"Extract Tables": "PDF 표 추출",
"FB2 to PDF": "FB2를 PDF로",
"Fix Page Size": "페이지 크기 통일",
"Flatten PDF": "PDF 평탄화",
"Font to Outline": "폰트 윤곽선 변환",
"Getting Started": "시작하기",
"Guide": "가이드",
"Header & Footer": "머리글 및 바닥글",
"HEIC to PDF": "HEIC를 PDF로",
"Home": "홈",
"Hostinger": "Hostinger",
"Images to PDF": "이미지를 PDF로",
"Invert Colors": "색상 반전",
"JPG to PDF": "JPG를 PDF로",
"JSON to PDF": "JSON을 PDF로",
"Linearize PDF": "PDF 선형화",
"Markdown to PDF": "Markdown을 PDF로",
"Menu": "메뉴",
"Merge PDF": "PDF 병합",
"MOBI to PDF": "MOBI를 PDF로",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "다음 페이지",
"Nginx": "Nginx",
"No results for": "검색 결과 없음:",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG를 PDF로",
"ODP to PDF": "ODP를 PDF로",
"ODS to PDF": "ODS를 PDF로",
"ODT to PDF": "ODT를 PDF로",
"On this page": "이 페이지의 내용",
"Optimize & Repair": "최적화 및 복구",
"Organize & Duplicate": "복제 및 정리",
"Organize & Manage": "정리 및 관리",
"Overview": "개요",
"Page Dimensions": "페이지 크기 정보",
"Page Numbers": "페이지 번호",
"PDF Booklet": "PDF 소책자",
"PDF Editor": "PDF 편집기",
"PDF Form Filler": "PDF 양식 작성",
"PDF Multi Tool": "PDF 멀티 도구",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF를 BMP로",
"PDF to CBZ": "PDF를 CBZ로",
"PDF to CSV": "PDF를 CSV로",
"PDF to Excel": "PDF를 Excel로",
"PDF to Greyscale": "PDF 흑백 변환",
"PDF to JPG": "PDF를 JPG로",
"PDF to JSON": "PDF를 JSON으로",
"PDF to Markdown": "PDF를 Markdown으로",
"PDF to PDF/A": "PDF를 PDF/A로",
"PDF to PNG": "PDF를 PNG로",
"PDF to SVG": "PDF를 SVG로",
"PDF to Text": "PDF를 텍스트로",
"PDF to TIFF": "PDF를 TIFF로",
"PDF to WebP": "PDF를 WebP로",
"PDF to Word": "PDF를 Word로",
"PDF Workflow Builder": "PDF 워크플로우 빌더",
"PDFs to ZIP": "PDF를 ZIP으로",
"PNG to PDF": "PNG를 PDF로",
"Posterize PDF": "PDF 포스터화",
"PowerPoint to PDF": "PowerPoint를 PDF로",
"Prepare PDF for AI": "AI용 PDF 준비",
"Previous page": "이전 페이지",
"Protect PDF": "PDF 보호",
"PSD to PDF": "PSD를 PDF로",
"PUB to PDF": "PUB를 PDF로",
"Rasterize PDF": "PDF 래스터화",
"Remove Annotations": "주석 제거",
"Remove Blank Pages": "빈 페이지 제거",
"Remove Metadata": "메타데이터 제거",
"Remove Restrictions": "제한 해제",
"Repair PDF": "PDF 복구",
"Reset search": "검색 초기화",
"Return to top": "맨 위로",
"Reverse Pages": "페이지 역순 정렬",
"Rotate by Custom Degrees": "사용자 지정 각도 회전",
"Rotate PDF": "PDF 회전",
"RTF to PDF": "RTF를 PDF로",
"Sanitize PDF": "PDF 정리",
"Scanner Effect": "스캔 효과",
"Search": "검색",
"Secure PDF": "PDF 보안",
"Self-Hosting": "자체 호스팅",
"Self-Hosting Guide": "자체 호스팅 가이드",
"Sign PDF": "PDF 서명",
"Skip to content": "본문으로 건너뛰기",
"Split PDF": "PDF 분할",
"SVG to PDF": "SVG를 PDF로",
"Switch to dark theme": "다크 테마로 전환",
"Switch to light theme": "라이트 테마로 전환",
"Table of Contents": "목차 생성",
"Text to PDF": "텍스트를 PDF로",
"TIFF to PDF": "TIFF를 PDF로",
"to close": "닫기",
"to navigate": "이동",
"to select": "선택",
"Tools": "도구",
"Tools Reference": "도구 참조",
"Unlock PDF": "PDF 잠금 해제",
"Validate Signature": "PDF 서명 검증",
"Vercel": "Vercel",
"View Metadata": "메타데이터 보기",
"VSD to PDF": "VSD를 PDF로",
"WebP to PDF": "WebP를 PDF로",
"Word to PDF": "Word를 PDF로",
"WPD to PDF": "WPD를 PDF로",
"WPS to PDF": "WPS를 PDF로",
"XML to PDF": "XML을 PDF로",
"XPS to PDF": "XPS를 PDF로"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Bijlagen toevoegen",
"Add Blank Page": "Blanco pagina toevoegen",
"Add Page Labels": "Paginalabels toevoegen",
"Add Stamps": "Stempels toevoegen",
"Add Watermark": "Watermerk toevoegen",
"Adjust Colors": "Kleuren aanpassen",
"Alternate & Mix Pages": "Pagina's afwisselen en mixen",
"Apache": "Apache",
"Appearance": "Weergave",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Achtergrondkleur",
"Bates Numbering": "Bates-nummering",
"BMP to PDF": "BMP naar PDF",
"CBZ to PDF": "CBZ naar PDF",
"Change language": "Taal wijzigen",
"Change Permissions": "Rechten aanpassen",
"Change Text Color": "Tekstkleur",
"Close search": "Zoeken sluiten",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combineren tot één pagina",
"Commercial License": "Commerciële licentie",
"Compare PDFs": "PDF's vergelijken",
"Compress PDF": "PDF comprimeren",
"Contributing": "Bijdragen",
"Convert from PDF": "Converteren van PDF",
"Convert to PDF": "Converteren naar PDF",
"Create PDF Form": "PDF-formulier aanmaken",
"Crop PDF": "PDF bijsnijden",
"CSV to PDF": "CSV naar PDF",
"Delete Pages": "Pagina's verwijderen",
"Deskew PDF": "PDF rechttrekken",
"Digital Signature": "Digitale handtekening",
"Display detailed list": "Gedetailleerde lijst tonen",
"Divide Pages": "Pagina's opdelen",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentatie voor BentoPDF - De gratis, open-source PDF-toolkit met privacy voorop",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Dubbel gelicentieerd onder AGPL-3.0 en een commerciële licentie.",
"Duplex Collate": "Dubbelzijdige scan sorteren",
"Edit & Annotate": "Bewerken & Annoteren",
"Edit Attachments": "Bijlagen bewerken",
"Edit Bookmarks": "Bladwijzers bewerken",
"Edit Metadata": "Metadata bewerken",
"Email to PDF": "E-mail naar PDF",
"EPUB to PDF": "EPUB naar PDF",
"Excel to PDF": "Excel naar PDF",
"Extract Attachments": "Bijlagen extraheren",
"Extract Images": "Afbeeldingen extraheren",
"Extract Pages": "Pagina's extraheren",
"Extract Tables": "PDF-tabellen Extraheren",
"FB2 to PDF": "FB2 naar PDF",
"Fix Page Size": "Paginagrootte corrigeren",
"Flatten PDF": "PDF platmaken",
"Font to Outline": "Lettertype naar contouren",
"Getting Started": "Aan de slag",
"Guide": "Gids",
"Header & Footer": "Koptekst en voettekst",
"HEIC to PDF": "HEIC naar PDF",
"Home": "Startpagina",
"Hostinger": "Hostinger",
"Images to PDF": "Afbeelding naar PDF",
"Invert Colors": "Kleuren omkeren",
"JPG to PDF": "JPG naar PDF",
"JSON to PDF": "JSON naar PDF",
"Linearize PDF": "PDF lineariseren",
"Markdown to PDF": "Markdown naar PDF",
"Menu": "Menu",
"Merge PDF": "PDF samenvoegen",
"MOBI to PDF": "MOBI naar PDF",
"N-Up PDF": "N-up PDF",
"Netlify": "Netlify",
"Next page": "Volgende pagina",
"Nginx": "Nginx",
"No results for": "Geen resultaten voor",
"OCR PDF": "PDF OCR",
"ODG to PDF": "ODG naar PDF",
"ODP to PDF": "ODP naar PDF",
"ODS to PDF": "ODS naar PDF",
"ODT to PDF": "ODT naar PDF",
"On this page": "Op deze pagina",
"Optimize & Repair": "Optimaliseren & Repareren",
"Organize & Duplicate": "Dupliceren & Organiseren",
"Organize & Manage": "Organiseren & Beheren",
"Overview": "Overzicht",
"Page Dimensions": "Paginaafmetingen",
"Page Numbers": "Paginanummers",
"PDF Booklet": "PDF-boekje",
"PDF Editor": "PDF bewerken",
"PDF Form Filler": "PDF-formulier invullen",
"PDF Multi Tool": "PDF-multitool",
"PDF OCG": "PDF-lagen (OCG)",
"PDF to BMP": "PDF naar BMP",
"PDF to CBZ": "PDF naar CBZ",
"PDF to CSV": "PDF naar CSV",
"PDF to Excel": "PDF naar Excel",
"PDF to Greyscale": "PDF naar grijswaarden",
"PDF to JPG": "PDF naar JPG",
"PDF to JSON": "PDF naar JSON",
"PDF to Markdown": "PDF naar Markdown",
"PDF to PDF/A": "PDF naar PDF/A",
"PDF to PNG": "PDF naar PNG",
"PDF to SVG": "PDF naar SVG",
"PDF to Text": "PDF naar tekst",
"PDF to TIFF": "PDF naar TIFF",
"PDF to WebP": "PDF naar WebP",
"PDF to Word": "PDF naar Word",
"PDF Workflow Builder": "PDF-workflowbouwer",
"PDFs to ZIP": "PDF's naar ZIP",
"PNG to PDF": "PNG naar PDF",
"Posterize PDF": "PDF-poster",
"PowerPoint to PDF": "PowerPoint naar PDF",
"Prepare PDF for AI": "PDF voorbereiden voor AI",
"Previous page": "Vorige pagina",
"Protect PDF": "PDF beveiligen",
"PSD to PDF": "PSD naar PDF",
"PUB to PDF": "PUB naar PDF",
"Rasterize PDF": "PDF rasteren",
"Remove Annotations": "Annotaties verwijderen",
"Remove Blank Pages": "Blanco pagina's verwijderen",
"Remove Metadata": "Metadata verwijderen",
"Remove Restrictions": "Beperkingen verwijderen",
"Repair PDF": "PDF repareren",
"Reset search": "Zoekopdracht wissen",
"Return to top": "Terug naar boven",
"Reverse Pages": "Paginavolgorde omkeren",
"Rotate by Custom Degrees": "Roteren met aangepaste hoek",
"Rotate PDF": "PDF roteren",
"RTF to PDF": "RTF naar PDF",
"Sanitize PDF": "PDF opschonen",
"Scanner Effect": "Scannereffect",
"Search": "Zoeken",
"Secure PDF": "PDF Beveiligen",
"Self-Hosting": "Zelf hosten",
"Self-Hosting Guide": "Gids voor zelf hosten",
"Sign PDF": "PDF ondertekenen",
"Skip to content": "Naar inhoud springen",
"Split PDF": "PDF splitsen",
"SVG to PDF": "SVG naar PDF",
"Switch to dark theme": "Overschakelen naar donker thema",
"Switch to light theme": "Overschakelen naar licht thema",
"Table of Contents": "Inhoudsopgave",
"Text to PDF": "Tekst naar PDF",
"TIFF to PDF": "TIFF naar PDF",
"to close": "om te sluiten",
"to navigate": "om te navigeren",
"to select": "om te selecteren",
"Tools": "Tools",
"Tools Reference": "Toolsoverzicht",
"Unlock PDF": "PDF ontgrendelen",
"Validate Signature": "PDF-handtekening Valideren",
"Vercel": "Vercel",
"View Metadata": "Metadata weergeven",
"VSD to PDF": "VSD naar PDF",
"WebP to PDF": "WebP naar PDF",
"Word to PDF": "Word naar PDF",
"WPD to PDF": "WPD naar PDF",
"WPS to PDF": "WPS naar PDF",
"XML to PDF": "XML naar PDF",
"XPS to PDF": "XPS naar PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Dodaj załączniki",
"Add Blank Page": "Dodaj pustą stronę",
"Add Page Labels": "Dodaj etykiety stron",
"Add Stamps": "Dodaj pieczątki",
"Add Watermark": "Dodaj znak wodny",
"Adjust Colors": "Dostosuj kolory",
"Alternate & Mix Pages": "Naprzemienne i mieszane strony",
"Apache": "Apache",
"Appearance": "Wygląd",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Kolor tła",
"Bates Numbering": "Numeracja Batesa",
"BMP to PDF": "BMP na PDF",
"CBZ to PDF": "CBZ na PDF",
"Change language": "Zmień język",
"Change Permissions": "Zmień uprawnienia",
"Change Text Color": "Zmień kolor tekstu",
"Close search": "Zamknij wyszukiwanie",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Połącz w jedną stronę",
"Commercial License": "Licencja komercyjna",
"Compare PDFs": "Porównaj PDF",
"Compress PDF": "Kompresuj PDF",
"Contributing": "Współtworzenie",
"Convert from PDF": "Konwertuj z PDF",
"Convert to PDF": "Konwertuj do PDF",
"Create PDF Form": "Utwórz formularz PDF",
"Crop PDF": "Przytnij PDF",
"CSV to PDF": "CSV na PDF",
"Delete Pages": "Usuń strony",
"Deskew PDF": "Wyprostuj PDF",
"Digital Signature": "Podpis cyfrowy",
"Display detailed list": "Wyświetl szczegółową listę",
"Divide Pages": "Podziel strony",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentacja BentoPDF: darmowy zestaw narzędzi PDF o otwartym kodzie źródłowym, stworzony z myślą o prywatności",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Podwójna licencja: AGPL-3.0 i licencja komercyjna.",
"Duplex Collate": "Sortowanie skanu dwustronnego",
"Edit & Annotate": "Edycja i adnotacje",
"Edit Attachments": "Edytuj załączniki",
"Edit Bookmarks": "Edytuj zakładki",
"Edit Metadata": "Edytuj metadane",
"Email to PDF": "E-mail na PDF",
"EPUB to PDF": "EPUB na PDF",
"Excel to PDF": "Excel na PDF",
"Extract Attachments": "Wyodrębnij załączniki",
"Extract Images": "Wyodrębnij obrazy",
"Extract Pages": "Wyodrębnij strony",
"Extract Tables": "Wyodrębnij tabele",
"FB2 to PDF": "FB2 na PDF",
"Fix Page Size": "Napraw rozmiar strony",
"Flatten PDF": "Spłaszcz PDF",
"Font to Outline": "Czcionka na krzywe",
"Getting Started": "Pierwsze kroki",
"Guide": "Przewodnik",
"Header & Footer": "Nagłówek i stopka",
"HEIC to PDF": "HEIC na PDF",
"Home": "Strona główna",
"Hostinger": "Hostinger",
"Images to PDF": "Obrazy do PDF",
"Invert Colors": "Odwróć kolory",
"JPG to PDF": "JPG na PDF",
"JSON to PDF": "JSON na PDF",
"Linearize PDF": "Linearyzuj PDF",
"Markdown to PDF": "Markdown na PDF",
"Menu": "Menu",
"Merge PDF": "Połącz PDF",
"MOBI to PDF": "MOBI na PDF",
"N-Up PDF": "PDF N-Up",
"Netlify": "Netlify",
"Next page": "Następna strona",
"Nginx": "Nginx",
"No results for": "Brak wyników dla",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG na PDF",
"ODP to PDF": "ODP na PDF",
"ODS to PDF": "ODS na PDF",
"ODT to PDF": "ODT na PDF",
"On this page": "Na tej stronie",
"Optimize & Repair": "Optymalizacja i naprawa",
"Organize & Duplicate": "Organizacja i duplikowanie",
"Organize & Manage": "Organizacja i zarządzanie",
"Overview": "Przegląd",
"Page Dimensions": "Wymiary strony",
"Page Numbers": "Numery stron",
"PDF Booklet": "Broszura PDF",
"PDF Editor": "Edytor PDF",
"PDF Form Filler": "Wypełnianie formularzy PDF",
"PDF Multi Tool": "Wielofunkcyjne narzędzie PDF",
"PDF OCG": "Warstwy PDF (OCG)",
"PDF to BMP": "PDF na BMP",
"PDF to CBZ": "PDF na CBZ",
"PDF to CSV": "PDF na CSV",
"PDF to Excel": "PDF na Excel",
"PDF to Greyscale": "PDF na odcienie szarości",
"PDF to JPG": "PDF na JPG",
"PDF to JSON": "PDF na JSON",
"PDF to Markdown": "PDF na Markdown",
"PDF to PDF/A": "PDF na PDF/A",
"PDF to PNG": "PDF na PNG",
"PDF to SVG": "PDF na SVG",
"PDF to Text": "PDF na tekst",
"PDF to TIFF": "PDF na TIFF",
"PDF to WebP": "PDF na WebP",
"PDF to Word": "PDF na Word",
"PDF Workflow Builder": "Kreator przepływów PDF",
"PDFs to ZIP": "PDF na ZIP",
"PNG to PDF": "PNG na PDF",
"Posterize PDF": "Plakatowanie PDF",
"PowerPoint to PDF": "PowerPoint na PDF",
"Prepare PDF for AI": "Przygotuj PDF dla AI",
"Previous page": "Poprzednia strona",
"Protect PDF": "Zabezpiecz PDF",
"PSD to PDF": "PSD na PDF",
"PUB to PDF": "PUB na PDF",
"Rasterize PDF": "Rasteryzuj PDF",
"Remove Annotations": "Usuń adnotacje",
"Remove Blank Pages": "Usuń puste strony",
"Remove Metadata": "Usuń metadane",
"Remove Restrictions": "Usuń restrykcje",
"Repair PDF": "Napraw PDF",
"Reset search": "Wyczyść wyszukiwanie",
"Return to top": "Wróć na górę",
"Reverse Pages": "Odwróć strony",
"Rotate by Custom Degrees": "Obróć o niestandardowy kąt",
"Rotate PDF": "Obróć PDF",
"RTF to PDF": "RTF na PDF",
"Sanitize PDF": "Sanityzuj PDF",
"Scanner Effect": "Efekt skanera",
"Search": "Szukaj",
"Secure PDF": "Zabezpiecz PDF",
"Self-Hosting": "Własny hosting",
"Self-Hosting Guide": "Przewodnik po własnym hostingu",
"Sign PDF": "Podpisz PDF",
"Skip to content": "Przejdź do treści",
"Split PDF": "Podziel PDF",
"SVG to PDF": "SVG na PDF",
"Switch to dark theme": "Przełącz na ciemny motyw",
"Switch to light theme": "Przełącz na jasny motyw",
"Table of Contents": "Spis treści",
"Text to PDF": "Tekst na PDF",
"TIFF to PDF": "TIFF na PDF",
"to close": "aby zamknąć",
"to navigate": "aby nawigować",
"to select": "aby wybrać",
"Tools": "Narzędzia",
"Tools Reference": "Opis narzędzi",
"Unlock PDF": "Odblokuj PDF",
"Validate Signature": "Zweryfikuj podpis",
"Vercel": "Vercel",
"View Metadata": "Wyświetl metadane",
"VSD to PDF": "VSD na PDF",
"WebP to PDF": "WebP na PDF",
"Word to PDF": "Word na PDF",
"WPD to PDF": "WPD na PDF",
"WPS to PDF": "WPS na PDF",
"XML to PDF": "XML na PDF",
"XPS to PDF": "XPS na PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Adicionar anexos",
"Add Blank Page": "Adicionar página em branco",
"Add Page Labels": "Adicionar rótulos de página",
"Add Stamps": "Adicionar carimbos",
"Add Watermark": "Adicionar marca d'água",
"Adjust Colors": "Ajustar cores",
"Alternate & Mix Pages": "Alternar e misturar páginas",
"Apache": "Apache",
"Appearance": "Aparência",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Cor de fundo",
"Bates Numbering": "Numeração Bates",
"BMP to PDF": "BMP para PDF",
"CBZ to PDF": "CBZ para PDF",
"Change language": "Mudar idioma",
"Change Permissions": "Alterar permissões",
"Change Text Color": "Alterar cor do texto",
"Close search": "Fechar busca",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Combinar em página única",
"Commercial License": "Licença comercial",
"Compare PDFs": "Comparar PDFs",
"Compress PDF": "Comprimir PDF",
"Contributing": "Contribuir",
"Convert from PDF": "Converter de PDF",
"Convert to PDF": "Converter para PDF",
"Create PDF Form": "Criar formulário PDF",
"Crop PDF": "Cortar PDF",
"CSV to PDF": "CSV para PDF",
"Delete Pages": "Excluir páginas",
"Deskew PDF": "Desinclinar PDF",
"Digital Signature": "Assinatura Digital",
"Display detailed list": "Exibir lista detalhada",
"Divide Pages": "Dividir páginas",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Documentação do BentoPDF: o kit de ferramentas PDF gratuito, de código aberto e focado em privacidade",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Licenciado em dupla licença: AGPL-3.0 e Licença Comercial.",
"Duplex Collate": "Intercalar digitalização frente e verso",
"Edit & Annotate": "Editar e Anotar",
"Edit Attachments": "Editar anexos",
"Edit Bookmarks": "Editar marcadores",
"Edit Metadata": "Editar metadados",
"Email to PDF": "E-mail para PDF",
"EPUB to PDF": "EPUB para PDF",
"Excel to PDF": "Excel para PDF",
"Extract Attachments": "Extrair anexos",
"Extract Images": "Extrair imagens",
"Extract Pages": "Extrair páginas",
"Extract Tables": "Extrair Tabelas",
"FB2 to PDF": "FB2 para PDF",
"Fix Page Size": "Ajustar tamanho da página",
"Flatten PDF": "Achatar PDF",
"Font to Outline": "Fonte para contorno",
"Getting Started": "Primeiros Passos",
"Guide": "Guia",
"Header & Footer": "Cabeçalho e rodapé",
"HEIC to PDF": "HEIC para PDF",
"Home": "Início",
"Hostinger": "Hostinger",
"Images to PDF": "Imagens para PDF",
"Invert Colors": "Inverter cores",
"JPG to PDF": "JPG para PDF",
"JSON to PDF": "JSON para PDF",
"Linearize PDF": "Linearizar PDF",
"Markdown to PDF": "Markdown para PDF",
"Menu": "Menu",
"Merge PDF": "Mesclar PDF",
"MOBI to PDF": "MOBI para PDF",
"N-Up PDF": "PDF N-Up",
"Netlify": "Netlify",
"Next page": "Próxima página",
"Nginx": "Nginx",
"No results for": "Nenhum resultado para",
"OCR PDF": "OCR em PDF",
"ODG to PDF": "ODG para PDF",
"ODP to PDF": "ODP para PDF",
"ODS to PDF": "ODS para PDF",
"ODT to PDF": "ODT para PDF",
"On this page": "Nesta página",
"Optimize & Repair": "Otimizar e Reparar",
"Organize & Duplicate": "Duplicar e Organizar",
"Organize & Manage": "Organizar e Gerenciar",
"Overview": "Visão geral",
"Page Dimensions": "Dimensões da página",
"Page Numbers": "Números de página",
"PDF Booklet": "Livreto PDF",
"PDF Editor": "Editor de PDF",
"PDF Form Filler": "Preenchimento de formulário PDF",
"PDF Multi Tool": "Multiferramenta PDF",
"PDF OCG": "Camadas de PDF (OCG)",
"PDF to BMP": "PDF para BMP",
"PDF to CBZ": "PDF para CBZ",
"PDF to CSV": "PDF para CSV",
"PDF to Excel": "PDF para Excel",
"PDF to Greyscale": "PDF para tons de cinza",
"PDF to JPG": "PDF para JPG",
"PDF to JSON": "PDF para JSON",
"PDF to Markdown": "PDF para Markdown",
"PDF to PDF/A": "PDF para PDF/A",
"PDF to PNG": "PDF para PNG",
"PDF to SVG": "PDF para SVG",
"PDF to Text": "PDF para texto",
"PDF to TIFF": "PDF para TIFF",
"PDF to WebP": "PDF para WebP",
"PDF to Word": "PDF para Word",
"PDF Workflow Builder": "Construtor de fluxo de trabalho PDF",
"PDFs to ZIP": "PDFs para ZIP",
"PNG to PDF": "PNG para PDF",
"Posterize PDF": "Posterizar PDF",
"PowerPoint to PDF": "PowerPoint para PDF",
"Prepare PDF for AI": "Preparar PDF para IA",
"Previous page": "Página anterior",
"Protect PDF": "Proteger PDF",
"PSD to PDF": "PSD para PDF",
"PUB to PDF": "PUB para PDF",
"Rasterize PDF": "Rasterizar PDF",
"Remove Annotations": "Remover anotações",
"Remove Blank Pages": "Remover páginas em branco",
"Remove Metadata": "Remover metadados",
"Remove Restrictions": "Remover restrições",
"Repair PDF": "Reparar PDF",
"Reset search": "Limpar busca",
"Return to top": "Voltar ao topo",
"Reverse Pages": "Inverter ordem das páginas",
"Rotate by Custom Degrees": "Girar em graus personalizados",
"Rotate PDF": "Girar PDF",
"RTF to PDF": "RTF para PDF",
"Sanitize PDF": "Sanitizar PDF",
"Scanner Effect": "Efeito scanner",
"Search": "Buscar",
"Secure PDF": "Proteger PDF",
"Self-Hosting": "Hospedagem Própria",
"Self-Hosting Guide": "Guia de Hospedagem Própria",
"Sign PDF": "Assinar PDF",
"Skip to content": "Pular para o conteúdo",
"Split PDF": "Dividir PDF",
"SVG to PDF": "SVG para PDF",
"Switch to dark theme": "Mudar para o tema escuro",
"Switch to light theme": "Mudar para o tema claro",
"Table of Contents": "Sumário",
"Text to PDF": "Texto para PDF",
"TIFF to PDF": "TIFF para PDF",
"to close": "para fechar",
"to navigate": "para navegar",
"to select": "para selecionar",
"Tools": "Ferramentas",
"Tools Reference": "Referência de Ferramentas",
"Unlock PDF": "Desbloquear PDF",
"Validate Signature": "Validar Assinatura",
"Vercel": "Vercel",
"View Metadata": "Ver metadados",
"VSD to PDF": "VSD para PDF",
"WebP to PDF": "WebP para PDF",
"Word to PDF": "Word para PDF",
"WPD to PDF": "WPD para PDF",
"WPS to PDF": "WPS para PDF",
"XML to PDF": "XML para PDF",
"XPS to PDF": "XPS para PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Добавление вложений",
"Add Blank Page": "Добавление пустой страницы",
"Add Page Labels": "Добавить метки страниц",
"Add Stamps": "Добавление штампов",
"Add Watermark": "Добавление водяных знаков",
"Adjust Colors": "Настройка цвета",
"Alternate & Mix Pages": "Объединение документов с чередованием страниц",
"Apache": "Apache",
"Appearance": "Оформление",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Цвет фона",
"Bates Numbering": "Bates-нумерация",
"BMP to PDF": "BMP в PDF",
"CBZ to PDF": "CBZ в PDF",
"Change language": "Сменить язык",
"Change Permissions": "Изменение разрешений",
"Change Text Color": "Изменение цвета текста",
"Close search": "Закрыть поиск",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Объединение в одну страницу",
"Commercial License": "Коммерческая лицензия",
"Compare PDFs": "Сравнение документов",
"Compress PDF": "Сжатие PDF",
"Contributing": "Участие в разработке",
"Convert from PDF": "Конвертация из PDF",
"Convert to PDF": "Конвертация в PDF",
"Create PDF Form": "Создание PDF-форм",
"Crop PDF": "Обрезка PDF",
"CSV to PDF": "CSV в PDF",
"Delete Pages": "Удаление страниц",
"Deskew PDF": "Выпрямление PDF",
"Digital Signature": "Цифровая подпись PDF",
"Display detailed list": "Показать подробный список",
"Divide Pages": "Разделение страниц",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Документация BentoPDF: бесплатный набор PDF-инструментов с открытым исходным кодом и приоритетом приватности",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Двойное лицензирование: AGPL-3.0 и коммерческая лицензия.",
"Duplex Collate": "Сортировка двустороннего сканирования",
"Edit & Annotate": "Редактирование и добавление примечаний",
"Edit Attachments": "Редактирование вложений",
"Edit Bookmarks": "Редактирование закладок",
"Edit Metadata": "Редактирование метаданных",
"Email to PDF": "Email в PDF",
"EPUB to PDF": "EPUB в PDF",
"Excel to PDF": "Excel в PDF",
"Extract Attachments": "Извлечение вложений",
"Extract Images": "Извлечение изображений",
"Extract Pages": "Извлечение страниц",
"Extract Tables": "Извлечение таблиц из PDF",
"FB2 to PDF": "FB2 в PDF",
"Fix Page Size": "Редактор размера страниц",
"Flatten PDF": "Сведение документа",
"Font to Outline": "Шрифты в кривые",
"Getting Started": "Начало работы",
"Guide": "Руководство",
"Header & Footer": "Колонтитулы",
"HEIC to PDF": "HEIC в PDF",
"Home": "Главная",
"Hostinger": "Hostinger",
"Images to PDF": "Изображения в PDF",
"Invert Colors": "Инверсия цвета",
"JPG to PDF": "JPG в PDF",
"JSON to PDF": "JSON в PDF",
"Linearize PDF": "Линеаризация документа",
"Markdown to PDF": "Markdown в PDF",
"Menu": "Меню",
"Merge PDF": "Объединение PDF",
"MOBI to PDF": "MOBI в PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Следующая страница",
"Nginx": "Nginx",
"No results for": "Нет результатов для",
"OCR PDF": "Распознавание текста в PDF",
"ODG to PDF": "ODG в PDF",
"ODP to PDF": "ODP в PDF",
"ODS to PDF": "ODS в PDF",
"ODT to PDF": "ODT в PDF",
"On this page": "На этой странице",
"Optimize & Repair": "Оптимизация и восстановление",
"Organize & Duplicate": "Дублирование и организация",
"Organize & Manage": "Организация и управление",
"Overview": "Обзор",
"Page Dimensions": "Размеры страниц",
"Page Numbers": "Нумерация страниц",
"PDF Booklet": "PDF-буклет",
"PDF Editor": "Редактор PDF",
"PDF Form Filler": "Заполнение PDF-форм",
"PDF Multi Tool": "PDF мультиинструмент",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF в BMP",
"PDF to CBZ": "PDF в CBZ",
"PDF to CSV": "PDF в CSV",
"PDF to Excel": "PDF в Excel",
"PDF to Greyscale": "PDF в оттенки серого",
"PDF to JPG": "PDF в JPG",
"PDF to JSON": "PDF в JSON",
"PDF to Markdown": "PDF в Markdown",
"PDF to PDF/A": "PDF в PDF/A",
"PDF to PNG": "PDF в PNG",
"PDF to SVG": "PDF в SVG",
"PDF to Text": "PDF в текст",
"PDF to TIFF": "PDF в TIFF",
"PDF to WebP": "PDF в WebP",
"PDF to Word": "PDF в Word",
"PDF Workflow Builder": "Конструктор PDF-процессов",
"PDFs to ZIP": "PDF в ZIP",
"PNG to PDF": "PNG в PDF",
"Posterize PDF": "Постеризация документа",
"PowerPoint to PDF": "PowerPoint в PDF",
"Prepare PDF for AI": "Подготовка PDF для ИИ",
"Previous page": "Предыдущая страница",
"Protect PDF": "Защита PDF",
"PSD to PDF": "PSD в PDF",
"PUB to PDF": "PUB в PDF",
"Rasterize PDF": "Растеризация документа",
"Remove Annotations": "Удаление аннотаций",
"Remove Blank Pages": "Удаление пустых страниц",
"Remove Metadata": "Удаление метаданных",
"Remove Restrictions": "Снятие ограничений",
"Repair PDF": "Восстановление документа",
"Reset search": "Сбросить поиск",
"Return to top": "Вернуться наверх",
"Reverse Pages": "Обращение порядка страниц",
"Rotate by Custom Degrees": "Поворот на заданное количество градусов",
"Rotate PDF": "Поворот PDF",
"RTF to PDF": "RTF в PDF",
"Sanitize PDF": "Санирование документа",
"Scanner Effect": "Эффект сканера",
"Search": "Поиск",
"Secure PDF": "Защита PDF",
"Self-Hosting": "Самостоятельный хостинг",
"Self-Hosting Guide": "Руководство по самостоятельному хостингу",
"Sign PDF": "Подписание PDF",
"Skip to content": "Перейти к содержимому",
"Split PDF": "Разделение PDF",
"SVG to PDF": "SVG в PDF",
"Switch to dark theme": "Переключить на тёмную тему",
"Switch to light theme": "Переключить на светлую тему",
"Table of Contents": "Оглавление",
"Text to PDF": "Текст в PDF",
"TIFF to PDF": "TIFF в PDF",
"to close": "закрыть",
"to navigate": "навигация",
"to select": "выбрать",
"Tools": "Инструменты",
"Tools Reference": "Справочник по инструментам",
"Unlock PDF": "Разблокировка PDF",
"Validate Signature": "Проверка подписи в PDF",
"Vercel": "Vercel",
"View Metadata": "Просмотр метаданных",
"VSD to PDF": "VSD в PDF",
"WebP to PDF": "WebP в PDF",
"Word to PDF": "Word в PDF",
"WPD to PDF": "WPD в PDF",
"WPS to PDF": "WPS в PDF",
"XML to PDF": "XML в PDF",
"XPS to PDF": "XPS в PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Pridať prílohy",
"Add Blank Page": "Pridať prázdnu stranu",
"Add Page Labels": "Pridať označenia strán",
"Add Stamps": "Pridať pečiatky",
"Add Watermark": "Pridať vodoznak",
"Adjust Colors": "Úprava farieb",
"Alternate & Mix Pages": "Striedavo spojiť a zmiešať strany",
"Apache": "Apache",
"Appearance": "Vzhľad",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Farba pozadia",
"Bates Numbering": "Batesovo číslovanie",
"BMP to PDF": "BMP do PDF",
"CBZ to PDF": "CBZ do PDF",
"Change language": "Zmeniť jazyk",
"Change Permissions": "Zmeniť oprávnenia",
"Change Text Color": "Zmeniť farbu textu",
"Close search": "Zavrieť vyhľadávanie",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Spojiť do jednej strany",
"Commercial License": "Komerčná licencia",
"Compare PDFs": "Porovnať PDF",
"Compress PDF": "Komprimovať PDF",
"Contributing": "Prispievanie",
"Convert from PDF": "Konvertovať z PDF",
"Convert to PDF": "Konvertovať do PDF",
"Create PDF Form": "Vytvoriť PDF formulár",
"Crop PDF": "Orezať PDF",
"CSV to PDF": "CSV do PDF",
"Delete Pages": "Odstrániť strany",
"Deskew PDF": "Zarovnať naklonené PDF",
"Digital Signature": "Digitálny podpis",
"Display detailed list": "Zobraziť podrobný zoznam",
"Divide Pages": "Rozdeliť strany",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentácia k BentoPDF - bezplatná open source sada PDF nástrojov s dôrazom na súkromie",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Duálne licencovaný pod AGPL-3.0 a komerčnou licenciou.",
"Duplex Collate": "Usporiadať obojstranné skenovanie",
"Edit & Annotate": "Úpravy a poznámky",
"Edit Attachments": "Upraviť prílohy",
"Edit Bookmarks": "Upraviť záložky",
"Edit Metadata": "Upraviť metadáta",
"Email to PDF": "E-mail do PDF",
"EPUB to PDF": "EPUB do PDF",
"Excel to PDF": "Excel do PDF",
"Extract Attachments": "Extrahovať prílohy",
"Extract Images": "Extrahovať obrázky",
"Extract Pages": "Extrahovať strany",
"Extract Tables": "Extrahovať tabuľky",
"FB2 to PDF": "FB2 do PDF",
"Fix Page Size": "Zjednotiť veľkosť strán",
"Flatten PDF": "Sploštiť PDF",
"Font to Outline": "Písma do kriviek",
"Getting Started": "Začíname",
"Guide": "Príručka",
"Header & Footer": "Hlavička a pätička",
"HEIC to PDF": "HEIC do PDF",
"Home": "Domov",
"Hostinger": "Hostinger",
"Images to PDF": "Obrázky do PDF",
"Invert Colors": "Invertovať farby",
"JPG to PDF": "JPG do PDF",
"JSON to PDF": "JSON do PDF",
"Linearize PDF": "Linearizovať PDF",
"Markdown to PDF": "Markdown do PDF",
"Menu": "Menu",
"Merge PDF": "Spojiť PDF",
"MOBI to PDF": "MOBI do PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Nasledujúca strana",
"Nginx": "Nginx",
"No results for": "Žiadne výsledky pre",
"OCR PDF": "Rozpoznávanie textu (OCR) PDF",
"ODG to PDF": "ODG do PDF",
"ODP to PDF": "ODP do PDF",
"ODS to PDF": "ODS do PDF",
"ODT to PDF": "ODT do PDF",
"On this page": "Na tejto stránke",
"Optimize & Repair": "Optimalizácia a oprava",
"Organize & Duplicate": "Usporiadanie a duplikovanie",
"Organize & Manage": "Usporiadanie a správa",
"Overview": "Prehľad",
"Page Dimensions": "Rozmery strany",
"Page Numbers": "Čísla strán",
"PDF Booklet": "PDF brožúra",
"PDF Editor": "Editor PDF",
"PDF Form Filler": "Vypĺňanie PDF formulárov",
"PDF Multi Tool": "Multinástroj PDF",
"PDF OCG": "PDF OCG (vrstvy)",
"PDF to BMP": "PDF do BMP",
"PDF to CBZ": "PDF do CBZ",
"PDF to CSV": "PDF do CSV",
"PDF to Excel": "PDF do Excelu",
"PDF to Greyscale": "PDF do odtieňov sivej",
"PDF to JPG": "PDF do JPG",
"PDF to JSON": "PDF do JSON",
"PDF to Markdown": "PDF do Markdownu",
"PDF to PDF/A": "PDF do PDF/A",
"PDF to PNG": "PDF do PNG",
"PDF to SVG": "PDF do SVG",
"PDF to Text": "PDF do textu",
"PDF to TIFF": "PDF do TIFF",
"PDF to WebP": "PDF do WebP",
"PDF to Word": "PDF do Wordu",
"PDF Workflow Builder": "Tvorca pracovných postupov (Workflow) PDF",
"PDFs to ZIP": "PDF do ZIP",
"PNG to PDF": "PNG do PDF",
"Posterize PDF": "Vytvoriť plagát z PDF",
"PowerPoint to PDF": "PowerPoint do PDF",
"Prepare PDF for AI": "Pripraviť PDF pre AI",
"Previous page": "Predchádzajúca strana",
"Protect PDF": "Chrániť PDF heslom",
"PSD to PDF": "PSD do PDF",
"PUB to PDF": "PUB do PDF",
"Rasterize PDF": "Rastrovať PDF",
"Remove Annotations": "Odstrániť anotácie",
"Remove Blank Pages": "Odstrániť prázdne strany",
"Remove Metadata": "Odstrániť metadáta",
"Remove Restrictions": "Odstrániť obmedzenia",
"Repair PDF": "Opraviť PDF",
"Reset search": "Vynulovať vyhľadávanie",
"Return to top": "Späť hore",
"Reverse Pages": "Obrátiť poradie strán",
"Rotate by Custom Degrees": "Otočiť o vlastné stupne",
"Rotate PDF": "Otočiť PDF",
"RTF to PDF": "RTF do PDF",
"Sanitize PDF": "Vyčistiť PDF",
"Scanner Effect": "Efekt skenera",
"Search": "Hľadať",
"Secure PDF": "Zabezpečiť PDF",
"Self-Hosting": "Vlastný hosting",
"Self-Hosting Guide": "Príručka k vlastnému hostingu",
"Sign PDF": "Podpísať PDF",
"Skip to content": "Preskočiť na obsah",
"Split PDF": "Rozdeliť PDF",
"SVG to PDF": "SVG do PDF",
"Switch to dark theme": "Prepnúť na tmavú tému",
"Switch to light theme": "Prepnúť na svetlú tému",
"Table of Contents": "Obsah",
"Text to PDF": "Text do PDF",
"TIFF to PDF": "TIFF do PDF",
"to close": "zavrieť",
"to navigate": "navigovať",
"to select": "vybrať",
"Tools": "Nástroje",
"Tools Reference": "Prehľad nástrojov",
"Unlock PDF": "Odomknúť PDF",
"Validate Signature": "Overiť podpis",
"Vercel": "Vercel",
"View Metadata": "Zobraziť metadáta",
"VSD to PDF": "VSD do PDF",
"WebP to PDF": "WebP do PDF",
"Word to PDF": "Word do PDF",
"WPD to PDF": "WPD do PDF",
"WPS to PDF": "WPS do PDF",
"XML to PDF": "XML do PDF",
"XPS to PDF": "XPS do PDF"
}
+160
View File
@@ -0,0 +1,160 @@
[
"Add Attachments",
"Add Blank Page",
"Add Page Labels",
"Add Stamps",
"Add Watermark",
"Adjust Colors",
"Alternate & Mix Pages",
"Apache",
"Appearance",
"AWS S3 + CloudFront",
"Background Color",
"Bates Numbering",
"BMP to PDF",
"CBZ to PDF",
"Change language",
"Change Permissions",
"Change Text Color",
"Close search",
"Cloudflare Pages",
"Combine to Single Page",
"Commercial License",
"Compare PDFs",
"Compress PDF",
"Contributing",
"Convert from PDF",
"Convert to PDF",
"Create PDF Form",
"Crop PDF",
"CSV to PDF",
"Delete Pages",
"Deskew PDF",
"Digital Signature",
"Display detailed list",
"Divide Pages",
"Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit",
"Dual-licensed under AGPL-3.0 and Commercial License.",
"Duplex Collate",
"Edit & Annotate",
"Edit Attachments",
"Edit Bookmarks",
"Edit Metadata",
"Email to PDF",
"EPUB to PDF",
"Excel to PDF",
"Extract Attachments",
"Extract Images",
"Extract Pages",
"Extract Tables",
"FB2 to PDF",
"Fix Page Size",
"Flatten PDF",
"Font to Outline",
"Getting Started",
"Guide",
"Header & Footer",
"HEIC to PDF",
"Home",
"Hostinger",
"Images to PDF",
"Invert Colors",
"JPG to PDF",
"JSON to PDF",
"Linearize PDF",
"Markdown to PDF",
"Menu",
"Merge PDF",
"MOBI to PDF",
"N-Up PDF",
"Netlify",
"Next page",
"Nginx",
"No results for",
"OCR PDF",
"ODG to PDF",
"ODP to PDF",
"ODS to PDF",
"ODT to PDF",
"On this page",
"Optimize & Repair",
"Organize & Duplicate",
"Organize & Manage",
"Overview",
"Page Dimensions",
"Page Numbers",
"PDF Booklet",
"PDF Editor",
"PDF Form Filler",
"PDF Multi Tool",
"PDF OCG",
"PDF to BMP",
"PDF to CBZ",
"PDF to CSV",
"PDF to Excel",
"PDF to Greyscale",
"PDF to JPG",
"PDF to JSON",
"PDF to Markdown",
"PDF to PDF/A",
"PDF to PNG",
"PDF to SVG",
"PDF to Text",
"PDF to TIFF",
"PDF to WebP",
"PDF to Word",
"PDF Workflow Builder",
"PDFs to ZIP",
"PNG to PDF",
"Posterize PDF",
"PowerPoint to PDF",
"Prepare PDF for AI",
"Previous page",
"Protect PDF",
"PSD to PDF",
"PUB to PDF",
"Rasterize PDF",
"Remove Annotations",
"Remove Blank Pages",
"Remove Metadata",
"Remove Restrictions",
"Repair PDF",
"Reset search",
"Return to top",
"Reverse Pages",
"Rotate by Custom Degrees",
"Rotate PDF",
"RTF to PDF",
"Sanitize PDF",
"Scanner Effect",
"Search",
"Secure PDF",
"Self-Hosting",
"Self-Hosting Guide",
"Sign PDF",
"Skip to content",
"Split PDF",
"SVG to PDF",
"Switch to dark theme",
"Switch to light theme",
"Table of Contents",
"Text to PDF",
"TIFF to PDF",
"to close",
"to navigate",
"to select",
"Tools",
"Tools Reference",
"Unlock PDF",
"Validate Signature",
"Vercel",
"View Metadata",
"VSD to PDF",
"WebP to PDF",
"Word to PDF",
"WPD to PDF",
"WPS to PDF",
"XML to PDF",
"XPS to PDF"
]
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Lägg till bilagor",
"Add Blank Page": "Lägg till tom sida",
"Add Page Labels": "Lägg till sidetiketter",
"Add Stamps": "Lägg till stämplar",
"Add Watermark": "Lägg till vattenstämpel",
"Adjust Colors": "Justera färger",
"Alternate & Mix Pages": "Alternera & blanda sidor",
"Apache": "Apache",
"Appearance": "Utseende",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Bakgrundsfärg",
"Bates Numbering": "Bates-numrering",
"BMP to PDF": "BMP till PDF",
"CBZ to PDF": "CBZ till PDF",
"Change language": "Byt språk",
"Change Permissions": "Ändra behörigheter",
"Change Text Color": "Ändra textfärg",
"Close search": "Stäng sökning",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Kombinera till en sida",
"Commercial License": "Kommersiell licens",
"Compare PDFs": "Jämför PDF:er",
"Compress PDF": "Komprimera PDF",
"Contributing": "Bidra",
"Convert from PDF": "Konvertera från PDF",
"Convert to PDF": "Konvertera till PDF",
"Create PDF Form": "Skapa PDF-formulär",
"Crop PDF": "Beskär PDF",
"CSV to PDF": "CSV till PDF",
"Delete Pages": "Ta bort sidor",
"Deskew PDF": "Räta upp PDF",
"Digital Signature": "Digital signatur",
"Display detailed list": "Visa detaljerad lista",
"Divide Pages": "Dela sidor",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Dokumentation för BentoPDF, den kostnadsfria PDF-verktygslådan med öppen källkod och integritet i fokus",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Dubbellicensierad under AGPL-3.0 och kommersiell licens.",
"Duplex Collate": "Sortera dubbelsidig skanning",
"Edit & Annotate": "Redigera & Kommentera",
"Edit Attachments": "Redigera bilagor",
"Edit Bookmarks": "Redigera bokmärken",
"Edit Metadata": "Redigera metadata",
"Email to PDF": "E-post till PDF",
"EPUB to PDF": "EPUB till PDF",
"Excel to PDF": "Excel till PDF",
"Extract Attachments": "Extrahera bilagor",
"Extract Images": "Extrahera bilder",
"Extract Pages": "Extrahera sidor",
"Extract Tables": "Extrahera tabeller",
"FB2 to PDF": "FB2 till PDF",
"Fix Page Size": "Fixa sidstorlek",
"Flatten PDF": "Platta till PDF",
"Font to Outline": "Typsnitt till kontur",
"Getting Started": "Kom igång",
"Guide": "Guide",
"Header & Footer": "Sidhuvud & sidfot",
"HEIC to PDF": "HEIC till PDF",
"Home": "Hem",
"Hostinger": "Hostinger",
"Images to PDF": "Bilder till PDF",
"Invert Colors": "Invertera färger",
"JPG to PDF": "JPG till PDF",
"JSON to PDF": "JSON till PDF",
"Linearize PDF": "Linjärisera PDF",
"Markdown to PDF": "Markdown till PDF",
"Menu": "Meny",
"Merge PDF": "Sammanfoga PDF",
"MOBI to PDF": "MOBI till PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Nästa sida",
"Nginx": "Nginx",
"No results for": "Inga resultat för",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG till PDF",
"ODP to PDF": "ODP till PDF",
"ODS to PDF": "ODS till PDF",
"ODT to PDF": "ODT till PDF",
"On this page": "På den här sidan",
"Optimize & Repair": "Optimera & Reparera",
"Organize & Duplicate": "Organisera & Duplicera",
"Organize & Manage": "Organisera & Hantera",
"Overview": "Översikt",
"Page Dimensions": "Sidmått",
"Page Numbers": "Sidnummer",
"PDF Booklet": "PDF-broschyr",
"PDF Editor": "PDF-redigerare",
"PDF Form Filler": "PDF-formulärifyllare",
"PDF Multi Tool": "PDF-multiverktyg",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF till BMP",
"PDF to CBZ": "PDF till CBZ",
"PDF to CSV": "PDF till CSV",
"PDF to Excel": "PDF till Excel",
"PDF to Greyscale": "PDF till gråskala",
"PDF to JPG": "PDF till JPG",
"PDF to JSON": "PDF till JSON",
"PDF to Markdown": "PDF till Markdown",
"PDF to PDF/A": "PDF till PDF/A",
"PDF to PNG": "PDF till PNG",
"PDF to SVG": "PDF till SVG",
"PDF to Text": "PDF till text",
"PDF to TIFF": "PDF till TIFF",
"PDF to WebP": "PDF till WebP",
"PDF to Word": "PDF till Word",
"PDF Workflow Builder": "PDF-arbetsflödesbyggare",
"PDFs to ZIP": "PDF:er till ZIP",
"PNG to PDF": "PNG till PDF",
"Posterize PDF": "Postera PDF",
"PowerPoint to PDF": "PowerPoint till PDF",
"Prepare PDF for AI": "Förbered PDF för AI",
"Previous page": "Föregående sida",
"Protect PDF": "Skydda PDF",
"PSD to PDF": "PSD till PDF",
"PUB to PDF": "PUB till PDF",
"Rasterize PDF": "Rasterisera PDF",
"Remove Annotations": "Ta bort anteckningar",
"Remove Blank Pages": "Ta bort tomma sidor",
"Remove Metadata": "Ta bort metadata",
"Remove Restrictions": "Ta bort begränsningar",
"Repair PDF": "Reparera PDF",
"Reset search": "Återställ sökning",
"Return to top": "Tillbaka till toppen",
"Reverse Pages": "Vänd sidordning",
"Rotate by Custom Degrees": "Rotera med valfri vinkel",
"Rotate PDF": "Rotera PDF",
"RTF to PDF": "RTF till PDF",
"Sanitize PDF": "Sanera PDF",
"Scanner Effect": "Skannereffekt",
"Search": "Sök",
"Secure PDF": "Säkra PDF",
"Self-Hosting": "Egen drift",
"Self-Hosting Guide": "Guide för egen drift",
"Sign PDF": "Signera PDF",
"Skip to content": "Hoppa till innehåll",
"Split PDF": "Dela PDF",
"SVG to PDF": "SVG till PDF",
"Switch to dark theme": "Byt till mörkt tema",
"Switch to light theme": "Byt till ljust tema",
"Table of Contents": "Innehållsförteckning",
"Text to PDF": "Text till PDF",
"TIFF to PDF": "TIFF till PDF",
"to close": "för att stänga",
"to navigate": "för att navigera",
"to select": "för att välja",
"Tools": "Verktyg",
"Tools Reference": "Verktygsreferens",
"Unlock PDF": "Lås upp PDF",
"Validate Signature": "Validera signatur",
"Vercel": "Vercel",
"View Metadata": "Visa metadata",
"VSD to PDF": "VSD till PDF",
"WebP to PDF": "WebP till PDF",
"Word to PDF": "Word till PDF",
"WPD to PDF": "WPD till PDF",
"WPS to PDF": "WPS till PDF",
"XML to PDF": "XML till PDF",
"XPS to PDF": "XPS till PDF"
}
+26
View File
@@ -0,0 +1,26 @@
export const DESCRIPTION =
'Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit';
export const FOOTER_MESSAGE =
'Dual-licensed under AGPL-3.0 and Commercial License.';
export const THEME_LABELS = [
'On this page',
'Return to top',
'Menu',
'Appearance',
'Switch to light theme',
'Switch to dark theme',
'Skip to content',
'Change language',
'Previous page',
'Next page',
'Search',
'No results for',
'Reset search',
'Close search',
'Display detailed list',
'to select',
'to navigate',
'to close',
];
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Ek Dosya Ekle",
"Add Blank Page": "Boş Sayfa Ekle",
"Add Page Labels": "Sayfa Etiketleri Ekle",
"Add Stamps": "Damga Ekle",
"Add Watermark": "Filigran Ekle",
"Adjust Colors": "Renkleri Ayarla",
"Alternate & Mix Pages": "Sayfaları Karıştır & Birleştir",
"Apache": "Apache",
"Appearance": "Görünüm",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Arka Plan Rengi",
"Bates Numbering": "Bates Numaralandırma",
"BMP to PDF": "BMP'den PDF'ye",
"CBZ to PDF": "CBZ'den PDF'ye",
"Change language": "Dili değiştir",
"Change Permissions": "İzinleri Değiştir",
"Change Text Color": "Metin Rengini Değiştir",
"Close search": "Aramayı kapat",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Tek Sayfada Birleştir",
"Commercial License": "Ticari Lisans",
"Compare PDFs": "PDF'leri Karşılaştır",
"Compress PDF": "PDF Sıkıştır",
"Contributing": "Katkıda Bulunma",
"Convert from PDF": "PDF'den Dönüştür",
"Convert to PDF": "PDF'ye Dönüştür",
"Create PDF Form": "PDF Formu Oluştur",
"Crop PDF": "PDF Kırp",
"CSV to PDF": "CSV'den PDF'ye",
"Delete Pages": "Sayfaları Sil",
"Deskew PDF": "PDF Eğriliğini Düzelt",
"Digital Signature": "Dijital İmza",
"Display detailed list": "Ayrıntılı listeyi göster",
"Divide Pages": "Sayfaları Böl",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "BentoPDF belgeleri: ücretsiz, açık kaynaklı, gizlilik odaklı PDF araç seti",
"Dual-licensed under AGPL-3.0 and Commercial License.": "AGPL-3.0 ve Ticari Lisans ile çift lisanslıdır.",
"Duplex Collate": "Çift Taraflı Harmanla",
"Edit & Annotate": "Düzenle & Açıklama Ekle",
"Edit Attachments": "Ek Dosyaları Düzenle",
"Edit Bookmarks": "Yer İşaretlerini Düzenle",
"Edit Metadata": "Üst Veriyi Düzenle",
"Email to PDF": "E-postadan PDF'ye",
"EPUB to PDF": "EPUB'dan PDF'ye",
"Excel to PDF": "Excel'den PDF'ye",
"Extract Attachments": "Ek Dosyaları Çıkar",
"Extract Images": "Görüntüleri Çıkar",
"Extract Pages": "Sayfaları Çıkar",
"Extract Tables": "Tabloları Çıkar",
"FB2 to PDF": "FB2'den PDF'ye",
"Fix Page Size": "Sayfa Boyutunu Düzelt",
"Flatten PDF": "PDF'yi Düzleştir",
"Font to Outline": "Yazı Tipini Ana Hatlara Dönüştür",
"Getting Started": "Başlarken",
"Guide": "Kılavuz",
"Header & Footer": "Üst Bilgi & Alt Bilgi",
"HEIC to PDF": "HEIC'den PDF'ye",
"Home": "Ana Sayfa",
"Hostinger": "Hostinger",
"Images to PDF": "Görselden PDF'ye",
"Invert Colors": "Renkleri Ters Çevir",
"JPG to PDF": "JPG'den PDF'ye",
"JSON to PDF": "JSON'dan PDF'ye",
"Linearize PDF": "PDF'yi Doğrusallaştır",
"Markdown to PDF": "Markdown'dan PDF'ye",
"Menu": "Menü",
"Merge PDF": "PDF Birleştir",
"MOBI to PDF": "MOBI'den PDF'ye",
"N-Up PDF": "N'li PDF",
"Netlify": "Netlify",
"Next page": "Sonraki sayfa",
"Nginx": "Nginx",
"No results for": "Sonuç bulunamadı:",
"OCR PDF": "PDF'de OCR",
"ODG to PDF": "ODG'den PDF'ye",
"ODP to PDF": "ODP'den PDF'ye",
"ODS to PDF": "ODS'ten PDF'ye",
"ODT to PDF": "ODT'den PDF'ye",
"On this page": "Bu sayfada",
"Optimize & Repair": "Optimize Et & Onar",
"Organize & Duplicate": "Çoğalt & Düzenle",
"Organize & Manage": "Düzenle & Yönet",
"Overview": "Genel Bakış",
"Page Dimensions": "Sayfa Boyutları",
"Page Numbers": "Sayfa Numaraları",
"PDF Booklet": "PDF Kitapçık",
"PDF Editor": "PDF Düzenleyici",
"PDF Form Filler": "PDF Form Doldurucu",
"PDF Multi Tool": "PDF Çoklu Araç",
"PDF OCG": "PDF Katmanları (OCG)",
"PDF to BMP": "PDF'den BMP'ye",
"PDF to CBZ": "PDF'den CBZ'ye",
"PDF to CSV": "PDF'den CSV'ye",
"PDF to Excel": "PDF'den Excel'e",
"PDF to Greyscale": "PDF'yi Gri Tonlamaya Çevir",
"PDF to JPG": "PDF'den JPG'ye",
"PDF to JSON": "PDF'den JSON'a",
"PDF to Markdown": "PDF'den Markdown'a",
"PDF to PDF/A": "PDF'den PDF/A'ya",
"PDF to PNG": "PDF'den PNG'ye",
"PDF to SVG": "PDF'den SVG'ye",
"PDF to Text": "PDF'den Metne",
"PDF to TIFF": "PDF'den TIFF'e",
"PDF to WebP": "PDF'den WebP'ye",
"PDF to Word": "PDF'den Word'e",
"PDF Workflow Builder": "PDF İş Akışı Oluşturucu",
"PDFs to ZIP": "PDF'leri ZIP Yap",
"PNG to PDF": "PNG'den PDF'ye",
"Posterize PDF": "PDF'yi Posterleştir",
"PowerPoint to PDF": "PowerPoint'ten PDF'ye",
"Prepare PDF for AI": "PDF'yi Yapay Zeka için Hazırla",
"Previous page": "Önceki sayfa",
"Protect PDF": "PDF'yi Şifrele",
"PSD to PDF": "PSD'den PDF'ye",
"PUB to PDF": "PUB'dan PDF'ye",
"Rasterize PDF": "PDF'yi Rasterleştir",
"Remove Annotations": "Açıklamaları Kaldır",
"Remove Blank Pages": "Boş Sayfaları Kaldır",
"Remove Metadata": "Üst Veriyi Kaldır",
"Remove Restrictions": "Kısıtlamaları Kaldır",
"Repair PDF": "PDF'yi Onar",
"Reset search": "Aramayı sıfırla",
"Return to top": "Başa dön",
"Reverse Pages": "Sayfaları Ters Çevir",
"Rotate by Custom Degrees": "Özel Açıyla Döndür",
"Rotate PDF": "PDF'yi Döndür",
"RTF to PDF": "RTF'den PDF'ye",
"Sanitize PDF": "PDF'yi Temizle",
"Scanner Effect": "Tarayıcı Efekti",
"Search": "Ara",
"Secure PDF": "PDF'yi Güvenceye Al",
"Self-Hosting": "Kendi Sunucunda Barındırma",
"Self-Hosting Guide": "Kendi Sunucunda Barındırma Kılavuzu",
"Sign PDF": "PDF İmzala",
"Skip to content": "İçeriğe geç",
"Split PDF": "PDF Böl",
"SVG to PDF": "SVG'den PDF'ye",
"Switch to dark theme": "Koyu temaya geç",
"Switch to light theme": "Açık temaya geç",
"Table of Contents": "İçindekiler",
"Text to PDF": "Metinden PDF'ye",
"TIFF to PDF": "TIFF'den PDF'ye",
"to close": "kapatmak için",
"to navigate": "gezinmek için",
"to select": "seçmek için",
"Tools": "Araçlar",
"Tools Reference": "Araç Başvurusu",
"Unlock PDF": "PDF'nin Şifresini Çöz",
"Validate Signature": "İmzayı Doğrula",
"Vercel": "Vercel",
"View Metadata": "Üst Veriyi Görüntüle",
"VSD to PDF": "VSD'den PDF'ye",
"WebP to PDF": "WebP'den PDF'ye",
"Word to PDF": "Word'den PDF'ye",
"WPD to PDF": "WPD'den PDF'ye",
"WPS to PDF": "WPS'ten PDF'ye",
"XML to PDF": "XML'den PDF'ye",
"XPS to PDF": "XPS'ten PDF'ye"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Додати вкладення",
"Add Blank Page": "Додати порожню сторінку",
"Add Page Labels": "Додати нумерацію сторінок",
"Add Stamps": "Додати штампи",
"Add Watermark": "Додати водяний знак",
"Adjust Colors": "Корекція кольору",
"Alternate & Mix Pages": "Чергування та змішування сторінок",
"Apache": "Apache",
"Appearance": "Вигляд",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Колір фону",
"Bates Numbering": "Нумерація Bates",
"BMP to PDF": "BMP у PDF",
"CBZ to PDF": "CBZ у PDF",
"Change language": "Змінити мову",
"Change Permissions": "Змінити дозволи",
"Change Text Color": "Змінити колір тексту",
"Close search": "Закрити пошук",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Об’єднати в одну сторінку",
"Commercial License": "Комерційна ліцензія",
"Compare PDFs": "Порівняти PDF",
"Compress PDF": "Стиснення PDF",
"Contributing": "Участь у розробці",
"Convert from PDF": "Конвертувати з PDF",
"Convert to PDF": "Конвертувати в PDF",
"Create PDF Form": "Створити PDF-форму",
"Crop PDF": "Обрізати PDF",
"CSV to PDF": "CSV у PDF",
"Delete Pages": "Видалити сторінки",
"Deskew PDF": "Вирівнювання PDF",
"Digital Signature": "Цифровий підпис PDF",
"Display detailed list": "Показати докладний список",
"Divide Pages": "Розділити сторінки",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Документація BentoPDF: безкоштовний PDF-набір з відкритим кодом, створений з урахуванням конфіденційності",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Подвійне ліцензування: AGPL-3.0 і комерційна ліцензія.",
"Duplex Collate": "Сортування двостороннього сканування",
"Edit & Annotate": "Редагування та анотації",
"Edit Attachments": "Редагувати вкладення",
"Edit Bookmarks": "Редагувати закладки",
"Edit Metadata": "Редагувати метадані",
"Email to PDF": "Email у PDF",
"EPUB to PDF": "EPUB у PDF",
"Excel to PDF": "Excel у PDF",
"Extract Attachments": "Витяг вкладень",
"Extract Images": "Витяг зображень",
"Extract Pages": "Витяг сторінок",
"Extract Tables": "Витяг таблиць з PDF",
"FB2 to PDF": "FB2 у PDF",
"Fix Page Size": "Вирівняти розмір сторінок",
"Flatten PDF": "Сплющити PDF",
"Font to Outline": "Шрифти у контури",
"Getting Started": "Початок роботи",
"Guide": "Посібник",
"Header & Footer": "Колонтитули",
"HEIC to PDF": "HEIC у PDF",
"Home": "Головна",
"Hostinger": "Hostinger",
"Images to PDF": "Зображення у PDF",
"Invert Colors": "Інвертувати кольори",
"JPG to PDF": "JPG у PDF",
"JSON to PDF": "JSON у PDF",
"Linearize PDF": "Лінеаризація PDF",
"Markdown to PDF": "Markdown у PDF",
"Menu": "Меню",
"Merge PDF": "Об’єднати PDF",
"MOBI to PDF": "MOBI у PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Наступна сторінка",
"Nginx": "Nginx",
"No results for": "Нічого не знайдено за запитом",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG у PDF",
"ODP to PDF": "ODP у PDF",
"ODS to PDF": "ODS у PDF",
"ODT to PDF": "ODT у PDF",
"On this page": "На цій сторінці",
"Optimize & Repair": "Оптимізація та відновлення",
"Organize & Duplicate": "Дублювати та впорядкувати",
"Organize & Manage": "Упорядкування та керування",
"Overview": "Огляд",
"Page Dimensions": "Розміри сторінок",
"Page Numbers": "Нумерація сторінок",
"PDF Booklet": "PDF-буклет",
"PDF Editor": "Редактор PDF",
"PDF Form Filler": "Заповнення PDF-форм",
"PDF Multi Tool": "PDF мультиінструмент",
"PDF OCG": "PDF OCG",
"PDF to BMP": "PDF у BMP",
"PDF to CBZ": "PDF у CBZ",
"PDF to CSV": "PDF у CSV",
"PDF to Excel": "PDF у Excel",
"PDF to Greyscale": "PDF у відтінки сірого",
"PDF to JPG": "PDF у JPG",
"PDF to JSON": "PDF у JSON",
"PDF to Markdown": "PDF у Markdown",
"PDF to PDF/A": "PDF у PDF/A",
"PDF to PNG": "PDF у PNG",
"PDF to SVG": "PDF у SVG",
"PDF to Text": "PDF у текст",
"PDF to TIFF": "PDF у TIFF",
"PDF to WebP": "PDF у WebP",
"PDF to Word": "PDF у Word",
"PDF Workflow Builder": "Конструктор PDF-процесів",
"PDFs to ZIP": "PDF у ZIP",
"PNG to PDF": "PNG у PDF",
"Posterize PDF": "Постеризація PDF",
"PowerPoint to PDF": "PowerPoint у PDF",
"Prepare PDF for AI": "Підготовка PDF для AI",
"Previous page": "Попередня сторінка",
"Protect PDF": "Захистити PDF",
"PSD to PDF": "PSD у PDF",
"PUB to PDF": "PUB у PDF",
"Rasterize PDF": "Растеризація PDF",
"Remove Annotations": "Видалити анотації",
"Remove Blank Pages": "Видалити порожні сторінки",
"Remove Metadata": "Видалити метадані",
"Remove Restrictions": "Зняти обмеження",
"Repair PDF": "Відновити PDF",
"Reset search": "Скинути пошук",
"Return to top": "Повернутися нагору",
"Reverse Pages": "Зворотний порядок сторінок",
"Rotate by Custom Degrees": "Повернути на довільний кут",
"Rotate PDF": "Повернути PDF",
"RTF to PDF": "RTF у PDF",
"Sanitize PDF": "Очистити PDF",
"Scanner Effect": "Ефект сканера",
"Search": "Пошук",
"Secure PDF": "Захист PDF",
"Self-Hosting": "Самостійний хостинг",
"Self-Hosting Guide": "Посібник із самостійного хостингу",
"Sign PDF": "Підписати PDF",
"Skip to content": "Перейти до вмісту",
"Split PDF": "Розділити PDF",
"SVG to PDF": "SVG у PDF",
"Switch to dark theme": "Перейти на темну тему",
"Switch to light theme": "Перейти на світлу тему",
"Table of Contents": "Зміст",
"Text to PDF": "Текст у PDF",
"TIFF to PDF": "TIFF у PDF",
"to close": "закрити",
"to navigate": "навігація",
"to select": "вибрати",
"Tools": "Інструменти",
"Tools Reference": "Довідник інструментів",
"Unlock PDF": "Розблокувати PDF",
"Validate Signature": "Перевірка підпису PDF",
"Vercel": "Vercel",
"View Metadata": "Перегляд метаданих",
"VSD to PDF": "VSD у PDF",
"WebP to PDF": "WebP у PDF",
"Word to PDF": "Word у PDF",
"WPD to PDF": "WPD у PDF",
"WPS to PDF": "WPS у PDF",
"XML to PDF": "XML у PDF",
"XPS to PDF": "XPS у PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "Thêm tệp đính kèm",
"Add Blank Page": "Thêm trang trống",
"Add Page Labels": "Thêm nhãn trang",
"Add Stamps": "Thêm tem",
"Add Watermark": "Thêm Watermark",
"Adjust Colors": "Điều chỉnh màu sắc",
"Alternate & Mix Pages": "Xen kẽ & Trộn trang",
"Apache": "Apache",
"Appearance": "Giao diện",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "Màu nền",
"Bates Numbering": "Đánh số Bates",
"BMP to PDF": "BMP sang PDF",
"CBZ to PDF": "CBZ sang PDF",
"Change language": "Đổi ngôn ngữ",
"Change Permissions": "Thay đổi quyền",
"Change Text Color": "Thay đổi màu văn bản",
"Close search": "Đóng tìm kiếm",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "Kết hợp thành một trang",
"Commercial License": "Giấy phép thương mại",
"Compare PDFs": "So sánh PDF",
"Compress PDF": "Nén PDF",
"Contributing": "Đóng góp",
"Convert from PDF": "Chuyển đổi từ PDF",
"Convert to PDF": "Chuyển đổi sang PDF",
"Create PDF Form": "Tạo form PDF",
"Crop PDF": "Cắt PDF",
"CSV to PDF": "CSV sang PDF",
"Delete Pages": "Xóa trang",
"Deskew PDF": "Chỉnh nghiêng PDF",
"Digital Signature": "Chữ ký số PDF",
"Display detailed list": "Hiển thị danh sách chi tiết",
"Divide Pages": "Chia trang",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "Tài liệu BentoPDF - Bộ công cụ PDF miễn phí, mã nguồn mở, đặt quyền riêng tư lên hàng đầu",
"Dual-licensed under AGPL-3.0 and Commercial License.": "Cấp phép kép theo AGPL-3.0 và Giấy phép thương mại.",
"Duplex Collate": "Sắp xếp bản quét hai mặt",
"Edit & Annotate": "Chỉnh sửa & Ghi chú",
"Edit Attachments": "Chỉnh sửa tệp đính kèm",
"Edit Bookmarks": "Chỉnh sửa Bookmark",
"Edit Metadata": "Chỉnh sửa Metadata",
"Email to PDF": "Email sang PDF",
"EPUB to PDF": "EPUB sang PDF",
"Excel to PDF": "Excel sang PDF",
"Extract Attachments": "Trích xuất tệp đính kèm",
"Extract Images": "Trích xuất hình ảnh",
"Extract Pages": "Trích xuất trang",
"Extract Tables": "Trích xuất bảng PDF",
"FB2 to PDF": "FB2 sang PDF",
"Fix Page Size": "Sửa kích thước trang",
"Flatten PDF": "Làm phẳng PDF",
"Font to Outline": "Phông chữ thành đường viền",
"Getting Started": "Bắt đầu",
"Guide": "Hướng dẫn",
"Header & Footer": "Đầu trang & Chân trang",
"HEIC to PDF": "HEIC sang PDF",
"Home": "Trang chủ",
"Hostinger": "Hostinger",
"Images to PDF": "Hình ảnh sang PDF",
"Invert Colors": "Đảo ngược màu",
"JPG to PDF": "JPG sang PDF",
"JSON to PDF": "JSON sang PDF",
"Linearize PDF": "Tuyến tính hóa PDF",
"Markdown to PDF": "Markdown sang PDF",
"Menu": "Menu",
"Merge PDF": "Gộp PDF",
"MOBI to PDF": "MOBI sang PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "Trang sau",
"Nginx": "Nginx",
"No results for": "Không có kết quả cho",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG sang PDF",
"ODP to PDF": "ODP sang PDF",
"ODS to PDF": "ODS sang PDF",
"ODT to PDF": "ODT sang PDF",
"On this page": "Trên trang này",
"Optimize & Repair": "Tối ưu hóa & Sửa chữa",
"Organize & Duplicate": "Nhân đôi & Sắp xếp",
"Organize & Manage": "Sắp xếp & Quản lý",
"Overview": "Tổng quan",
"Page Dimensions": "Kích thước trang",
"Page Numbers": "Số trang",
"PDF Booklet": "Sách nhỏ PDF",
"PDF Editor": "Trình chỉnh sửa PDF",
"PDF Form Filler": "Điền form PDF",
"PDF Multi Tool": "Công cụ đa năng PDF",
"PDF OCG": "Lớp PDF (OCG)",
"PDF to BMP": "PDF sang BMP",
"PDF to CBZ": "PDF sang CBZ",
"PDF to CSV": "PDF sang CSV",
"PDF to Excel": "PDF sang Excel",
"PDF to Greyscale": "PDF sang thang xám",
"PDF to JPG": "PDF sang JPG",
"PDF to JSON": "PDF sang JSON",
"PDF to Markdown": "PDF sang Markdown",
"PDF to PDF/A": "PDF sang PDF/A",
"PDF to PNG": "PDF sang PNG",
"PDF to SVG": "PDF sang SVG",
"PDF to Text": "PDF sang văn bản",
"PDF to TIFF": "PDF sang TIFF",
"PDF to WebP": "PDF sang WebP",
"PDF to Word": "PDF sang Word",
"PDF Workflow Builder": "Trình xây dựng quy trình PDF",
"PDFs to ZIP": "PDF sang ZIP",
"PNG to PDF": "PNG sang PDF",
"Posterize PDF": "Chia PDF thành poster",
"PowerPoint to PDF": "PowerPoint sang PDF",
"Prepare PDF for AI": "Chuẩn bị PDF cho AI",
"Previous page": "Trang trước",
"Protect PDF": "Bảo vệ PDF",
"PSD to PDF": "PSD sang PDF",
"PUB to PDF": "PUB sang PDF",
"Rasterize PDF": "Raster hóa PDF",
"Remove Annotations": "Xóa ghi chú",
"Remove Blank Pages": "Xóa trang trống",
"Remove Metadata": "Xóa Metadata",
"Remove Restrictions": "Xóa hạn chế",
"Repair PDF": "Sửa chữa PDF",
"Reset search": "Đặt lại tìm kiếm",
"Return to top": "Về đầu trang",
"Reverse Pages": "Đảo ngược trang",
"Rotate by Custom Degrees": "Xoay theo độ tùy chỉnh",
"Rotate PDF": "Xoay PDF",
"RTF to PDF": "RTF sang PDF",
"Sanitize PDF": "Làm sạch PDF",
"Scanner Effect": "Hiệu ứng máy quét",
"Search": "Tìm kiếm",
"Secure PDF": "Bảo mật PDF",
"Self-Hosting": "Tự lưu trữ",
"Self-Hosting Guide": "Hướng dẫn tự lưu trữ",
"Sign PDF": "Ký PDF",
"Skip to content": "Chuyển đến nội dung",
"Split PDF": "Chia PDF",
"SVG to PDF": "SVG sang PDF",
"Switch to dark theme": "Chuyển sang giao diện tối",
"Switch to light theme": "Chuyển sang giao diện sáng",
"Table of Contents": "Mục lục",
"Text to PDF": "Văn bản sang PDF",
"TIFF to PDF": "TIFF sang PDF",
"to close": "để đóng",
"to navigate": "để di chuyển",
"to select": "để chọn",
"Tools": "Công cụ",
"Tools Reference": "Tham chiếu công cụ",
"Unlock PDF": "Mở khóa PDF",
"Validate Signature": "Xác minh chữ ký PDF",
"Vercel": "Vercel",
"View Metadata": "Xem Metadata",
"VSD to PDF": "VSD sang PDF",
"WebP to PDF": "WebP sang PDF",
"Word to PDF": "Word sang PDF",
"WPD to PDF": "WPD sang PDF",
"WPS to PDF": "WPS sang PDF",
"XML to PDF": "XML sang PDF",
"XPS to PDF": "XPS sang PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "新增附件",
"Add Blank Page": "新增空白頁面",
"Add Page Labels": "新增頁面標籤",
"Add Stamps": "新增印章",
"Add Watermark": "新增浮水印",
"Adjust Colors": "調整顏色",
"Alternate & Mix Pages": "交錯混合頁面",
"Apache": "Apache",
"Appearance": "外觀",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "背景顏色",
"Bates Numbering": "Bates 編號",
"BMP to PDF": "BMP 轉 PDF",
"CBZ to PDF": "CBZ 轉 PDF",
"Change language": "變更語言",
"Change Permissions": "變更權限",
"Change Text Color": "更改文字顏色",
"Close search": "關閉搜尋",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "合併為單一頁面",
"Commercial License": "商業授權",
"Compare PDFs": "比較 PDF",
"Compress PDF": "壓縮 PDF",
"Contributing": "參與貢獻",
"Convert from PDF": "從 PDF 轉換",
"Convert to PDF": "轉換為 PDF",
"Create PDF Form": "建立 PDF 表單",
"Crop PDF": "裁切 PDF",
"CSV to PDF": "CSV 轉 PDF",
"Delete Pages": "刪除頁面",
"Deskew PDF": "PDF 歪斜修正",
"Digital Signature": "數位簽章",
"Display detailed list": "顯示詳細清單",
"Divide Pages": "分割頁面",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "BentoPDF 說明文件:免費、開源、隱私優先的 PDF 工具箱",
"Dual-licensed under AGPL-3.0 and Commercial License.": "以 AGPL-3.0 與商業授權雙重授權。",
"Duplex Collate": "雙面掃描整理",
"Edit & Annotate": "編輯與註解",
"Edit Attachments": "編輯附件",
"Edit Bookmarks": "編輯書籤",
"Edit Metadata": "編輯中繼資料",
"Email to PDF": "電子郵件轉 PDF",
"EPUB to PDF": "EPUB 轉 PDF",
"Excel to PDF": "Excel 轉 PDF",
"Extract Attachments": "擷取附件",
"Extract Images": "擷取圖片",
"Extract Pages": "擷取頁面",
"Extract Tables": "擷取 PDF 表格",
"FB2 to PDF": "FB2 轉 PDF",
"Fix Page Size": "統一頁面尺寸",
"Flatten PDF": "平面化 PDF",
"Font to Outline": "字型轉外框",
"Getting Started": "開始使用",
"Guide": "指南",
"Header & Footer": "頁首與頁尾",
"HEIC to PDF": "HEIC 轉 PDF",
"Home": "首頁",
"Hostinger": "Hostinger",
"Images to PDF": "圖片轉 PDF",
"Invert Colors": "反轉顏色",
"JPG to PDF": "JPG 轉 PDF",
"JSON to PDF": "JSON 轉 PDF",
"Linearize PDF": "線性化 PDF",
"Markdown to PDF": "Markdown 轉 PDF",
"Menu": "選單",
"Merge PDF": "合併 PDF",
"MOBI to PDF": "MOBI 轉 PDF",
"N-Up PDF": "多頁併一頁 (N-Up)",
"Netlify": "Netlify",
"Next page": "下一頁",
"Nginx": "Nginx",
"No results for": "找不到相關結果:",
"OCR PDF": "PDF 文字辨識 (OCR)",
"ODG to PDF": "ODG 轉 PDF",
"ODP to PDF": "ODP 轉 PDF",
"ODS to PDF": "ODS 轉 PDF",
"ODT to PDF": "ODT 轉 PDF",
"On this page": "本頁內容",
"Optimize & Repair": "最佳化與修復",
"Organize & Duplicate": "整理與複製",
"Organize & Manage": "整理與管理",
"Overview": "概覽",
"Page Dimensions": "頁面尺寸",
"Page Numbers": "頁碼",
"PDF Booklet": "PDF 小手冊",
"PDF Editor": "PDF 編輯器",
"PDF Form Filler": "PDF 表單填寫器",
"PDF Multi Tool": "PDF 多功能工具",
"PDF OCG": "PDF 圖層(OCG)",
"PDF to BMP": "PDF 轉 BMP",
"PDF to CBZ": "PDF 轉 CBZ",
"PDF to CSV": "PDF 轉 CSV",
"PDF to Excel": "PDF 轉 Excel",
"PDF to Greyscale": "PDF 轉灰階",
"PDF to JPG": "PDF 轉 JPG",
"PDF to JSON": "PDF 轉 JSON",
"PDF to Markdown": "PDF 轉 Markdown",
"PDF to PDF/A": "PDF 轉 PDF/A",
"PDF to PNG": "PDF 轉 PNG",
"PDF to SVG": "PDF 轉 SVG",
"PDF to Text": "PDF 轉文字",
"PDF to TIFF": "PDF 轉 TIFF",
"PDF to WebP": "PDF 轉 WebP",
"PDF to Word": "PDF 轉 Word",
"PDF Workflow Builder": "PDF 工作流程建構器",
"PDFs to ZIP": "PDF 轉 ZIP",
"PNG to PDF": "PNG 轉 PDF",
"Posterize PDF": "海報化 PDF",
"PowerPoint to PDF": "PowerPoint 轉 PDF",
"Prepare PDF for AI": "為 AI 準備 PDF",
"Previous page": "上一頁",
"Protect PDF": "保護 PDF",
"PSD to PDF": "PSD 轉 PDF",
"PUB to PDF": "PUB 轉 PDF",
"Rasterize PDF": "光柵化 PDF",
"Remove Annotations": "移除註解",
"Remove Blank Pages": "移除空白頁面",
"Remove Metadata": "移除中繼資料",
"Remove Restrictions": "移除限制",
"Repair PDF": "修復 PDF",
"Reset search": "重設搜尋",
"Return to top": "回到頂端",
"Reverse Pages": "反轉頁面",
"Rotate by Custom Degrees": "自訂角度旋轉",
"Rotate PDF": "旋轉 PDF",
"RTF to PDF": "RTF 轉 PDF",
"Sanitize PDF": "清理 PDF",
"Scanner Effect": "掃描效果",
"Search": "搜尋",
"Secure PDF": "保護 PDF",
"Self-Hosting": "自行架設",
"Self-Hosting Guide": "自行架設指南",
"Sign PDF": "簽署 PDF",
"Skip to content": "跳至內容",
"Split PDF": "分割 PDF",
"SVG to PDF": "SVG 轉 PDF",
"Switch to dark theme": "切換為深色主題",
"Switch to light theme": "切換為淺色主題",
"Table of Contents": "目錄",
"Text to PDF": "文字轉 PDF",
"TIFF to PDF": "TIFF 轉 PDF",
"to close": "關閉",
"to navigate": "切換選項",
"to select": "選取",
"Tools": "工具",
"Tools Reference": "工具參考",
"Unlock PDF": "解除鎖定 PDF",
"Validate Signature": "驗證 PDF 數位簽章",
"Vercel": "Vercel",
"View Metadata": "檢視中繼資料",
"VSD to PDF": "VSD 轉 PDF",
"WebP to PDF": "WebP 轉 PDF",
"Word to PDF": "Word 轉 PDF",
"WPD to PDF": "WPD 轉 PDF",
"WPS to PDF": "WPS 轉 PDF",
"XML to PDF": "XML 轉 PDF",
"XPS to PDF": "XPS 轉 PDF"
}
+160
View File
@@ -0,0 +1,160 @@
{
"Add Attachments": "添加附件",
"Add Blank Page": "添加空白页",
"Add Page Labels": "添加页面标签",
"Add Stamps": "添加印章",
"Add Watermark": "添加水印",
"Adjust Colors": "调整颜色",
"Alternate & Mix Pages": "交替混合页面",
"Apache": "Apache",
"Appearance": "外观",
"AWS S3 + CloudFront": "AWS S3 + CloudFront",
"Background Color": "背景颜色",
"Bates Numbering": "Bates 编号",
"BMP to PDF": "BMP 转 PDF",
"CBZ to PDF": "CBZ 转 PDF",
"Change language": "切换语言",
"Change Permissions": "更改权限",
"Change Text Color": "更改文本颜色",
"Close search": "关闭搜索",
"Cloudflare Pages": "Cloudflare Pages",
"Combine to Single Page": "合并为单页",
"Commercial License": "商业许可",
"Compare PDFs": "比较 PDF",
"Compress PDF": "压缩 PDF",
"Contributing": "参与贡献",
"Convert from PDF": "从 PDF 转换",
"Convert to PDF": "转换为 PDF",
"Create PDF Form": "创建 PDF 表单",
"Crop PDF": "裁剪 PDF",
"CSV to PDF": "CSV 转 PDF",
"Delete Pages": "删除页面",
"Deskew PDF": "校正 PDF",
"Digital Signature": "数字签名",
"Display detailed list": "显示详细列表",
"Divide Pages": "分割页面",
"Docker": "Docker",
"Documentation for BentoPDF - The free, open-source, privacy-first PDF toolkit": "BentoPDF 文档:免费、开源、隐私优先的 PDF 工具箱",
"Dual-licensed under AGPL-3.0 and Commercial License.": "采用 AGPL-3.0 与商业许可双重授权。",
"Duplex Collate": "双面扫描整理",
"Edit & Annotate": "编辑与注释",
"Edit Attachments": "编辑附件",
"Edit Bookmarks": "编辑书签",
"Edit Metadata": "编辑元数据",
"Email to PDF": "邮件转 PDF",
"EPUB to PDF": "EPUB 转 PDF",
"Excel to PDF": "Excel 转 PDF",
"Extract Attachments": "提取附件",
"Extract Images": "提取图片",
"Extract Pages": "提取页面",
"Extract Tables": "提取 PDF 表格",
"FB2 to PDF": "FB2 转 PDF",
"Fix Page Size": "修复页面尺寸",
"Flatten PDF": "扁平化 PDF",
"Font to Outline": "字体转轮廓",
"Getting Started": "快速入门",
"Guide": "指南",
"Header & Footer": "页眉和页脚",
"HEIC to PDF": "HEIC 转 PDF",
"Home": "首页",
"Hostinger": "Hostinger",
"Images to PDF": "图片转 PDF",
"Invert Colors": "反转颜色",
"JPG to PDF": "JPG 转 PDF",
"JSON to PDF": "JSON 转 PDF",
"Linearize PDF": "线性化 PDF",
"Markdown to PDF": "Markdown 转 PDF",
"Menu": "菜单",
"Merge PDF": "合并 PDF",
"MOBI to PDF": "MOBI 转 PDF",
"N-Up PDF": "N-Up PDF",
"Netlify": "Netlify",
"Next page": "下一页",
"Nginx": "Nginx",
"No results for": "没有找到相关结果:",
"OCR PDF": "OCR PDF",
"ODG to PDF": "ODG 转 PDF",
"ODP to PDF": "ODP 转 PDF",
"ODS to PDF": "ODS 转 PDF",
"ODT to PDF": "ODT 转 PDF",
"On this page": "本页内容",
"Optimize & Repair": "优化与修复",
"Organize & Duplicate": "复制与组织",
"Organize & Manage": "组织与管理",
"Overview": "概览",
"Page Dimensions": "页面尺寸",
"Page Numbers": "页码",
"PDF Booklet": "PDF 小册子",
"PDF Editor": "PDF 编辑器",
"PDF Form Filler": "PDF 表单填写器",
"PDF Multi Tool": "PDF 多功能工具",
"PDF OCG": "PDF 图层 (OCG)",
"PDF to BMP": "PDF 转 BMP",
"PDF to CBZ": "PDF 转 CBZ",
"PDF to CSV": "PDF 转 CSV",
"PDF to Excel": "PDF 转 Excel",
"PDF to Greyscale": "PDF 转灰度",
"PDF to JPG": "PDF 转 JPG",
"PDF to JSON": "PDF 转 JSON",
"PDF to Markdown": "PDF 转 Markdown",
"PDF to PDF/A": "PDF 转 PDF/A",
"PDF to PNG": "PDF 转 PNG",
"PDF to SVG": "PDF 转 SVG",
"PDF to Text": "PDF 转文本",
"PDF to TIFF": "PDF 转 TIFF",
"PDF to WebP": "PDF 转 WebP",
"PDF to Word": "PDF 转 Word",
"PDF Workflow Builder": "PDF 工作流构建器",
"PDFs to ZIP": "PDF 转 ZIP",
"PNG to PDF": "PNG 转 PDF",
"Posterize PDF": "海报化 PDF",
"PowerPoint to PDF": "PowerPoint 转 PDF",
"Prepare PDF for AI": "为 AI 准备 PDF",
"Previous page": "上一页",
"Protect PDF": "保护 PDF",
"PSD to PDF": "PSD 转 PDF",
"PUB to PDF": "PUB 转 PDF",
"Rasterize PDF": "栅格化 PDF",
"Remove Annotations": "移除注释",
"Remove Blank Pages": "移除空白页",
"Remove Metadata": "移除元数据",
"Remove Restrictions": "移除限制",
"Repair PDF": "修复 PDF",
"Reset search": "重置搜索",
"Return to top": "返回顶部",
"Reverse Pages": "反转页面",
"Rotate by Custom Degrees": "按自定义角度旋转",
"Rotate PDF": "旋转 PDF",
"RTF to PDF": "RTF 转 PDF",
"Sanitize PDF": "清理 PDF",
"Scanner Effect": "扫描效果",
"Search": "搜索",
"Secure PDF": "安全 PDF",
"Self-Hosting": "自托管",
"Self-Hosting Guide": "自托管指南",
"Sign PDF": "签署 PDF",
"Skip to content": "跳到正文",
"Split PDF": "分割 PDF",
"SVG to PDF": "SVG 转 PDF",
"Switch to dark theme": "切换到深色主题",
"Switch to light theme": "切换到浅色主题",
"Table of Contents": "目录",
"Text to PDF": "文本转 PDF",
"TIFF to PDF": "TIFF 转 PDF",
"to close": "关闭",
"to navigate": "导航",
"to select": "选择",
"Tools": "工具",
"Tools Reference": "工具参考",
"Unlock PDF": "解锁 PDF",
"Validate Signature": "验证签名",
"Vercel": "Vercel",
"View Metadata": "查看元数据",
"VSD to PDF": "VSD 转 PDF",
"WebP to PDF": "WebP 转 PDF",
"Word to PDF": "Word 转 PDF",
"WPD to PDF": "WPD 转 PDF",
"WPS to PDF": "WPS 转 PDF",
"XML to PDF": "XML 转 PDF",
"XPS to PDF": "XPS 转 PDF"
}
+195
View File
@@ -0,0 +1,195 @@
export const nav = [
{ text: 'Home', link: '/' },
{ text: 'Getting Started', link: '/getting-started' },
{ text: 'Tools', link: '/tools/' },
{ text: 'Self-Hosting', link: '/self-hosting/' },
{ text: 'Contributing', link: '/contributing' },
{ text: 'Commercial License', link: '/licensing' },
];
export const sidebar = {
'/tools/': [
{
text: 'Tools Reference',
items: [{ text: 'Overview', link: '/tools/' }],
},
{
text: 'Edit & Annotate',
collapsed: false,
items: [
{ text: 'PDF Editor', link: '/tools/edit-pdf' },
{ text: 'Edit Bookmarks', link: '/tools/bookmark' },
{ text: 'Table of Contents', link: '/tools/table-of-contents' },
{ text: 'Page Numbers', link: '/tools/page-numbers' },
{ text: 'Add Page Labels', link: '/tools/add-page-labels' },
{ text: 'Bates Numbering', link: '/tools/bates-numbering' },
{ text: 'Add Watermark', link: '/tools/add-watermark' },
{ text: 'Header & Footer', link: '/tools/header-footer' },
{ text: 'Invert Colors', link: '/tools/invert-colors' },
{ text: 'Scanner Effect', link: '/tools/scanner-effect' },
{ text: 'Adjust Colors', link: '/tools/adjust-colors' },
{ text: 'Background Color', link: '/tools/background-color' },
{ text: 'Change Text Color', link: '/tools/text-color' },
{ text: 'Sign PDF', link: '/tools/sign-pdf' },
{ text: 'Add Stamps', link: '/tools/add-stamps' },
{ text: 'Remove Annotations', link: '/tools/remove-annotations' },
{ text: 'Crop PDF', link: '/tools/crop-pdf' },
{ text: 'PDF Form Filler', link: '/tools/form-filler' },
{ text: 'Create PDF Form', link: '/tools/form-creator' },
{ text: 'Remove Blank Pages', link: '/tools/remove-blank-pages' },
],
},
{
text: 'Convert to PDF',
collapsed: true,
items: [
{ text: 'Images to PDF', link: '/tools/image-to-pdf' },
{ text: 'JPG to PDF', link: '/tools/jpg-to-pdf' },
{ text: 'PNG to PDF', link: '/tools/png-to-pdf' },
{ text: 'WebP to PDF', link: '/tools/webp-to-pdf' },
{ text: 'SVG to PDF', link: '/tools/svg-to-pdf' },
{ text: 'BMP to PDF', link: '/tools/bmp-to-pdf' },
{ text: 'HEIC to PDF', link: '/tools/heic-to-pdf' },
{ text: 'TIFF to PDF', link: '/tools/tiff-to-pdf' },
{ text: 'Text to PDF', link: '/tools/txt-to-pdf' },
{ text: 'Markdown to PDF', link: '/tools/markdown-to-pdf' },
{ text: 'JSON to PDF', link: '/tools/json-to-pdf' },
{ text: 'ODT to PDF', link: '/tools/odt-to-pdf' },
{ text: 'CSV to PDF', link: '/tools/csv-to-pdf' },
{ text: 'RTF to PDF', link: '/tools/rtf-to-pdf' },
{ text: 'Word to PDF', link: '/tools/word-to-pdf' },
{ text: 'Excel to PDF', link: '/tools/excel-to-pdf' },
{ text: 'PowerPoint to PDF', link: '/tools/powerpoint-to-pdf' },
{ text: 'XPS to PDF', link: '/tools/xps-to-pdf' },
{ text: 'MOBI to PDF', link: '/tools/mobi-to-pdf' },
{ text: 'EPUB to PDF', link: '/tools/epub-to-pdf' },
{ text: 'FB2 to PDF', link: '/tools/fb2-to-pdf' },
{ text: 'CBZ to PDF', link: '/tools/cbz-to-pdf' },
{ text: 'WPD to PDF', link: '/tools/wpd-to-pdf' },
{ text: 'WPS to PDF', link: '/tools/wps-to-pdf' },
{ text: 'XML to PDF', link: '/tools/xml-to-pdf' },
{ text: 'ODG to PDF', link: '/tools/odg-to-pdf' },
{ text: 'ODS to PDF', link: '/tools/ods-to-pdf' },
{ text: 'ODP to PDF', link: '/tools/odp-to-pdf' },
{ text: 'PUB to PDF', link: '/tools/pub-to-pdf' },
{ text: 'VSD to PDF', link: '/tools/vsd-to-pdf' },
{ text: 'PSD to PDF', link: '/tools/psd-to-pdf' },
{ text: 'Email to PDF', link: '/tools/email-to-pdf' },
],
},
{
text: 'Convert from PDF',
collapsed: true,
items: [
{ text: 'PDF to JPG', link: '/tools/pdf-to-jpg' },
{ text: 'PDF to PNG', link: '/tools/pdf-to-png' },
{ text: 'PDF to WebP', link: '/tools/pdf-to-webp' },
{ text: 'PDF to BMP', link: '/tools/pdf-to-bmp' },
{ text: 'PDF to TIFF', link: '/tools/pdf-to-tiff' },
{ text: 'PDF to CBZ', link: '/tools/pdf-to-cbz' },
{ text: 'PDF to SVG', link: '/tools/pdf-to-svg' },
{ text: 'PDF to CSV', link: '/tools/pdf-to-csv' },
{ 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-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' },
{ text: 'PDF to Text', link: '/tools/pdf-to-text' },
{ text: 'Extract Tables', link: '/tools/extract-tables' },
],
},
{
text: 'Organize & Manage',
collapsed: true,
items: [
{ text: 'PDF Workflow Builder', link: '/tools/pdf-workflow' },
{ text: 'PDF Multi Tool', link: '/tools/pdf-multi-tool' },
{ text: 'OCR PDF', link: '/tools/ocr-pdf' },
{ text: 'Merge PDF', link: '/tools/merge-pdf' },
{ text: 'Alternate & Mix Pages', link: '/tools/alternate-merge' },
{ text: 'Duplex Collate', link: '/tools/duplex-collate' },
{ text: 'Organize & Duplicate', link: '/tools/organize-pdf' },
{ text: 'Add Attachments', link: '/tools/add-attachments' },
{ text: 'Extract Attachments', link: '/tools/extract-attachments' },
{ text: 'Edit Attachments', link: '/tools/edit-attachments' },
{ text: 'PDF OCG', link: '/tools/pdf-layers' },
{ text: 'Split PDF', link: '/tools/split-pdf' },
{ text: 'Divide Pages', link: '/tools/divide-pages' },
{ text: 'Extract Pages', link: '/tools/extract-pages' },
{ text: 'Delete Pages', link: '/tools/delete-pages' },
{ text: 'Add Blank Page', link: '/tools/add-blank-page' },
{ text: 'Reverse Pages', link: '/tools/reverse-pages' },
{ text: 'Rotate PDF', link: '/tools/rotate-pdf' },
{ text: 'Rotate by Custom Degrees', link: '/tools/rotate-custom' },
{ text: 'N-Up PDF', link: '/tools/n-up-pdf' },
{ text: 'PDF Booklet', link: '/tools/pdf-booklet' },
{ text: 'Combine to Single Page', link: '/tools/combine-single-page' },
{ text: 'View Metadata', link: '/tools/view-metadata' },
{ text: 'Edit Metadata', link: '/tools/edit-metadata' },
{ text: 'PDFs to ZIP', link: '/tools/pdf-to-zip' },
{ text: 'Compare PDFs', link: '/tools/compare-pdfs' },
{ text: 'Posterize PDF', link: '/tools/posterize-pdf' },
],
},
{
text: 'Optimize & Repair',
collapsed: true,
items: [
{ text: 'Compress PDF', link: '/tools/compress-pdf' },
{ text: 'PDF to PDF/A', link: '/tools/pdf-to-pdfa' },
{ text: 'Fix Page Size', link: '/tools/fix-page-size' },
{ text: 'Linearize PDF', link: '/tools/linearize-pdf' },
{ text: 'Page Dimensions', link: '/tools/page-dimensions' },
{ text: 'Remove Restrictions', link: '/tools/remove-restrictions' },
{ text: 'Repair PDF', link: '/tools/repair-pdf' },
{ text: 'Rasterize PDF', link: '/tools/rasterize-pdf' },
{ text: 'Deskew PDF', link: '/tools/deskew-pdf' },
{ text: 'Font to Outline', link: '/tools/font-to-outline' },
],
},
{
text: 'Secure PDF',
collapsed: true,
items: [
{ text: 'Protect PDF', link: '/tools/protect-pdf' },
{ text: 'Sanitize PDF', link: '/tools/sanitize-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' },
{ text: 'Digital Signature', link: '/tools/digital-sign-pdf' },
{ text: 'Validate Signature', link: '/tools/validate-signature-pdf' },
],
},
],
'/self-hosting/': [
{
text: 'Self-Hosting Guide',
items: [
{ text: 'Overview', link: '/self-hosting/' },
{ text: 'Docker', link: '/self-hosting/docker' },
{ text: 'Vercel', link: '/self-hosting/vercel' },
{ text: 'Netlify', link: '/self-hosting/netlify' },
{ text: 'Cloudflare Pages', link: '/self-hosting/cloudflare' },
{ text: 'AWS S3 + CloudFront', link: '/self-hosting/aws' },
{ text: 'Hostinger', link: '/self-hosting/hostinger' },
{ text: 'Nginx', link: '/self-hosting/nginx' },
{ text: 'Apache', link: '/self-hosting/apache' },
],
},
],
'/': [
{
text: 'Guide',
items: [
{ text: 'Getting Started', link: '/getting-started' },
{ text: 'Tools Reference', link: '/tools/' },
{ text: 'Self-Hosting', link: '/self-hosting/' },
{ text: 'Contributing', link: '/contributing' },
{ text: 'Commercial License', link: '/licensing' },
],
},
],
};
+136
View File
@@ -0,0 +1,136 @@
# المساهمة
شكرًا لاهتمامك بالمساهمة في BentoPDF! سيساعدك هذا الدليل على البدء.
## البدء
### المتطلبات
- Node.js 18+
- npm 9+
- Git
### الإعداد
```bash
# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/bentopdf.git
cd bentopdf
# Install dependencies
npm install
# Start development server
npm run dev
```
## بنية المشروع
```
bentopdf/
├── src/
│ ├── js/
│ │ ├── config/ # Tool definitions
│ │ ├── logic/ # Tool page logic
│ │ ├── utils/ # Shared utilities
│ │ └── ui.ts # UI helpers
│ ├── pages/ # Tool HTML pages
│ └── css/ # Styles
├── public/
│ ├── locales/ # Translations
│ └── pymupdf-wasm/ # WASM modules
├── docs/ # Documentation (VitePress)
└── scripts/ # Build scripts
```
## إضافة أداة جديدة
### الخطوة 1: إنشاء ملف المنطق
أنشئ `src/js/logic/your-tool-page.ts`:
```typescript
import { showLoader, hideLoader, showAlert } from '../ui.js';
import { state } from '../state.js';
document.addEventListener('DOMContentLoaded', () => {
// Your tool logic here
});
```
### الخطوة 2: إنشاء صفحة HTML
أنشئ `src/pages/your-tool.html` باتباع قوالب الأدوات الموجودة.
### الخطوة 3: تسجيل الأداة
أضف إلى `src/js/config/tools.ts`:
```typescript
{
href: import.meta.env.BASE_URL + 'your-tool.html',
name: 'Your Tool',
icon: 'ph-icon-name',
subtitle: 'Description of your tool.',
}
```
### الخطوة 4: الإضافة إلى إعدادات البناء
أضف الصفحة إلى `vite.config.ts`:
```typescript
'your-tool': resolve(__dirname, 'src/pages/your-tool.html'),
```
### الخطوة 5: إضافة الترجمات
أضف مدخلات إلى جميع ملفات اللغات في `public/locales/`:
```json
{
"yourTool": {
"name": "Your Tool",
"subtitle": "Description"
}
}
```
## نمط الكود
- استخدم TypeScript لكل الكود الجديد
- اتبع الأنماط الموجودة للحفاظ على الاتساق
- شغّل `npm run format` قبل الإيداع
- لا تضف تعليقات في كود الإنتاج (تُزال التعليقات أثناء البناء)
## عملية طلب السحب
1. أنشئ فرعًا للميزة: `git checkout -b feature/your-feature`
2. أجرِ تعديلاتك
3. اختبر جيدًا: `npm run build`
4. أرسل طلب سحب (PR) مع وصف واضح
## الترجمة
راجع [TRANSLATION.md](https://github.com/alam00000/bentopdf/blob/main/TRANSLATION.md) لإضافة لغات جديدة.
## اتفاقية ترخيص المساهم
قبل دمج طلب السحب، ستحتاج إلى توقيع اتفاقية CLA الخاصة بنا:
- [اتفاقية المساهم الفرد (ICLA)](https://github.com/alam00000/bentopdf/blob/main/ICLA.md)
- [اتفاقية المساهم المؤسسي (CCLA)](https://github.com/alam00000/bentopdf/blob/main/CCLA.md)
## الحصول على المساعدة
- [مشكلات GitHub](https://github.com/alam00000/bentopdf/issues)
- [مجتمع Discord](https://discord.gg/Bgq3Ay3f2w)
## الترخيص
BentoPDF مرخّص بترخيص مزدوج:
- **AGPL-3.0** للمشاريع مفتوحة المصدر التي تشارك كامل شيفرتها المصدرية علنًا
- **ترخيص تجاري** للتطبيقات الخاصة/مغلقة المصدر - [احصل على ترخيص مدى الحياة مقابل 79$](https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd)
بمساهمتك، فإنك توافق على ترخيص مساهماتك بموجب هذه الشروط.
+80
View File
@@ -0,0 +1,80 @@
# البدء
مرحبًا بك في BentoPDF! سيساعدك هذا الدليل على الانطلاق بسرعة.
## ما هو BentoPDF؟
BentoPDF مجموعة أدوات PDF مجانية ومفتوحة المصدر تضع الخصوصية أولًا، وتعمل **بالكامل داخل متصفحك**. ملفاتك لا تغادر جهازك أبدًا، فكل المعالجة تتم محليًا باستخدام تقنية WebAssembly (WASM).
## بداية سريعة
### الخيار 1: استخدام النسخة المستضافة
زر [bentopdf.com](https://www.bentopdf.com) لاستخدام BentoPDF فورًا، بدون أي تثبيت.
### الخيار 2: الاستضافة الذاتية باستخدام Docker
> [!IMPORTANT]
> يتطلب تحويل ملفات Office وجود `SharedArrayBuffer`، وهذا يحتاج إلى كل مما يلي:
>
> - `Cross-Origin-Opener-Policy: same-origin`
> - `Cross-Origin-Embedder-Policy: require-corp`
> - سياق آمن
>
> يعمل `http://localhost` للاختبار المحلي لأن المتصفحات تعتبر عنوان الحلقة المحلية موثوقًا. أما `http://192.168.x.x` أو غيره من عناوين الشبكة المحلية فعادةً لا يُعتبر كذلك، لذا تتطلب تحويلات Word/Excel/PowerPoint اتصال HTTPS عند الوصول من أجهزة أخرى على شبكتك.
```bash
# Pull and run the Docker image (self-hosted build)
docker run -d -p 3000:8080 ghcr.io/alam00000/bentopdf-simple:latest
# Or use Docker Compose
curl -O https://raw.githubusercontent.com/alam00000/bentopdf/main/docker-compose.yml
docker compose up -d
```
> [!TIP]
> يتوفر BentoPDF بنسختين: **نسخة الاستضافة الذاتية** (`bentopdf-simple`، المستخدمة أعلاه) لعمليات النشر الداخلية وللفرق والمؤسسات، و**النسخة التجارية** (`bentopdf:latest`) التي يستخدمها bentopdf.com نفسه وأصحاب التراخيص التجارية الذين ينشرون خدمات موجهة للعامة. كلتا النسختين تتضمنان أدوات PDF نفسها، وتضيف النسخة التجارية الواجهة الرئيسية لـ bentopdf.com والأسئلة الشائعة وآراء المستخدمين والتذييل. إذا كنت غير متأكد، فاستخدم نسخة الاستضافة الذاتية.
ثم افتح `http://localhost:3000` في متصفحك.
> [!NOTE]
> إذا كنت تجهّز نشرًا معزولًا عن الإنترنت لميزة OCR، فعليك استضافة خطوط الطبقة النصية الخاصة بـ OCR داخليًا، إضافة إلى عامل Tesseract وبيئة التشغيل الأساسية وملفات traineddata. الإعداد الكامل موثّق في [الاستضافة الذاتية](/ar/self-hosting/)، بما في ذلك `VITE_OCR_FONT_BASE_URL` والمجلد المضمّن `ocr-fonts/`.
### الخيار 3: البناء من المصدر
```bash
# Clone the repository
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
# Install dependencies
npm install
# Start development server
npm run dev
```
## نظرة سريعة على الميزات
| الفئة | الأدوات |
| -------------------- | ----------------------------------------------------------- |
| **التحويل إلى PDF** | Word وExcel وPowerPoint والصور وMarkdown وEPUB وMOBI وغيرها |
| **التحويل من PDF** | JPG وPNG ونص وExcel وSVG وغيرها |
| **التحرير والتعليق** | التوقيع، التمييز، التنقيح، تعبئة النماذج، إضافة الأختام |
| **التنظيم** | دمج، تقسيم، تدوير، حذف الصفحات، إعادة الترتيب |
| **التحسين** | ضغط، إصلاح، تسطيح، OCR |
| **الأمان** | تشفير، فك التشفير، إزالة القيود |
## دعم المتصفحات
يعمل BentoPDF بأفضل شكل على المتصفحات الحديثة:
- ✅ Chrome/Edge 90+
- ✅ Firefox 90+
- ✅ Safari 15+
## الخطوات التالية
- [استكشف جميع الأدوات](/ar/tools/)
- [استضف BentoPDF بنفسك](/ar/self-hosting/)
- [ساهم في المشروع](/ar/contributing)
+42
View File
@@ -0,0 +1,42 @@
---
# https://vitepress.dev/reference/default-theme-home-page
layout: home
hero:
name: 'BentoPDF'
text: 'أدوات PDF مجانية ومفتوحة المصدر'
tagline: عالج ملفات PDF بالكامل داخل متصفحك. بدون رفع ملفات. بدون خوادم. خصوصية كاملة.
actions:
- theme: brand
text: ابدأ الآن
link: /ar/getting-started
- theme: alt
text: عرض الأدوات
link: /ar/tools/
- theme: alt
text: الاستضافة الذاتية
link: /ar/self-hosting/
- theme: alt
text: الترخيص التجاري
link: /ar/licensing
features:
- icon: 🔒
title: خصوصية 100%
details: ملفاتك لا تغادر جهازك أبدًا. تتم كل المعالجة محليًا في متصفحك باستخدام WebAssembly.
- icon: ⚡
title: سريع ومجاني
details: بدون تسجيل، بدون حدود، بدون علامات مائية. عالج عددًا غير محدود من ملفات PDF مجانًا، إلى الأبد.
- icon: 🛠️
title: أكثر من 50 أداة
details: حوّل وحرّر وادمج وقسّم وضغط ووقّع وطبّق OCR، والمزيد. كل ما تحتاجه في مكان واحد.
- icon: 🌐
title: قابل للاستضافة الذاتية
details: انشره على بنيتك التحتية الخاصة. Docker أو Vercel أو Netlify أو AWS، أو بيئات معزولة تمامًا عن الإنترنت مع عمال OCR وبيانات لغات وخطوط طبقة نصية مستضافة ذاتيًا.
---
## OCR بدون اتصال
إذا استضفت BentoPDF ذاتيًا في بيئة معزولة عن الإنترنت أو بدون اتصال، فإن OCR يحتاج إلى أكثر من عامل Tesseract وملفات traineddata. فإخراج PDF القابل للبحث يتطلب أيضًا تقديم خطوط الطبقة النصية الخاصة بـ OCR من الداخل.
راجع [الاستضافة الذاتية](/ar/self-hosting/) للإعداد الكامل، بما في ذلك `VITE_OCR_FONT_BASE_URL` والمجلد المضمّن `ocr-fonts/` وسير العمل المحدّث للبيئات المعزولة.
+110
View File
@@ -0,0 +1,110 @@
# Commercial License
BentoPDF is dual-licensed under **AGPL-3.0** (for open-source projects) and a **Commercial License** (for proprietary/closed-source applications).
::: tip Full Details
For complete licensing information, delivery details, AGPL component notices, and invoicing, visit our [Licensing Page](https://www.bentopdf.com/licensing).
:::
## Get a Commercial License
**[Get Lifetime License for $79](https://buy.polar.sh/polar_cl_ThDfffbl733x7oAodcIryCzhlO57ZtcWPq6HJ1qMChd)**. A one-time purchase that includes all future updates forever.
## When Do You Need a Commercial License?
| Use Case | License Required |
| ------------------------------------------- | ---------------------- |
| Open-source project with public source code | AGPL-3.0 (Free) |
| Internal company tool (not distributed) | AGPL-3.0 (Free) |
| Proprietary/closed-source application | **Commercial License** |
| SaaS product without source code disclosure | **Commercial License** |
| Redistributing without AGPL compliance | **Commercial License** |
## Delivery & Licensing Model
- **No license key is required or provided.** BentoPDF intentionally does not use license keys to streamline deployment and reduce operational friction for users.
- Upon purchase, users receive a ZIP archive containing the complete BentoPDF source code and binaries.
- The source code provided is identical to the code published in our public open-source repository.
**GitHub Repository:** [github.com/alam00000/bentopdf](https://github.com/alam00000/bentopdf)
## Important Notice on Third-Party Components
::: info AGPL Components — Pre-configured via CDN
BentoPDF **does not bundle** AGPL-licensed processing libraries in its source code. These components are loaded at runtime from CDN URLs that are **pre-configured by default** — all features work out of the box with zero setup.
| Component | License | Status |
| --------------- | -------- | ---------------------- |
| **PyMuPDF** | AGPL-3.0 | Pre-configured via CDN |
| **Ghostscript** | AGPL-3.0 | Pre-configured via CDN |
| **CoherentPDF** | AGPL-3.0 | Pre-configured via CDN |
WASM module URLs are configured via environment variables at build time (`.env.production`). The defaults point to jsDelivr CDN. For custom deployments (air-gapped, self-hosted), you can override via environment variables, Docker build args, or per-user via **Advanced Settings** in the UI.
See [Self-Hosting > WASM Configuration](/ar/self-hosting/#إعداد-wasm-مكونات-agpl) for details.
This approach ensures:
- BentoPDF's core code remains under its dual-license (AGPL-3.0 / Commercial)
- WASM binaries are loaded at runtime, not included in the source
- Clear compliance boundaries for commercial users
:::
::: tip Commercial License & AGPL Features
The commercial license covers BentoPDF's own code. If you configure and use AGPL components (PyMuPDF, Ghostscript, CoherentPDF), you must still comply with their respective AGPL-3.0 license terms, which may require source code disclosure if you distribute modified versions.
:::
## Invoicing
- Payments are handled by [Polar](https://polar.sh), which automatically emails an invoice after purchase.
- Polar handles VAT invoices for businesses in applicable regions. Select **"I'm purchasing as a business"** at checkout and enter your billing address and Tax/VAT number.
**Questions?** Contact [[email protected]](mailto:[email protected]) with your purchase details.
## What's Included
| Feature | Included |
| ----------------------------- | -------------- |
| Full source code | ✅ |
| All 50+ PDF tools | ✅ |
| Self-hosting rights | ✅ |
| Lifetime updates | ✅ |
| Remove branding (Simple Mode) | ✅ |
| Hyper Compress (bundled) | ✅ |
| Commercial support | ✅ (via email) |
| Priority feature requests | ✅ |
## Bundled Components
**Building on BentoPDF? Hyper Compress is included.** The BentoPDF commercial license includes [Hyper Compress](https://github.com/alam00000/bentopdf-hyper-compress) as a bundled component, so you don't need a separate Hyper Compress license to use it inside BentoPDF.
You may use a bundled component only through BentoPDF's own tools, as part of the BentoPDF application you deploy, including your branded or modified version of BentoPDF. You may not:
- call it from your own code through an API, SDK, command line, or headless or server process;
- separate, repackage or sublicense it, or use it in other software;
- offer a product or service whose main purpose is what the bundled component does, such as a compression-only app or website;
- modify the bundled component itself.
Any other use requires a separate [Hyper Compress license](https://www.bentopdf.com/hyper-compress#pricing), from $99/year. [Kura](https://github.com/alam00000/bentopdf-kura) is not a bundled component and is always licensed separately, with [commercial licenses](https://www.bentopdf.com/kura#pricing) from $99/year.
## FAQ
### Do I need a license key to use BentoPDF?
No. BentoPDF does not use license keys. The commercial license grants you legal rights to use the software in proprietary applications.
### Can I use BentoPDF in my SaaS product?
Yes, with a commercial license. Without it, you must comply with AGPL-3.0, which requires you to make your full source code available to users.
### Does the commercial license cover Hyper Compress or Kura?
Hyper Compress, yes, when you use it through BentoPDF. It is included as a [bundled component](#bundled-components). Using the engine on its own, or inside other software, needs a separate [Hyper Compress license](https://www.bentopdf.com/hyper-compress#pricing), from $99/year. Kura is not included and is licensed separately, from [$99/year](https://www.bentopdf.com/kura#pricing).
### What about the AGPL components?
Components like CoherentPDF are licensed under AGPL v3 and remain under that license. The commercial license covers BentoPDF's own code but does not override third-party AGPL obligations.
### How do I get an invoice?
Polar emails your invoice automatically after purchase. For a VAT invoice, select "I'm purchasing as a business" at checkout. If you need anything else, email [[email protected]](mailto:[email protected]) with your purchase details.
+275
View File
@@ -0,0 +1,275 @@
# النشر باستخدام Apache
استضف BentoPDF باستخدام خادم Apache HTTP.
## المتطلبات
- Apache 2.4+
- تفعيل mod_rewrite
- شهادة SSL (موصى بها)
## الخطوة 1: بناء المشروع
```bash
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
npm install
npm run build
```
لتخصيص العلامة التجارية، عيّن متغيرات البيئة قبل البناء:
```bash
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
```
## الخطوة 2: نسخ الملفات
```bash
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdf
```
## الخطوة 3: إعداد Apache
أنشئ `/etc/apache2/sites-available/bentopdf.conf`:
```apache
<VirtualHost *:80>
ServerName your-domain.com
Redirect permanent / https://your-domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.com
DocumentRoot /var/www/bentopdf
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
<Directory /var/www/bentopdf>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# WASM MIME type
AddType application/wasm .wasm
# Prevent double-compression of pre-compressed files
SetEnvIfNoCase Request_URI "\.gz$" no-gzip
# Compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json application/wasm
</IfModule>
# Cache headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/wasm "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>
# Required headers for SharedArrayBuffer (LibreOffice WASM)
Header always set Cross-Origin-Embedder-Policy "require-corp"
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Resource-Policy "cross-origin"
# Security headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
# Pre-compressed LibreOffice WASM files
<FilesMatch "soffice\.wasm\.gz$">
ForceType application/wasm
Header set Content-Encoding "gzip"
</FilesMatch>
<FilesMatch "soffice\.data\.gz$">
ForceType application/octet-stream
Header set Content-Encoding "gzip"
</FilesMatch>
</VirtualHost>
```
## الخطوة 4: ملف .htaccess للتوجيه
أنشئ `/var/www/bentopdf/.htaccess`:
```apache
RewriteEngine On
RewriteBase /
# Existing files/dirs - serve directly
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# ============================================
# LANGUAGE ROUTES
# ============================================
# Supported languages: de, es, zh, zh-TW, vi, it, id, tr, fr, pt
# English has no prefix - served from root
# English prefix redirects to root
RewriteRule ^en/?$ / [R=301,L]
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]
# 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]
# ============================================
# ADD .HTML EXTENSION (ROOT LEVEL)
# ============================================
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^/]+)$ $1.html [L]
ErrorDocument 404 /404.html
```
## الخطوة 5: تفعيل الوحدات المطلوبة
```bash
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod expires
sudo a2enmod deflate
```
## الخطوة 6: تفعيل الموقع
```bash
sudo a2ensite bentopdf.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
```
## النشر في مجلد فرعي
للاستضافة على المسار `/pdf/`:
1. ابنِ المشروع مع عنوان أساسي (base URL):
```bash
BASE_URL=/pdf/ npm run build
```
2. حدّث `.htaccess`:
```apache
RewriteEngine On
RewriteBase /pdf/
# Existing files/dirs - serve directly
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Language routes
RewriteRule ^en/?$ /pdf/ [R=301,L]
RewriteRule ^en/(.+)$ /pdf/$1 [R=301,L]
RewriteCond %{DOCUMENT_ROOT}/pdf/$1/index.html -f
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/?$ /pdf/$1/index.html [L]
RewriteCond %{DOCUMENT_ROOT}/pdf/$1/$2.html -f
RewriteRule ^(de|es|zh|zh-TW|vi|it|id|tr|fr|pt)/([^/]+)/?$ /pdf/$1/$2.html [L]
# Root level .html extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^/]+)$ $1.html [L]
ErrorDocument 404 /pdf/404.html
```
## استكشاف الأخطاء وإصلاحها
### أخطاء WASM 404
تأكد من ضبط نوع MIME:
```apache
AddType application/wasm .wasm
```
### أداة توقيع PDF أو تعبئة النماذج تعرض عارضًا فارغًا (خطأ MIME لملفات `.mjs`)
إذا ظهر في وحدة تحكم المتصفح:
```
Failed to load module script: The server responded with a non-JavaScript
MIME type of "application/octet-stream". Strict MIME type checking is
enforced for module scripts per HTML spec.
```
...وكان الطلب الفاشل ينتهي بـ `.mjs`، فإن إعداد Apache لديك يفتقد الربط `.mjs → application/javascript`. يتضمن عارض PDF المدمج ملفات وحدات ES بامتداد `.mjs`، ولا يشملها ملف `mime.types` الافتراضي في Apache.
أضف التالي إلى VirtualHost أو إلى `.htaccess`:
```apache
AddType application/javascript .mjs
```
ثم أعد تحميل Apache:
```bash
sudo apache2ctl configtest && sudo systemctl reload apache2
```
للتأكد: في أدوات المطوّر بالمتصفح (DevTools) ← تبويب Network، ابحث عن طلب `.mjs` الفاشل وافحص ترويسة الاستجابة `Content-Type`. يجب أن تكون الآن `application/javascript` وليست `application/octet-stream`.
### إعادة الكتابة لا تعمل
تأكد من تفعيل mod_rewrite:
```bash
sudo a2enmod rewrite
```
### تحويل Word/ODT/Excel إلى PDF لا يعمل
يتطلب LibreOffice WASM وجود `SharedArrayBuffer`، وهذا يحتاج إلى هذه الترويسات:
```apache
Header always set Cross-Origin-Embedder-Policy "require-corp"
Header always set Cross-Origin-Opener-Policy "same-origin"
```
ويحتاج أيضًا إلى سياق آمن. يعمل `http://localhost` للاختبار المحلي، لكن `http://192.168.x.x` أو غيره من عناوين الشبكة المحلية يتطلب عادةً HTTPS. إذا كانت الترويسات موجودة لكن `window.crossOriginIsolated` ما زالت `false`، فتحقق مما إذا كانت الصفحة تُفتح عبر HTTP عادي من مصدر ليس عنوان الحلقة المحلية.
كما تحتاج ملفات `.wasm.gz` و`.data.gz` المضغوطة مسبقًا إلى `Content-Encoding` صحيح:
```apache
<FilesMatch "soffice\.wasm\.gz$">
ForceType application/wasm
Header set Content-Encoding "gzip"
</FilesMatch>
<FilesMatch "soffice\.data\.gz$">
ForceType application/octet-stream
Header set Content-Encoding "gzip"
</FilesMatch>
```
تأكد من تفعيل `mod_headers`: `sudo a2enmod headers`
### تم رفض الإذن
```bash
sudo chown -R www-data:www-data /var/www/bentopdf
sudo chmod -R 755 /var/www/bentopdf
```

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