Compare commits

...

122 Commits

Author SHA1 Message Date
github-actions[bot]
03529567ba 📝 Update README: Translation Progress Table (#2254)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-15 22:18:01 +00:00
Anthony Stirling
781a52c759 Update ignore_translation.toml 2024-11-15 22:15:36 +00:00
Anthony Stirling
be2c103065 Update build.gradle 2024-11-15 21:56:57 +00:00
albanobattistella
80fd2eff5f Update messages_it_IT.properties (#2250)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-15 21:53:39 +00:00
github-actions[bot]
65abfd9c7a Update translation files (#2252)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-11-15 21:52:28 +00:00
Rafael Encinas
1833d7cd73 Clear file inputs after jobs (#2248) 2024-11-15 20:21:23 +00:00
reecebrowne
fd93dad9a5 Multitool advertising (#2247)
* Multi-tool advert on pages that share functionality

* Update translation files

Signed-off-by: GitHub Action <action@github.com>

---------

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-11-15 18:57:51 +00:00
albanobattistella
ef18b17890 Update messages_it_IT.properties (#2239) 2024-11-15 11:27:02 +00:00
Ludy
d3ae9f9a81 Prohibit the registration of unauthorized usernames (#2240) 2024-11-15 09:36:59 +00:00
Ludy
4a70d680a4 added title display on hovering, added missing german translations (#2237)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-15 09:28:37 +00:00
Ludy
82ebd3dba9 Add: missing swagger Tag (#2238) 2024-11-15 09:25:17 +00:00
MaratheHarshad
15848e3de6 Fix: Ensure backend receives false when checkbox is unchecked in split-pdf-by-chapters feature (#2234)
* Implemented hidden input tags to resolve issue with file input handling

* Cleanup: Remove log statements for production readiness

---------

Co-authored-by: Harshad Marathe <harshad@DESKTOP-1MNKUHA>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-14 21:46:24 +00:00
github-actions[bot]
ea0d9301ff 📝 Update README: Translation Progress Table (#2236)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-14 20:22:45 +00:00
reecebrowne
b27e1f254c Feature/1976/multi tool multiple pages (#2200)
* Multitool - Select multiple pages for rotation tool

* Multitool multi select delete feature

* Multitool multi select UI improvements and big fixes

* Multitool multi select select all and UI improvements

* Multi tool multi select, download selected, clean up and bug fixes

* Comments

* Update buttons for page selection

* Update translation files

Signed-off-by: GitHub Action <action@github.com>

* Multitool multiselect split functionality and UI updates

* Download selected button, additional tooltips

* Update translation files

Signed-off-by: GitHub Action <action@github.com>

* revert CertSignController

* remove material icons

* restore to previous certsigncontroller

* Update CertSignController.java

---------

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-14 20:00:36 +00:00
Anthony Stirling
7f30882e5e Setup new docker org stirlingtools/stirling-pdf (#2232)
* Update push-docker.yml

* Update push-docker.yml

* Update push-docker.yml
2024-11-14 11:20:17 +00:00
Anthony Stirling
26c0a92e30 Update pull_request_template.md 2024-11-13 13:59:22 +00:00
Renan
5cf53e39d0 Increase watermark coverage to fill page (#2049) (#2220)
* Increase watermark coverage to fill page (#2049)

* Increase watermark coverage to fill page with the new calculation (#2049)
2024-11-13 11:12:30 +00:00
Dimitris Kaitantzidis
7f566d5de8 Fix canvas crop (#2221)
* WIP: fixes canvas and rect to crop - small problem in smaller screens - neew to fix re render page on resize

* Closes #2209
2024-11-13 10:35:02 +00:00
S. Neuhaus
caa32c5bae Mention HTTP error 413 in FAQ (#2226) 2024-11-13 10:33:27 +00:00
Ludy
41c41cc88c adds missing dependencies in the endpoints (#2224) 2024-11-13 08:54:11 +00:00
leo-jmateo
c2acd74447 Catalan Translation - Stirling PDF String Updates (#2222)
* Update messages_ca_CA.properties

Partial Catalan Translation Contribution for Stirling PDF

Hi,

I’ve completed a partial Catalan translation for Stirling PDF, covering all strings up to the Pipeline section. I focused on maintaining consistency in terminology to ensure a smooth user experience in Catalan.

* Update messages_ca_CA.properties

Update on Catalan Translation Verification – Test 2 Passed

Hi [Developer’s Name],

I’ve now completed the verification for Test 2 and ensured that all keys in messages_en_GB.properties align with those in messages_ca_CA.properties. The files should now be fully synchronized with no missing or extra keys.

I’ll proceed to re-run the tests to confirm everything is in order.

Please feel free to review the updated pull request, and let me know if there’s anything further you’d like me to adjust.

Thank you for your support!

Best regards,

* Catalan Translation - Stirling PDF String Updates

Hi,

I have worked on the Catalan translation for some of the text strings in the Stirling PDF project. Attached are my contributions, which include the relevant strings for various parts of the system. I’ve made a few small adjustments to ensure the translation is as accurate and coherent as possible in technical contexts.

Changes made:
	1.	Translation of strings related to PDF manipulation tools (e.g., Add Watermark, Split PDF, etc.).
	2.	Adjustments of terms for better accuracy, such as using “Eliminar” instead of “Treure” or “Esborrar”.
	3.	Review of technical translations to ensure consistency, such as using “Nombre” instead of “Quantitat” for referring to the number of documents or pages.

Attached are the modified strings for your review:
	•	[Attach the modified strings file]

If you have any questions or need further adjustments, I’m happy to help.

Thank you for your attention and for all your work on the project!

Best regards,

* Catalan Translation - Stirling PDF String Updates

Hi,

I have worked on the Catalan translation for some of the text strings in the Stirling PDF project. Attached are my contributions, which include the relevant strings for various parts of the system. I’ve made a few small adjustments to ensure the translation is as accurate and coherent as possible in technical contexts.

Changes made:
	1.	Translation of strings related to PDF manipulation tools (e.g., Add Watermark, Split PDF, etc.).
	2.	Adjustments of terms for better accuracy, such as using “Eliminar” instead of “Treure” or “Esborrar”.
	3.	Review of technical translations to ensure consistency, such as using “Nombre” instead of “Quantitat” for referring to the number of documents or pages.

Attached are the modified strings for your review:
	•	[Attach the modified strings file]

If you have any questions or need further adjustments, I’m happy to help.

Thank you for your attention and for all your work on the project!

Best regards,

* Catalan Translation - Stirling PDF String Updates

Hi,

I have worked on the Catalan translation for some of the text strings in the Stirling PDF project. Attached are my contributions, which include the relevant strings for various parts of the system. I’ve made a few small adjustments to ensure the translation is as accurate and coherent as possible in technical contexts.

Changes made:
	1.	Translation of strings related to PDF manipulation tools (e.g., Add Watermark, Split PDF, etc.).
	2.	Adjustments of terms for better accuracy, such as using “Eliminar” instead of “Treure” or “Esborrar”.
	3.	Review of technical translations to ensure consistency, such as using “Nombre” instead of “Quantitat” for referring to the number of documents or pages.

Attached are the modified strings for your review:
	•	[Attach the modified strings file]

If you have any questions or need further adjustments, I’m happy to help.

Thank you for your attention and for all your work on the project!

Best regards,

* Catalan Translation - Stirling PDF String Updates

* 📝 Sync README
> Made via sync_files.yml

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-13 07:54:49 +00:00
Ludy
4d5d0e3cef Removes references to nonexistent endpoint (#2223) 2024-11-13 07:51:47 +00:00
MaratheHarshad
df6af8766f Restricting file input to .md files for Markdown to PDF conversion (#2219)
Co-authored-by: Harshad Marathe <harshad@DESKTOP-1MNKUHA>
2024-11-12 16:58:51 +00:00
Anthony Stirling
0dd4456ae8 Update HowToUseOCR.md 2024-11-12 13:31:34 +00:00
Anthony Stirling
b0c8912742 Update README.md 2024-11-12 11:06:04 +00:00
github-actions[bot]
467be09749 📝 Update README: Translation Progress Table (#2214)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-11 23:16:05 +00:00
Anthony Stirling
ceabcf2b3d Update get-info-on-pdf.html #2212 2024-11-11 23:12:57 +00:00
leo-jmateo
361a0c9be8 Update messages_ca_CA.properties (#2210)
* Update messages_ca_CA.properties

Partial Catalan Translation Contribution for Stirling PDF

Hi,

I’ve completed a partial Catalan translation for Stirling PDF, covering all strings up to the Pipeline section. I focused on maintaining consistency in terminology to ensure a smooth user experience in Catalan.

* Update messages_ca_CA.properties

Update on Catalan Translation Verification – Test 2 Passed

Hi [Developer’s Name],

I’ve now completed the verification for Test 2 and ensured that all keys in messages_en_GB.properties align with those in messages_ca_CA.properties. The files should now be fully synchronized with no missing or extra keys.

I’ll proceed to re-run the tests to confirm everything is in order.

Please feel free to review the updated pull request, and let me know if there’s anything further you’d like me to adjust.

Thank you for your support!

Best regards,

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-11 22:38:54 +00:00
Ludy
128ca8e224 Fix: Reading the username based on the login method. (#2211) 2024-11-11 11:55:46 +00:00
Anthony Stirling
7d1d6d1f12 Update Version-groups.md 2024-11-11 10:40:27 +00:00
Ludovic Ortega
645c786d95 feat: move helm chart to https://github.com/Stirling-Tools/Stirling-PDF-chart (#2208)
* feat: remove helm chart

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>

* feat: mention kubernetes in install doc

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>

---------

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-10 13:48:58 +00:00
Ludy
862a88e2e9 Fix: missing opener for View PDF #2206 (#2207)
Fix missing opener for View PDF #2206
2024-11-10 13:24:12 +00:00
github-actions[bot]
2f92aa90ef 💾 Update Version (#2205)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-09 23:11:42 +00:00
Anthony Stirling
ba8dd04086 Update build.gradle 2024-11-09 23:11:10 +00:00
github-actions[bot]
c13509cf67 💾 Update Version (#2204)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-09 23:10:30 +00:00
Anthony Stirling
0ab02e6ceb Update build.gradle 2024-11-09 23:02:12 +00:00
Anthony Stirling
af52652aee Rename release-helm-charts.yml to release-helm-charts.yml-disabled 2024-11-09 23:01:55 +00:00
Anthony Stirling
e534f022f5 Rename lint-helm-charts.yml to lint-helm-charts.yml-disabled 2024-11-09 23:01:26 +00:00
Ludy
84867a7ad7 Fix: Card has no favorite icon (#2203)
fixes the bug if the card has no favorite icon
2024-11-09 15:07:51 +00:00
Renan
e97cb9d49e Add option to insert blank page between pages in Multi-tool (#2194) (#2201) 2024-11-08 22:51:03 +00:00
Anthony Stirling
1b0c1b6cff Searchbar in nav auto select, and exe nolonger disable CLI (#2197)
* fix remmeber me

* remove uselss comment

* Update translation files (#2185)

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>

* exe no longer disable CLI

---------

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: a <a>
2024-11-07 21:50:47 +00:00
Rafael Encinas
7eea7fb3cb [Feature] Set Executor Instances limits dynamically from properties (#2193)
* Update 'ProcessExecutor.java' to use dynamic process limits from properties

* Move limits location out of 'application.properties'

* Rename 'SemaphoreLimit' to 'SessionLimit' and bundle with 'Timeout...' into one parent class
2024-11-07 00:43:57 +00:00
github-actions[bot]
c921b5d76f 📝 Update README: Translation Progress Table (#2190)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-05 23:28:15 +00:00
Peter Dave Hello
26ec0c5d77 Update and improve zh_TW Traditional Chinese locale (#2188) 2024-11-05 23:26:26 +00:00
ninjat
404e31468e Added input sanitization to fix self-xss issue (#2189) 2024-11-05 21:44:24 +00:00
Anthony Stirling
0c0f61aa0d fix remmeber me (#2184)
* fix remmeber me

* remove uselss comment

* Update translation files (#2185)

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>

---------

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-11-05 14:31:31 +00:00
Ludovic Ortega
40ffb6559d feat: add helm chart github action (#2113)
* feat: add helm chart github action

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>

* fix: remove test branch

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>

* fix: run helm-docs-built after syncing version

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>

* fix: helm repo url

---------

Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-11-04 20:13:26 +00:00
github-actions[bot]
645c5ff36f 📝 Update README: Translation Progress Table (#2165)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-03 22:47:28 +00:00
MaratheHarshad
83db7a22f5 Fix: Navbar layout overflow (#2162)
Fix: Navbar layout overflow using Bootstrap class .navbar-expand-xl

Co-authored-by: Harshad Marathe <harshad@DESKTOP-1MNKUHA>
2024-11-03 20:59:57 +00:00
Ludy
ebfccfa835 Corrects AI generated translation (#2166) 2024-11-03 20:39:00 +00:00
Saud Fatayerji
aa810163d2 Completed translations for 19 languages using AI (#2164)
Created translations for various languages using AI
2024-11-03 20:14:45 +00:00
github-actions[bot]
dcb69ad66a 📝 Update README: Translation Progress Table (#2160)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-03 18:05:03 +00:00
Ludy
1a19024961 Fix: Auto language detection #2122 (#2148)
* Fix: Auto language detection #2122

* add LanguageService and AdditionalLanguageJsController

* hidden swagger
2024-11-03 14:20:26 +00:00
albanobattistella
68c9601245 Update messages_it_IT.properties (#2161) 2024-11-03 14:16:06 +00:00
Ludy
7ec343d9ce Fix: Add missing .map file for minified files (#2156) 2024-11-03 07:55:39 +00:00
Ludy
6f42d976f6 Fix: Path correction to draggable.js #2154 + little makeup (#2159) 2024-11-03 07:26:45 +00:00
Ludy
cf13803fd4 Fix: redeclaration of const and add: tranlation placeholder for Session Expiry Messages (#2158)
Fix: redeclaration of const
2024-11-03 07:24:16 +00:00
Ludy
a8d0d1a871 re-config labeler & add new labels (#2153)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-11-03 07:21:56 +00:00
Ludy
a5aac01b4d fixed minor bugs in Markdown (#2152) 2024-11-03 07:20:10 +00:00
albanobattistella
2be14788b1 Update messages_it_IT.properties (#2146) 2024-11-01 16:32:52 +00:00
github-actions[bot]
217404be7f 📝 Update README: Translation Progress Table (#2136)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-31 20:33:03 +00:00
github-actions[bot]
d3dc3e07b2 Update translation files (#2145)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-31 20:22:11 +00:00
Eric
94702dbafa fix signature logo not loading and add option to disable it (#2143)
* fix signature logo not loading and add option to disable it

* Hardening suggestions for Stirling-PDF / fix-sig-logo (#2144)

Modernize and secure temp file creation

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>

---------

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
2024-10-31 20:18:42 +00:00
Anthony Stirling
febc3cf48b Update pull_request_template.md 2024-10-31 17:46:30 +00:00
Philip H.
c5abb47403 navbar.css: prevent overlapping of elements (#2140)
go-pro-link is overlapping the settings button
2024-10-31 17:45:44 +00:00
Anthony Stirling
0e3c9bcc10 Update README.md 2024-10-31 14:52:41 +00:00
github-actions[bot]
384c3ee88f 💾 Update Version (#2139)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-31 13:06:55 +00:00
Anthony Stirling
5f7a0537f9 Update build.gradle 2024-10-31 13:06:12 +00:00
Anthony Stirling
5aa5628465 [bug fix] Update compress-pdf.html (#2138)
Update compress-pdf.html
2024-10-31 10:59:51 +00:00
albanobattistella
0d91bca932 Update messages_it_IT.properties (#2135) 2024-10-30 19:55:54 +00:00
Ludovic Ortega
8e88591499 chore(helm): bump chart version according to semver (#2109)
Signed-off-by: Ludovic Ortega <ludovic.ortega@adminafk.fr>
2024-10-30 13:49:28 +00:00
github-actions[bot]
3e051d0105 Update 3rd Party Licenses (#2134)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-30 13:00:51 +00:00
dependabot[bot]
4a9b16ff8f Bump org.springframework.security:spring-security-saml2-service-provider from 6.3.3 to 6.3.4 (#2052)
Bump org.springframework.security:spring-security-saml2-service-provider

Bumps [org.springframework.security:spring-security-saml2-service-provider](https://github.com/spring-projects/spring-security) from 6.3.3 to 6.3.4.
- [Release notes](https://github.com/spring-projects/spring-security/releases)
- [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc)
- [Commits](https://github.com/spring-projects/spring-security/compare/6.3.3...6.3.4)

---
updated-dependencies:
- dependency-name: org.springframework.security:spring-security-saml2-service-provider
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-30 12:58:47 +00:00
github-actions[bot]
a7082ecd85 💾 Update Version (#2132)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-30 12:48:44 +00:00
github-actions[bot]
966e6a4923 📝 Update README: Translation Progress Table (#2133)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-30 12:48:30 +00:00
Anthony Stirling
27d2681a97 Feature/save signs (#2127)
* apply fix

* Fixes empty th:action

* Update build.gradle

* fix

* formatting

* Save signatures

* Fix code scanning alert no. 42: Uncontrolled data used in path expression

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix UserServiceInterface

* Merge branch 'feature/saveSigns' of
git@github.com:Stirling-Tools/Stirling-PDF.git into feature/saveSigns

* 0.31.0 bump and further csrf

* formatting

* preview name

* add

* sign doc

* Update translation files (#2128)

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>

---------

Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: Dimitrios Kaitantzidis <james_k23@hotmail.gr>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: a <a>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-30 12:46:44 +00:00
github-actions[bot]
ed75fa4e1b 📝 Update README: Translation Progress Table (#2129)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 19:05:01 +00:00
Rania Amina
9b9752bd7a Update id_ID Translation and fix some grammars (#2108)
* Update id_ID Translation and fix some grammars

* sync lines to fix build warning

* get back new line at end of file

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-10-29 19:03:00 +00:00
Anthony Stirling
903dc7638c Fix csrf (#2126)
* apply fix

* Fixes empty th:action

* Update build.gradle

* fix

* formatting

---------

Co-authored-by: Dimitrios Kaitantzidis <james_k23@hotmail.gr>
2024-10-29 17:56:29 +00:00
github-actions[bot]
c39b111edc 📝 Update README: Translation Progress Table (#2121)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 16:31:25 +00:00
github-actions[bot]
d910929aa6 Update translation files (#2125)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-29 16:30:44 +00:00
reecebrowne
a9ce0e80ee Feature/298 improve compare performance (#2124)
* Implement Diff.js

* Compare feature - add service worker and improve efficiency for large files

* Compare - messages updated to be compatable with language packs

* Compare - Acknowledge Diff.js usage

* Add message warning there is  no text in uploaded pdf to messages file

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
2024-10-29 15:56:45 +00:00
Florian Fish
4922ab700e Add new french translations (#2120)
Add new french translations and improve simple quote
2024-10-29 10:12:49 +00:00
github-actions[bot]
01f3c138a6 Update 3rd Party Licenses (#2119)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-28 23:22:15 +00:00
github-actions[bot]
4e21f76979 📝 Update README: Translation Progress Table (#2103)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-28 23:22:02 +00:00
dependabot[bot]
a9ccd85e75 Bump org.springframework.boot from 3.3.4 to 3.3.5 (#2118)
Bumps [org.springframework.boot](https://github.com/spring-projects/spring-boot) from 3.3.4 to 3.3.5.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

---
updated-dependencies:
- dependency-name: org.springframework.boot
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 23:19:59 +00:00
dependabot[bot]
6f407f1d2f Bump springBootVersion from 3.3.4 to 3.3.5 (#2117)
Bumps `springBootVersion` from 3.3.4 to 3.3.5.

Updates `org.springframework.boot:spring-boot-starter-web` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-jetty` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-thymeleaf` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-security` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-data-jpa` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-oauth2-client` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-test` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-starter-actuator` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

Updates `org.springframework.boot:spring-boot-devtools` from 3.3.4 to 3.3.5
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.3.5)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-starter-web
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-jetty
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-thymeleaf
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-security
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-data-jpa
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-oauth2-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-test
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-starter-actuator
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.springframework.boot:spring-boot-devtools
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-28 23:19:36 +00:00
pixeebot[bot]
af5e2b6895 Modernize and secure temp file creation (#2106)
Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
2024-10-28 23:19:12 +00:00
Ludy
d2046c64d8 Optimierung der SAML2-Integration und Verbesserung der Zertifikats- und Fehlerbehandlung (#2105)
* certificate processing

* Hides dialog when provider list is empty

* removed: unused
2024-10-27 22:17:36 +00:00
Manuel Mora Gordillo
1b88d89191 Spanish translate (#2102)
* Spanish translate

* Added blank line

---------

Co-authored-by: Manu <manuel@fusiontelecom.co>
2024-10-25 13:20:13 +01:00
github-actions[bot]
03bf98265b 📝 Update README: Translation Progress Table (#2072)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-24 14:21:17 +01:00
Anthony Stirling
89da2a5c01 Auto detect presence of external dependencies (LibreOffice etc) and disable/enable features dynamically (#2082)
* Create ExternalAppDepConfig.java

* Update EndpointConfiguration.java

* Hardening suggestions for Stirling-PDF / ExternalAppDepConfig (#2083)

Switch order of literals to prevent NullPointerException

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>

---------

Co-authored-by: pixeebot[bot] <104101892+pixeebot[bot]@users.noreply.github.com>
2024-10-24 13:59:17 +01:00
swanemar
a10d06b693 added some missing translations (#2085) 2024-10-24 10:35:32 +00:00
Eric
a7ed99084f visual certificate signing (#2084)
add visual digital signature
2024-10-24 07:08:09 +01:00
github-actions[bot]
88f3594d80 Update 3rd Party Licenses (#2080)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-23 12:28:58 +01:00
Eric
e0b77ca274 extract and apply the image orientation from exif data in imageToPdf (#2073) 2024-10-23 12:17:40 +01:00
albanobattistella
bac81c930d Update messages_it_IT.properties (#2077) 2024-10-23 12:16:49 +01:00
Corbinian Grimm
2f49626a4c Update messages_de_DE.properties (#2070)
* Update messages_de_DE.properties

Completed translations for German language.

* Update messages_de_DE.properties
2024-10-22 21:53:13 +01:00
Anthony Stirling
83ef003505 Update PostHogService.java 2024-10-22 15:36:54 +01:00
Anthony Stirling
949b87005c Fix metricCollection 2024-10-22 15:36:22 +01:00
a
532f7cdbbf Merge branch 'main' of git@github.com:Stirling-Tools/Stirling-PDF.git into main 2024-10-22 12:22:20 +01:00
Anthony Stirling
51c4a60313 Remove pro badge if enabled 2024-10-22 12:22:08 +01:00
reecebrowne
aa00808219 Removed horizontal scroll logic from multi-tool template (#2065)
* Removed horizontal scroll logic from multi-tool template

* Remove unused horizontalScroll.js
2024-10-22 12:02:00 +01:00
github-actions[bot]
5d40175e18 💾 Update Version (#2064)
💾 Sync Versions
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-22 11:30:59 +01:00
Anthony Stirling
a40fdd5a0b Fixes for analyticsPrompt 2024-10-22 11:10:09 +01:00
github-actions[bot]
6ea7ffc36c 📝 Update README: Translation Progress Table (#2062)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-22 09:54:46 +01:00
Thomas BERNARD
39e0fd8eef French translation improvements (#2061)
* fix a spelling mistake in a french message

n'importe quel fichier au singulier

* Translate "Remove Certificate Sign" to French

* french translation for pdfToPDFA.pdfWithDigitalSignature

* fix french translation for BootToPDF and PDFToBook

* Translate "Remove image" to French

* Translate "Split PDF by Chapters" to French

* fr translation : Popular => Populaire

* french translation for adminUserSettings.* messages

* french translation for session.expired
2024-10-22 08:11:48 +01:00
Anthony Stirling
cae8cd0aa9 Add on hover color to sign (#2059)
* Fixed layering issue with z-index, and added smoother transitions for… (#1996)

Fixed layering issue with z-index, and added smoother transitions for signing

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>

* Delete package-lock.json

---------

Co-authored-by: Surya Karthikeyan Vijayalakshmi <108506548+SuryaKV101@users.noreply.github.com>
2024-10-22 00:44:22 +01:00
Anthony Stirling
04d5ae1912 Default terms and conditions to stirlingpdf.com (#2058) 2024-10-22 00:42:17 +01:00
github-actions[bot]
e01ba93cf8 Update 3rd Party Licenses (#2057)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-22 00:41:44 +01:00
github-actions[bot]
edd0ec9d23 Update 3rd Party Licenses (#2056)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-22 00:22:01 +01:00
dependabot[bot]
899f3d267b Bump org.commonmark:commonmark from 0.23.0 to 0.24.0 (#2054)
Bumps [org.commonmark:commonmark](https://github.com/commonmark/commonmark-java) from 0.23.0 to 0.24.0.
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.23.0...commonmark-parent-0.24.0)

---
updated-dependencies:
- dependency-name: org.commonmark:commonmark
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-22 00:21:14 +01:00
dependabot[bot]
88c0a9e26b Bump org.springframework:spring-webmvc from 6.1.13 to 6.1.14 (#2053)
Bumps [org.springframework:spring-webmvc](https://github.com/spring-projects/spring-framework) from 6.1.13 to 6.1.14.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.13...v6.1.14)

---
updated-dependencies:
- dependency-name: org.springframework:spring-webmvc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-22 00:19:52 +01:00
dependabot[bot]
dc6cec9daf Bump org.commonmark:commonmark-ext-gfm-tables from 0.23.0 to 0.24.0 (#2055)
Bumps [org.commonmark:commonmark-ext-gfm-tables](https://github.com/commonmark/commonmark-java) from 0.23.0 to 0.24.0.
- [Release notes](https://github.com/commonmark/commonmark-java/releases)
- [Changelog](https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.23.0...commonmark-parent-0.24.0)

---
updated-dependencies:
- dependency-name: org.commonmark:commonmark-ext-gfm-tables
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-22 00:19:14 +01:00
github-actions[bot]
a64dd2e282 📝 Update README: Translation Progress Table (#2047)
📝 Sync README
> Made via sync_files.yml

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-20 21:02:09 +01:00
github-actions[bot]
c9b7d848b4 Update translation files (#2048)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-20 21:01:50 +01:00
Anthony Stirling
89a9ba6ebc remove unused translation 2024-10-20 21:00:16 +01:00
Patryk Marszelewski
22249ef9bf Update messages_pl_PL.properties (#2042) 2024-10-20 20:34:39 +01:00
github-actions[bot]
619a863b99 Update 3rd Party Licenses (#2044)
Signed-off-by: GitHub Action <action@github.com>
Co-authored-by: GitHub Action <action@github.com>
2024-10-20 20:32:57 +01:00
Peter Dave Hello
e098b2999c Update and improve zh_TW Traditional Chinese locale (#2046)
This is a small follow-up to #2030, but it will significantly improve the user experience for Traditional Chinese users.
2024-10-20 20:32:40 +01:00
IT Creativity + Art Team
1149f2a30d Update messages_bg_BG.properties (#2045)
Update messages_bg_BG.properties
2024-10-20 20:32:18 +01:00
Ludy
eff1843061 Major Enhancements to SAML2 and OAuth2 Integration with Simplified Security Configurations (#2040)
* implement Saml2 login/logout

* changed: deprecation code

* relyingPartyRegistrations only enabled samle
2024-10-20 12:30:58 +01:00
185 changed files with 11591 additions and 6992 deletions

View File

@@ -16,21 +16,27 @@ Java:
Back End: Back End:
- changed-files: - changed-files:
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/**/*'
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/provider/**/*' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/**/*'
- any-glob-to-any-file: 'src/main/resources/settings.yml.template' - any-glob-to-any-file: 'src/main/resources/settings.yml.template'
- any-glob-to-any-file: 'src/main/resources/application.properties'
- any-glob-to-any-file: 'src/main/resources/banner.txt' - any-glob-to-any-file: 'src/main/resources/banner.txt'
- any-glob-to-any-file: 'scripts/png_to_webp.py'
- any-glob-to-any-file: 'split_photos.py'
Security: Security:
- changed-files: - changed-files:
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/security/**/*'
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/provider/**/*' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/provider/**/*'
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/config/model/AuthenticationType.java' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/model/AuthenticationType.java'
- any-glob-to-any-file: 'scripts/download-security-jar.sh'
API: API:
- changed-files: - changed-files:
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/web/MetricsController.java'
- any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*' - any-glob-to-any-file: 'src/main/java/stirling/software/SPDF/controller/api/**/*'
- any-glob-to-any-file: 'scripts/png_to_webp.py'
- any-glob-to-any-file: 'split_photos.py'
Documentation: Documentation:
- changed-files: - changed-files:
@@ -43,6 +49,9 @@ Docker:
- any-glob-to-any-file: 'Dockerfile' - any-glob-to-any-file: 'Dockerfile'
- any-glob-to-any-file: 'Dockerfile-*' - any-glob-to-any-file: 'Dockerfile-*'
- any-glob-to-any-file: 'exampleYmlFiles/*.yml' - any-glob-to-any-file: 'exampleYmlFiles/*.yml'
- any-glob-to-any-file: 'scripts/init.sh'
- any-glob-to-any-file: 'scripts/init-without-ocr.sh'
- any-glob-to-any-file: 'scripts/installFonts.sh'
Test: Test:
- changed-files: - changed-files:

21
.github/labels.yml vendored
View File

@@ -3,9 +3,12 @@
# #
# The repository labels will be automatically configured using this file and # The repository labels will be automatically configured using this file and
# the GitHub Action https://github.com/marketplace/actions/github-labeler. # the GitHub Action https://github.com/marketplace/actions/github-labeler.
- name: "Licenses"
color: "EDEDED"
from_name: "licenses"
- name: "Back End" - name: "Back End"
color: "20CE6C" color: "20CE6C"
description: "Issues related to back-end development" description: "Issues or pull requests related to back-end development"
from_name: "Back end" from_name: "Back end"
- name: "Bug" - name: "Bug"
description: "Something isn't working" description: "Something isn't working"
@@ -24,6 +27,7 @@
from_name: "documentation" from_name: "documentation"
- name: "Done for next release" - name: "Done for next release"
color: "0CDBD1" color: "0CDBD1"
description: "Items that are completed and will be included in the next release"
- name: "Done" - name: "Done"
color: "60F13B" color: "60F13B"
- name: "duplicate" - name: "duplicate"
@@ -37,7 +41,7 @@
description: "Fix needs to be confirmed" description: "Fix needs to be confirmed"
- name: "Front End" - name: "Front End"
color: "BBD2F1" color: "BBD2F1"
description: "Issues related to front-end development" description: "Issues or pull requests related to front-end development"
- name: "github-actions" - name: "github-actions"
description: "Pull requests that update GitHub Actions code" description: "Pull requests that update GitHub Actions code"
color: "999999" color: "999999"
@@ -91,3 +95,16 @@
description: "Testing-related issues or pull requests" description: "Testing-related issues or pull requests"
- name: "Stale" - name: "Stale"
color: "000000" color: "000000"
description: "Issues or pull requests that have become inactive"
- name: "Priority: Critical"
color: "000000"
description: "Issues or pull requests with the highest priority"
- name: "Priority: High"
color: "FF0000"
description: "Issues or pull requests with high priority"
- name: "Priority: Medium"
color: "FFFF00"
description: "Issues or pull requests with medium priority"
- name: "Priority: Low"
color: "00FF00"
description: "Issues or pull requests with low priority"

View File

@@ -8,6 +8,8 @@ Closes #(issue_number)
- [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have performed a self-review of my own code - [ ] I have performed a self-review of my own code
- [ ] I have attached images of the change if it is UI based
- [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] If my code has heavily changed functionality I have updated relevant docs on [Stirling-PDFs doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
- [ ] My changes generate no new warnings - [ ] My changes generate no new warnings
- [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only)

View File

@@ -1,67 +0,0 @@
import re
import yaml
# Paths to the files
chart_yaml_path = "chart/stirling-pdf/Chart.yaml"
gradle_path = "build.gradle"
def get_chart_version(path):
"""
Reads the appVersion from Chart.yaml.
Args:
path (str): The file path to the Chart.yaml.
Returns:
str: The appVersion if found, otherwise an empty string.
"""
with open(path, encoding="utf-8") as file:
chart_yaml = yaml.safe_load(file)
return chart_yaml.get("appVersion", "")
def get_gradle_version(path):
"""
Extracts the version from build.gradle.
Args:
path (str): The file path to the build.gradle.
Returns:
str: The version if found, otherwise an empty string.
"""
with open(path, encoding="utf-8") as file:
for line in file:
if "version =" in line:
# Extracts the value after 'version ='
return re.search(r'version\s*=\s*[\'"](.+?)[\'"]', line).group(1)
return ""
def update_chart_version(path, new_version):
"""
Updates the appVersion in Chart.yaml with a new version.
Args:
path (str): The file path to the Chart.yaml.
new_version (str): The new version to update to.
"""
with open(path, encoding="utf-8") as file:
chart_yaml = yaml.safe_load(file)
chart_yaml["appVersion"] = new_version
with open(path, "w", encoding="utf-8") as file:
yaml.safe_dump(chart_yaml, file)
# Main logic
chart_version = get_chart_version(chart_yaml_path)
gradle_version = get_gradle_version(gradle_path)
if chart_version != gradle_version:
print(
f"Versions do not match. Updating Chart.yaml from {chart_version} to {gradle_version}."
)
update_chart_version(chart_yaml_path, gradle_version)
else:
print("Versions match. No update required.")

View File

@@ -10,6 +10,7 @@ on:
permissions: permissions:
contents: read contents: read
packages: write packages: write
jobs: jobs:
push: push:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -66,6 +67,7 @@ jobs:
images: | images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf ${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: | tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }},enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=${{ steps.versionNumber.outputs.versionNumber }},enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
@@ -93,6 +95,7 @@ jobs:
images: | images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf ${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: | tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
@@ -119,6 +122,7 @@ jobs:
images: | images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf ${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: | tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-fat,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-fat,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-fat,enable=${{ github.ref == 'refs/heads/master' }} type=raw,value=latest-fat,enable=${{ github.ref == 'refs/heads/master' }}

View File

@@ -14,44 +14,6 @@ permissions:
pull-requests: write pull-requests: write
jobs: jobs:
sync-versions:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install dependencies
run: pip install pyyaml
- name: Sync versions
run: python .github/scripts/gradle_to_chart.py
- name: Set up git config
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Run git add
run: |
git add .
git diff --staged --quiet || git commit -m ":floppy_disk: Sync Versions
> Made via sync_files.yml" || echo "no changes"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update files
committer: GitHub Action <action@github.com>
author: GitHub Action <action@github.com>
signoff: true
branch: sync_version
title: ":floppy_disk: Update Version"
body: |
Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
draft: false
delete-branch: true
labels: github-actions
sync-readme: sync-readme:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ bin/
tmp/ tmp/
*.tmp *.tmp
*.bak *.bak
*.exe
*.swp *.swp
*~.nib *~.nib
local.properties local.properties

View File

@@ -1,6 +1,7 @@
# New Database Backup and Import Functionality # New Database Backup and Import Functionality
**Full activation will take place on approximately January 5th, 2025!** > [!IMPORTANT]
> **Full activation will take place on approximately January 5th, 2025!**
Why is the waiting time six months? Why is the waiting time six months?

View File

@@ -7,6 +7,7 @@ Stirling-PDF is a robust, locally hosted web-based PDF manipulation tool. This g
## 2. Project Overview ## 2. Project Overview
Stirling-PDF is built using: Stirling-PDF is built using:
- Spring Boot + Thymeleaf - Spring Boot + Thymeleaf
- PDFBox - PDFBox
- LibreOffice - LibreOffice
@@ -20,14 +21,17 @@ Stirling-PDF is built using:
## 3. Development Environment Setup ## 3. Development Environment Setup
### Prerequisites ### Prerequisites
- Docker - Docker
- Git - Git
- Java JDK 17 or later - Java JDK 17 or later
- Gradle 7.0 or later (Included within repo) - Gradle 7.0 or later (Included within repo)
### Setup Steps ### Setup Steps
1. Clone the repository: 1. Clone the repository:
```
```bash
git clone https://github.com/Stirling-Tools/Stirling-PDF.git git clone https://github.com/Stirling-Tools/Stirling-PDF.git
cd Stirling-PDF cd Stirling-PDF
``` ```
@@ -43,10 +47,9 @@ Visit the [Lombok website](https://projectlombok.org/setup/) for installation in
5. Add environment variable 5. Add environment variable
For local testing you should generally be testing the full 'Security' version of Stirling-PDF to do this you must add the environment flag DOCKER_ENABLE_SECURITY=true to your system and/or IDE build/run step For local testing you should generally be testing the full 'Security' version of Stirling-PDF to do this you must add the environment flag DOCKER_ENABLE_SECURITY=true to your system and/or IDE build/run step
## 4. Project Structure ## 4. Project Structure
``` ```bash
Stirling-PDF/ Stirling-PDF/
├── .github/ # GitHub-specific files (workflows, issue templates) ├── .github/ # GitHub-specific files (workflows, issue templates)
├── configs/ # Configuration files used by stirling at runtime (generated at runtime) ├── configs/ # Configuration files used by stirling at runtime (generated at runtime)
@@ -92,6 +95,7 @@ Stirling-PDF/
## 5. Docker-based Development ## 5. Docker-based Development
Stirling-PDF offers several Docker versions: Stirling-PDF offers several Docker versions:
- Full: All features included - Full: All features included
- Ultra-Lite: Basic PDF operations only - Ultra-Lite: Basic PDF operations only
- Fat: Includes additional libraries and fonts predownloaded - Fat: Includes additional libraries and fonts predownloaded
@@ -153,11 +157,13 @@ docker-compose -f exampleYmlFiles/docker-compose-latest-security.yml up
Stirling-PDF uses different Docker images for various configurations. The build process is controlled by environment variables and uses specific Dockerfile variants. Here's how to build the Docker images: Stirling-PDF uses different Docker images for various configurations. The build process is controlled by environment variables and uses specific Dockerfile variants. Here's how to build the Docker images:
1. Set the security environment variable: 1. Set the security environment variable:
```bash ```bash
export DOCKER_ENABLE_SECURITY=false # or true for security-enabled builds export DOCKER_ENABLE_SECURITY=false # or true for security-enabled builds
``` ```
2. Build the project with Gradle: 2. Build the project with Gradle:
```bash ```bash
./gradlew clean build ./gradlew clean build
``` ```
@@ -165,16 +171,19 @@ Stirling-PDF uses different Docker images for various configurations. The build
3. Build the Docker images: 3. Build the Docker images:
For the latest version: For the latest version:
```bash ```bash
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile . docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
``` ```
For the ultra-lite version: For the ultra-lite version:
```bash ```bash
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite . docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
``` ```
For the fat version (with security enabled): For the fat version (with security enabled):
```bash ```bash
export DOCKER_ENABLE_SECURITY=true export DOCKER_ENABLE_SECURITY=true
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat . docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat .
@@ -182,8 +191,6 @@ Stirling-PDF uses different Docker images for various configurations. The build
Note: The `--no-cache` and `--pull` flags ensure that the build process uses the latest base images and doesn't use cached layers, which is useful for testing and ensuring reproducible builds. however to improve build times these can often be removed depending on your usecase Note: The `--no-cache` and `--pull` flags ensure that the build process uses the latest base images and doesn't use cached layers, which is useful for testing and ensuring reproducible builds. however to improve build times these can often be removed depending on your usecase
## 6. Testing ## 6. Testing
### Comprehensive Testing Script ### Comprehensive Testing Script
@@ -197,6 +204,7 @@ To run the test script:
``` ```
This script performs the following actions: This script performs the following actions:
1. Builds all Docker images (full, ultra-lite, fat) 1. Builds all Docker images (full, ultra-lite, fat)
2. Runs each version to ensure it starts correctly 2. Runs each version to ensure it starts correctly
3. Executes Cucumber tests against main version and ensures feature compatibility, in the event these tests fail your PR will not be merged 3. Executes Cucumber tests against main version and ensures feature compatibility, in the event these tests fail your PR will not be merged
@@ -209,7 +217,6 @@ Note: The `test.sh` script will run automatically when you raise a PR. However,
2. Access the application at `http://localhost:8080` and manually test all features developed. 2. Access the application at `http://localhost:8080` and manually test all features developed.
### Local Testing (Java and UI Components) ### Local Testing (Java and UI Components)
For quick iterations and development of Java backend, JavaScript, and UI components, you can run and test Stirling-PDF locally without Docker. This approach allows you to work on and verify changes to: For quick iterations and development of Java backend, JavaScript, and UI components, you can run and test Stirling-PDF locally without Docker. This approach allows you to work on and verify changes to:
@@ -223,7 +230,8 @@ For quick iterations and development of Java backend, JavaScript, and UI compone
To run Stirling-PDF locally: To run Stirling-PDF locally:
1. Compile and run the project using built in IDE methods or by running: 1. Compile and run the project using built in IDE methods or by running:
```
```bash
./gradlew bootRun ./gradlew bootRun
``` ```
@@ -234,11 +242,11 @@ To run Stirling-PDF locally:
4. For API changes, use tools like Postman or curl to test endpoints directly. 4. For API changes, use tools like Postman or curl to test endpoints directly.
Important notes: Important notes:
- Local testing doesn't include features that depend on external tools like OCRmyPDF, LibreOffice, or Python scripts. - Local testing doesn't include features that depend on external tools like OCRmyPDF, LibreOffice, or Python scripts.
- There are currently no automated unit tests. All testing is done manually through the UI or API calls. (You are welcome to add JUnits!) - There are currently no automated unit tests. All testing is done manually through the UI or API calls. (You are welcome to add JUnits!)
- Always verify your changes in the full Docker environment before submitting pull requests, as some integrations and features will only work in the complete setup. - Always verify your changes in the full Docker environment before submitting pull requests, as some integrations and features will only work in the complete setup.
## 7. Contributing ## 7. Contributing
1. Fork the repository on GitHub. 1. Fork the repository on GitHub.
@@ -246,14 +254,17 @@ Important notes:
3. Make your changes and commit them with clear, descriptive messages and ensure any documentation is updated related to your changes. 3. Make your changes and commit them with clear, descriptive messages and ensure any documentation is updated related to your changes.
4. Test your changes thoroughly in the Docker environment. 4. Test your changes thoroughly in the Docker environment.
5. Run the `test.sh` script to ensure all versions build correctly and pass the Cucumber tests: 5. Run the `test.sh` script to ensure all versions build correctly and pass the Cucumber tests:
```bash ```bash
./test.sh ./test.sh
``` ```
6. Push your changes to your fork. 6. Push your changes to your fork.
7. Submit a pull request to the main repository. 7. Submit a pull request to the main repository.
8. See additional [contributing guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) 8. See additional [contributing guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
When you raise a PR: When you raise a PR:
- The `test.sh` script will run automatically against your PR. - The `test.sh` script will run automatically against your PR.
- The PR checks will verify versioning and dependency updates. - The PR checks will verify versioning and dependency updates.
- Documentation will be automatically updated for dependency changes. - Documentation will be automatically updated for dependency changes.
@@ -268,6 +279,7 @@ API documentation is available at `/swagger-ui/index.html` when running the appl
## 9. Customization ## 9. Customization
Stirling-PDF can be customized through environment variables or a `settings.yml` file. Key customization options include: Stirling-PDF can be customized through environment variables or a `settings.yml` file. Key customization options include:
- Application name and branding - Application name and branding
- Security settings - Security settings
- UI customization - UI customization
@@ -276,7 +288,8 @@ Stirling-PDF can be customized through environment variables or a `settings.yml`
When using Docker, pass environment variables using the `-e` flag or in your `docker-compose.yml` file. When using Docker, pass environment variables using the `-e` flag or in your `docker-compose.yml` file.
Example: Example:
```
```bash
docker run -p 8080:8080 -e APP_NAME="My PDF Tool" stirling-pdf:full docker run -p 8080:8080 -e APP_NAME="My PDF Tool" stirling-pdf:full
``` ```
@@ -293,16 +306,14 @@ For managing language translations that affect multiple files, Stirling-PDF prov
This script helps you make consistent replacements across language files. This script helps you make consistent replacements across language files.
When contributing translations: When contributing translations:
1. Use the helper script for multi-file changes. 1. Use the helper script for multi-file changes.
2. Ensure all language files are updated consistently. 2. Ensure all language files are updated consistently.
3. The PR checks will verify consistency in language file updates. 3. The PR checks will verify consistency in language file updates.
Remember to test your changes thoroughly to ensure they don't break any existing functionality. Remember to test your changes thoroughly to ensure they don't break any existing functionality.
## Code examples
# Code examples
### Overview of Thymeleaf ### Overview of Thymeleaf
@@ -311,22 +322,28 @@ Thymeleaf is a server-side Java HTML template engine. It is used in Stirling-PD
### Thymeleaf overview ### Thymeleaf overview
In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content. In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content.
Some examples of this are
Some examples of this are:
```html ```html
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block> <th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
or or
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block> <th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
``` ```
Where it uses the th:block, th: indicating its a special thymeleaf element to be used serverside in generating the html, and block being the actual element type. Where it uses the th:block, th: indicating its a special thymeleaf element to be used serverside in generating the html, and block being the actual element type.
In this case we are inserting the ``navbar`` entry within the ``fragments/navbar.html`` fragment into the ``th:block`` element. In this case we are inserting the ``navbar`` entry within the ``fragments/navbar.html`` fragment into the ``th:block`` element.
They can be more complex such as They can be more complex such as:
```html ```html
<th:block th:insert="~{fragments/common :: head(title=#{pageExtracter.title}, header=#{pageExtracter.header})}"></th:block> <th:block th:insert="~{fragments/common :: head(title=#{pageExtracter.title}, header=#{pageExtracter.header})}"></th:block>
``` ```
Which is the same as above but passes the parameters title and header into the fragment common.html to be used in its HTML generation Which is the same as above but passes the parameters title and header into the fragment common.html to be used in its HTML generation
Thymeleaf can also be used to loop through objects or pass things from java side into html side. Thymeleaf can also be used to loop through objects or pass things from java side into html side.
```java ```java
@GetMapping @GetMapping
public String newFeaturePage(Model model) { public String newFeaturePage(Model model) {
@@ -334,7 +351,9 @@ Thymeleaf can also be used to loop through objects or pass things from java side
return "new-feature"; return "new-feature";
} }
``` ```
in above example if exampleData is a list of plain java objects of class Person and within it you had id, name, age etc. You can reference it like so in above example if exampleData is a list of plain java objects of class Person and within it you had id, name, age etc. You can reference it like so
```html ```html
<tbody> <tbody>
<!-- Use th:each to iterate over the list --> <!-- Use th:each to iterate over the list -->
@@ -346,6 +365,7 @@ in above example if exampleData is a list of plain java objects of class Person
</tr> </tr>
</tbody> </tbody>
``` ```
This would generate n entries of tr for each person in exampleData This would generate n entries of tr for each person in exampleData
### Adding a New Feature to the Backend (API) ### Adding a New Feature to the Backend (API)
@@ -397,34 +417,35 @@ This would generate n entries of tr for each person in exampleData
``` ```
2b. **Integrate the Service with the Controller:** 2b. **Integrate the Service with the Controller:**
- Autowire the service class in the controller and use it to handle the API request.
```java - Autowire the service class in the controller and use it to handle the API request.
package stirling.software.SPDF.controller.api;
import org.springframework.beans.factory.annotation.Autowired; ```java
import org.springframework.web.bind.annotation.GetMapping; package stirling.software.SPDF.controller.api;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import stirling.software.SPDF.service.NewFeatureService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController import org.springframework.beans.factory.annotation.Autowired;
@RequestMapping("/api/v1/new-feature") import org.springframework.web.bind.annotation.GetMapping;
@Tag(name = "General", description = "General APIs") import org.springframework.web.bind.annotation.RequestMapping;
public class NewFeatureController { import org.springframework.web.bind.annotation.RestController;
import stirling.software.SPDF.service.NewFeatureService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@Autowired @RestController
private NewFeatureService newFeatureService; @RequestMapping("/api/v1/new-feature")
@Tag(name = "General", description = "General APIs")
public class NewFeatureController {
@GetMapping @Autowired
@Operation(summary = "New Feature", description = "This is a new feature endpoint.") private NewFeatureService newFeatureService;
public String newFeature() {
return newFeatureService.getNewFeatureData(); @GetMapping
} @Operation(summary = "New Feature", description = "This is a new feature endpoint.")
} public String newFeature() {
``` return newFeatureService.getNewFeatureData();
}
}
```
### Adding a New Feature to the Frontend (UI) ### Adding a New Feature to the Frontend (UI)
@@ -511,7 +532,6 @@ This would generate n entries of tr for each person in exampleData
</li> </li>
``` ```
## Adding New Translations to Existing Language Files in Stirling-PDF ## Adding New Translations to Existing Language Files in Stirling-PDF
When adding a new feature or modifying existing ones in Stirling-PDF, you'll need to add new translation entries to the existing language files. Here's a step-by-step guide: When adding a new feature or modifying existing ones in Stirling-PDF, you'll need to add new translation entries to the existing language files. Here's a step-by-step guide:
@@ -522,8 +542,8 @@ Find the existing `messages.properties` files in the `src/main/resources` direct
- `messages.properties` (default, usually English) - `messages.properties` (default, usually English)
- `messages_en_GB.properties` - `messages_en_GB.properties`
- `messages_fr.properties` - `messages_fr_FR.properties`
- `messages_de.properties` - `messages_de_DE.properties`
- etc. - etc.
### 2. Add New Translation Entries ### 2. Add New Translation Entries
@@ -552,6 +572,4 @@ In your Thymeleaf templates, use the `#{key}` syntax to reference the new transl
<button th:text="#{pdfSplitter.button.split}">Split PDF</button> <button th:text="#{pdfSplitter.button.split}">Split PDF</button>
``` ```
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization. Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.

View File

@@ -1,47 +1,46 @@
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript | | Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript | Unoconv | Ghostscript |
| ------------------- | ------- | ------- | -------- | ----- | --- | ------ | ------ | ----------- | -------- | ---- | ---------- | | ------------------- | ------- | ------- | -------- | ----- | --- | ------ | ------ | ----------- | -------- | ---- | ---------- | ------- | ----------- |
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ | | adjust-contrast | ✔️ | | | | | | | | | | ✔️ | | |
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | | | auto-split-pdf | ✔️ | | | | | | | | | ✔️ | | | |
| crop | ✔️ | | | | | | | | | ✔️ | | | crop | ✔️ | | | | | | | | | ✔️ | | | |
| extract-page | ✔️ | | | | | | | | | ✔️ | | | extract-page | ✔️ | | | | | | | | | ✔️ | | | |
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | | | merge-pdfs | ✔️ | | | | | | | | | ✔️ | | | |
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | | | multi-page-layout | ✔️ | | | | | | | | | ✔️ | | | |
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ | | pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ | | |
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | | | pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | | | |
| remove-pages | ✔️ | | | | | | | | | ✔️ | | | remove-pages | ✔️ | | | | | | | | | ✔️ | | | |
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | | | rotate-pdf | ✔️ | | | | | | | | | ✔️ | | | |
| scale-pages | ✔️ | | | | | | | | | ✔️ | | | scale-pages | ✔️ | | | | | | | | | ✔️ | | | |
| split-pdfs | ✔️ | | | | | | | | | ✔️ | | | split-pdfs | ✔️ | | | | | | | | | ✔️ | | | |
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | | | file-to-pdf | | ✔️ | | | ✔️ | ✔️ | | ✔️ | | | | ✔️ | |
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | | | img-to-pdf | | ✔️ | | | | | | | | ✔️ | | | |
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | | | |
| pdf-to-img | | ✔️ | | | | ✔️ | | | | ✔️ | | | pdf-to-img | | ✔️ | | | | ✔️ | | | | ✔️ | | | |
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | | | pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | | | ✔️ |
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | | | pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | | | |
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | | | |
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | | | |
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | | | |
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | | | pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | | | |
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | | | add-password | | | ✔️ | | | | | | | ✔️ | | | |
| add-password | | | ✔️ | | | | | | | ✔️ | | | add-watermark | | | ✔️ | | | | | | | ✔️ | | | |
| add-watermark | | | ✔️ | | | | | | | ✔️ | | | cert-sign | | | ✔️ | | | | | | | ✔️ | | | |
| cert-sign | | | ✔️ | | | | | | | ✔️ | | | remove-cert-sign | | | ✔️ | | | | | | | ✔️ | | | |
| remove-cert-sign | | | ✔️ | | | | | | | ✔️ | | | change-permissions | | | ✔️ | | | | | | | ✔️ | | | |
| change-permissions | | | ✔️ | | | | | | | ✔️ | | | remove-password | | | ✔️ | | | | | | | ✔️ | | | |
| remove-password | | | ✔️ | | | | | | | ✔️ | | | sanitize-pdf | | | ✔️ | | | | | | | ✔️ | | | |
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | | | add-image | | | | ✔️ | | | | | | ✔️ | | | |
| add-image | | | | ✔️ | | | | | | ✔️ | | | add-page-numbers | | | | ✔️ | | | | | | ✔️ | | | |
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | | | auto-rename | | | | ✔️ | | | | | | ✔️ | | | |
| auto-rename | | | | ✔️ | | | | | | ✔️ | | | change-metadata | | | | ✔️ | | | | | | ✔️ | | | |
| change-metadata | | | | ✔️ | | | | | | ✔️ | | | compare | | | | ✔️ | | | | | | | ✔️ | | |
| compare | | | | ✔️ | | | | | | | ✔️ | | compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | ✔️ |
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | |
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | extract-images | | | | ✔️ | | | | | | ✔️ | | | |
| extract-images | | | | ✔️ | | | | | | ✔️ | | | flatten | | | | ✔️ | | | | | | | ✔️ | | |
| flatten | | | | ✔️ | | | | | | | ✔️ | | get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | | | |
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | | | ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | |
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | | | remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | |
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | | | repair | | | | ✔️ | ✔️ | | | ✔️ | | | | | ✔️ |
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | | | show-javascript | | | | ✔️ | | | | | | | ✔️ | | |
| show-javascript | | | | ✔️ | | | | | | | ✔️ | | sign | | | | ✔️ | | | | | | | ✔️ | | |
| sign | | | | ✔️ | | | | | | | ✔️ |

View File

@@ -1,33 +1,41 @@
## User Guide for Local Directory Scanning and File Processing ## User Guide for Local Directory Scanning and File Processing
### Setting Up Watched Folders: ### Setting Up Watched Folders
- Create a folder where you want your files to be monitored. This is your 'watched folder'. - Create a folder where you want your files to be monitored. This is your 'watched folder'.
- The default directory for this is `./pipeline/watchedFolders/` - The default directory for this is `./pipeline/watchedFolders/`.
- Place any directories you want to be scanned into this folder, this folder should contain multiple folders each for their own tasks and pipelines. - Place any directories you want to be scanned into this folder. This folder should contain multiple folders, each for their own tasks and pipelines.
### Configuring Processing with JSON Files: ### Configuring Processing with JSON Files
- In each directory you want processed (e.g `./pipeline/watchedFolders/officePrinter`), include a JSON configuration file.
- This JSON file should specify how you want the files in the directory to be handled (e.g., what operations to perform on them) which can be made, configured and downloaded from Stirling-PDF Pipeline interface.r - In each directory you want processed (e.g., `./pipeline/watchedFolders/officePrinter`), include a JSON configuration file.
- This JSON file should specify how you want the files in the directory to be handled (e.g., what operations to perform on them). This can be made, configured, and downloaded from the Stirling-PDF Pipeline interface.
### Automatic Scanning and Processing
### Automatic Scanning and Processing:
- The system automatically checks the watched folder every minute for new directories and files to process. - The system automatically checks the watched folder every minute for new directories and files to process.
- When a directory with a valid JSON configuration file is found, it begins processing the files inside as per the configuration. - When a directory with a valid JSON configuration file is found, it begins processing the files inside according to the configuration.
### Processing Steps
### Processing Steps:
- Files in each directory are processed according to the instructions in the JSON file. - Files in each directory are processed according to the instructions in the JSON file.
- This might involve file conversions, data filtering, renaming files, etc. If the output of a step is a zip, this zip will be automatically unzipped as it passes to next process. - This might involve file conversions, data filtering, renaming files, etc. If the output of a step is a zip, this zip will be automatically unzipped as it passes to the next process.
### Results and Output
### Results and Output:
- After processing, the results are saved in a specified output location. This could be a different folder or location as defined in the JSON file or the default location `./pipeline/finishedFolders/`. - After processing, the results are saved in a specified output location. This could be a different folder or location as defined in the JSON file or the default location `./pipeline/finishedFolders/`.
- Each processed file is named and organized according to the rules set in the JSON configuration. - Each processed file is named and organized according to the rules set in the JSON configuration.
### Completion and Cleanup: ### Completion and Cleanup
- Once processing is complete, the original files in the watched folder's directory are removed. - Once processing is complete, the original files in the watched folder's directory are removed.
- You can find the processed files in the designated output location. - You can find the processed files in the designated output location.
### Error Handling: ### Error Handling
- If there's an error during processing, the system will not delete the original files, allowing you to check and retry if necessary. - If there's an error during processing, the system will not delete the original files, allowing you to check and retry if necessary.
### User Interaction: ### User Interaction
- As a user, your main tasks are to set up the watched folders, place directories with files for processing, and create the corresponding JSON configuration files. - As a user, your main tasks are to set up the watched folders, place directories with files for processing, and create the corresponding JSON configuration files.
- The system handles the rest, including scanning, processing, and outputting results. - The system handles the rest, including scanning, processing, and outputting results.

View File

@@ -1,43 +1,47 @@
<p align="center"><img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80" ><br><h1 align="center">Stirling-PDF</h1> <p align="center">
<img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80">
<br>
<h1 align="center">Stirling-PDF</h1>
</p> </p>
# How to add new languages to Stirling-PDF # How to add new languages to Stirling-PDF
Fork Stirling-PDF and make a new branch out of Main Fork Stirling-PDF and create a new branch out of `main`.
Then add reference to the language in the navbar by adding a new language entry to the dropdown Then add a reference to the language in the navbar by adding a new language entry to the dropdown:
https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html - Edit the file: [languages.html](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html)
and add a flag svg file to - Add a flag SVG file to: [flags directory](https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags)
https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags
Any SVG flags are fine, i got most of mine from [here](https://flagicons.lipis.dev/)
If your language isn't represented by a flag just find whichever closely matches it, such as for Arabic i chose Saudi Arabia
For example to add Polish you would add Any SVG flags are fine; most of the current ones were sourced from [here](https://flagicons.lipis.dev/). If your language isn't represented by a flag, choose a similar one, such as Saudi Arabia's flag for Arabic.
For example, to add Polish, you would add:
```html ```html
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="pl_PL"> <a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL">
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski <img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
</a> </a>
``` ```
The data-language-code is the code used to reference the file in the next step. The `data-bs-language-code` is the code used to reference the file in the next step.
Start by copying the existing english property file ### Add Language Property File
[https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties) Start by copying the existing English property file:
Copy and rename it to messages_{your data-language-code here}.properties, in the polish example you would set the name to messages_pl_PL.properties - [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties)
Then simply translate all property entries within that file and make a PR into main for others to use! Copy and rename it to `messages_{your data-bs-language-code here}.properties`. In the Polish example, you would set the name to `messages_pl_PL.properties`.
If you do not have a java IDE i am happy to verify the changes worked once you raise PR (but won't be able to verify the translations themselves) Then simply translate all property entries within that file and make a Pull Request (PR) into `main` for others to use!
If you do not have a Java IDE, I am happy to verify that the changes work once you raise the PR (but I won't be able to verify the translations themselves).
## Handling Untranslatable Strings ## Handling Untranslatable Strings
Sometimes, certain strings in the properties file may not require translation because they are the same in the target language or are universal (like names of protocols, certain terminologies, etc.). To ensure accurate statistics for language progress, these strings should be added to the `ignore_translation.toml` file located in the `scripts` directory. This will exclude them from the translation progress calculations. Sometimes, certain strings in the properties file may not require translation because they are the same in the target language or are universal (like names of protocols, certain terminologies, etc.). To ensure accurate statistics for language progress, these strings should be added to the `ignore_translation.toml` file located in the `scripts` directory. This will exclude them from the translation progress calculations.
For example, if the English string error=Error does not need translation in Polish, add it to the ignore_translation.toml under the Polish section: For example, if the English string `error=Error` does not need translation in Polish, add it to the `ignore_translation.toml` under the Polish section:
```toml ```toml
[pl_PL] [pl_PL]
@@ -49,7 +53,9 @@ ignore = [
## Add New Translation Tags ## Add New Translation Tags
- **Important**: If you add any new translation tags, they must first be added to the `messages_en_GB.properties` file. This ensures consistency across all language files. > [!IMPORTANT]
> If you add any new translation tags, they must first be added to the `messages_en_GB.properties` file. This ensures consistency across all language files.
- New translation tags **must be added** to the `messages_en_GB.properties` file to maintain a reference for other languages. - New translation tags **must be added** to the `messages_en_GB.properties` file to maintain a reference for other languages.
- After adding the new tags to `messages_en_GB.properties`, add and translate them in the respective language file (e.g., `messages_pl_PL.properties`). - After adding the new tags to `messages_en_GB.properties`, add and translate them in the respective language file (e.g., `messages_pl_PL.properties`).

View File

@@ -3,34 +3,36 @@
This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker. This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker.
## My OCR used to work and now doesn't! ## My OCR used to work and now doesn't!
The paths have changed for the tessadata locations on new docker images, please use ``/usr/share/tessdata`` (Others should still work for backwards compatibility but might not)
The paths have changed for the tessdata locations on new Docker images. Please use `/usr/share/tessdata` (Others should still work for backward compatibility but might not).
## How does the OCR Work ## How does the OCR Work
Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition.
All credit goes to them for this awesome work! Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF), which in turn uses Tesseract for its text recognition. All credit goes to them for this awesome work!
## Language Packs ## Language Packs
Tesseract OCR supports a variety of languages. You can find additional language packs in the Tesseract GitHub repositories: Tesseract OCR supports a variety of languages. You can find additional language packs in the Tesseract GitHub repositories:
- [tessdata_fast](https://github.com/tesseract-ocr/tessdata_fast): These language packs are smaller and faster to load, but may provide lower recognition accuracy. - [tessdata_fast](https://github.com/tesseract-ocr/tessdata_fast): These language packs are smaller and faster to load but may provide lower recognition accuracy.
- [tessdata](https://github.com/tesseract-ocr/tessdata): These language packs are larger and provide better recognition accuracy, but may take longer to load. - [tessdata](https://github.com/tesseract-ocr/tessdata): These language packs are larger and provide better recognition accuracy, but may take longer to load.
Depending on your requirements, you can choose the appropriate language pack for your use case. By default Stirling-PDF uses the tessdata_fast eng but this can be replaced. Depending on your requirements, you can choose the appropriate language pack for your use case. By default, Stirling-PDF uses `tessdata_fast` for English, but this can be replaced.
### Installing Language Packs ### Installing Language Packs
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need. 1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata` 2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata`
# DO NOT REMOVE EXISTING ENG.TRAINEDDATA, IT'S REQUIRED. **DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED.**
#### Docker ### Docker Setup
If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs. If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs.
#### Docker Compose
Modify your `docker-compose.yml` file to include the following volume configuration:
#### Docker Compose
Modify your `docker-compose.yml` file to include the following volume configuration:
```yaml ```yaml
services: services:
@@ -40,18 +42,19 @@ services:
- /location/of/trainingData:/usr/share/tessdata - /location/of/trainingData:/usr/share/tessdata
``` ```
#### Docker Run
Add the following to your existing Docker run command:
#### Docker run
Add the following to your existing docker run command
```bash ```bash
-v /location/of/trainingData:/usr/share/tessdata -v /location/of/trainingData:/usr/share/tessdata
``` ```
#### Non-Docker ### Non-Docker Setup
If you are not using Docker, you need to install the OCR components, including the ocrmypdf app.
You can see [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html)
Debian based systems, install languages with this command: If you are not using Docker, you need to install the OCR components, including the `ocrmypdf` app. You can see the [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html).
For Debian-based systems, install languages with this command:
```bash ```bash
sudo apt update &&\ sudo apt update &&\
@@ -65,7 +68,7 @@ apt search tesseract-ocr-
dpkg-query -W tesseract-ocr- | sed 's/tesseract-ocr-//g' dpkg-query -W tesseract-ocr- | sed 's/tesseract-ocr-//g'
``` ```
Fedora: For Fedora:
```bash ```bash
# All languages # All languages
@@ -77,3 +80,23 @@ dnf search -C tesseract-langpack-
# View installed languages: # View installed languages:
rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g' rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g'
``` ```
For Windows:
Ensure ocrmypdf in installed with
``pip install ocrmypdf``
Additional languages must be downloaded manually:
Download desired .traineddata files from tessdata or tessdata_fast
Place them in the tessdata folder within your Tesseract installation directory
(e.g., C:\Program Files\Tesseract-OCR\tessdata)
Verify installation:
``tesseract --list-langs``
You must then edit your ``/configs/settings.yml`` and change the system.tessdataDir to match the directory containing lang files
```
system:
tessdataDir: C:/Program Files/Tesseract-OCR/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
```

View File

@@ -1,48 +1,35 @@
To run the application without Docker/Podman, you will need to manually install all dependencies and build the necessary components. To run the application without Docker/Podman, you will need to manually install all dependencies and build the necessary components.
Note that some dependencies might not be available in the standard repositories of all Linux distributions, and may require additional steps to install. Note that some dependencies might not be available in the standard repositories of all Linux distributions, and may require additional steps to install.
The following guide assumes you have a basic understanding of using a command line interface in your operating system. The following guide assumes you have a basic understanding of using a command line interface in your operating system.
It should work on most Linux distributions and MacOS. For Windows, you might need to use Windows Subsystem for Linux (WSL) for certain steps. It should work on most Linux distributions and MacOS. For Windows, you might need to use Windows Subsystem for Linux (WSL) for certain steps. The amount of dependencies is to actually reduce overall size, i.e., installing LibreOffice subcomponents rather than the full LibreOffice package.
The amount of dependencies is to actually reduce overall size, ie installing LibreOffice sub components rather than full LibreOffice package.
You could theoretically use a Distrobox/Toolbox, if your Distribution has old or not all Packages. But you might just as well use the Docker Container then. You could theoretically use a Distrobox/Toolbox if your distribution has old or not all packages. But you might just as well use the Docker container then.
### Step 1: Prerequisites ### Step 1: Prerequisites
Install the following software, if not already installed: Install the following software, if not already installed:
- Java 17 or later (21 recommended) - Java 17 or later (21 recommended)
- Gradle 7.0 or later (included within repo so not needed on server) - Gradle 7.0 or later (included within repo so not needed on server)
- Git - Git
- Python 3.8 (with pip) - Python 3.8 (with pip)
- Make - Make
- GCC/G++ - GCC/G++
- Automake - Automake
- Autoconf - Autoconf
- libtool - libtool
- pkg-config - pkg-config
- zlib1g-dev - zlib1g-dev
- libleptonica-dev - libleptonica-dev
For Debian-based systems, you can use the following command: For Debian-based systems, you can use the following command:
```bash ```bash
sudo apt-get update sudo apt-get update
sudo apt-get install -y git automake autoconf libtool libleptonica-dev pkg-config zlib1g-dev make g++ openjdk-21-jdk python3 python3-pip sudo apt-get install -y git automake autoconf libtool libleptonica-dev pkg-config zlib1g-dev make g++ openjdk-21-jdk python3 python3-pip
``` ```
For Fedora-based systems use this command: For Fedora-based systems use this command:
@@ -52,6 +39,7 @@ sudo dnf install -y git automake autoconf libtool leptonica-devel pkg-config zli
``` ```
For non-root users with Nix Package Manager, use the following command: For non-root users with Nix Package Manager, use the following command:
```bash ```bash
nix-channel --update nix-channel --update
nix-env -iA nixpkgs.jdk21 nixpkgs.git nixpkgs.python38 nixpkgs.gnumake nixpkgs.libgcc nixpkgs.automake nixpkgs.autoconf nixpkgs.libtool nixpkgs.pkg-config nixpkgs.zlib nixpkgs.leptonica nix-env -iA nixpkgs.jdk21 nixpkgs.git nixpkgs.python38 nixpkgs.gnumake nixpkgs.libgcc nixpkgs.automake nixpkgs.autoconf nixpkgs.libtool nixpkgs.pkg-config nixpkgs.zlib nixpkgs.leptonica
@@ -63,45 +51,37 @@ For Debian and Fedora, you can build it from source using the following commands
```bash ```bash
mkdir ~/.git mkdir ~/.git
cd ~/.git &&\ cd ~/.git && \
git clone https://github.com/agl/jbig2enc.git &&\ git clone https://github.com/agl/jbig2enc.git && \
cd jbig2enc &&\ cd jbig2enc && \
./autogen.sh &&\ ./autogen.sh && \
./configure &&\ ./configure && \
make &&\ make && \
sudo make install sudo make install
``` ```
For Nix, you will face `Leptonica not detected`. Bypass this by installing it directly using the following command: For Nix, you will face `Leptonica not detected`. Bypass this by installing it directly using the following command:
```bash ```bash
nix-env -iA nixpkgs.jbig2enc nix-env -iA nixpkgs.jbig2enc
``` ```
### Step 3: Install Additional Software ### Step 3: Install Additional Software
Next we need to install LibreOffice for conversions, ocrmypdf for OCR, and opencv for pattern recognition functionality.
Next we need to install LibreOffice for conversions, ocrmypdf for OCR, and OpenCV for pattern recognition functionality.
Install the following software: Install the following software:
- libreoffice-core - libreoffice-core
- libreoffice-common - libreoffice-common
- libreoffice-writer - libreoffice-writer
- libreoffice-calc - libreoffice-calc
- libreoffice-impress - libreoffice-impress
- python3-uno - python3-uno
- unoconv - unoconv
- pngquant - pngquant
- unpaper - unpaper
- ocrmypdf - ocrmypdf
- opencv-python-headless - opencv-python-headless
For Debian-based systems, you can use the following command: For Debian-based systems, you can use the following command:
@@ -128,51 +108,52 @@ pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
### Step 4: Clone and Build Stirling-PDF ### Step 4: Clone and Build Stirling-PDF
```bash ```bash
cd ~/.git &&\ cd ~/.git && \
git clone https://github.com/Stirling-Tools/Stirling-PDF.git &&\ git clone https://github.com/Stirling-Tools/Stirling-PDF.git && \
cd Stirling-PDF &&\ cd Stirling-PDF && \
chmod +x ./gradlew &&\ chmod +x ./gradlew && \
./gradlew build ./gradlew build
``` ```
### Step 5: Move jar to desired location ### Step 5: Move Jar to Desired Location
After the build process, a `.jar` file will be generated in the `build/libs` directory. After the build process, a `.jar` file will be generated in the `build/libs` directory. You can move this file to a desired location, for example, `/opt/Stirling-PDF/`. You must also move the Script folder within the Stirling-PDF repo that you have downloaded to this directory. This folder is required for the Python scripts using OpenCV.
You can move this file to a desired location, for example, `/opt/Stirling-PDF/`.
You must also move the Script folder within the Stirling-PDF repo that you have downloaded to this directory.
This folder is required for the python scripts using OpenCV.
```bash ```bash
sudo mkdir /opt/Stirling-PDF &&\ sudo mkdir /opt/Stirling-PDF && \
sudo mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ &&\ sudo mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ && \
sudo mv scripts /opt/Stirling-PDF/ &&\ sudo mv scripts /opt/Stirling-PDF/ && \
echo "Scripts installed." echo "Scripts installed."
``` ```
For non-root users, you can just keep the jar in the main directory of Stirling-PDF using the following command: For non-root users, you can just keep the jar in the main directory of Stirling-PDF using the following command:
```bash ```bash
mv ./build/libs/Stirling-PDF-*.jar ./Stirling-PDF-*.jar mv ./build/libs/Stirling-PDF-*.jar ./Stirling-PDF-*.jar
``` ```
### Step 6: Other files ### Step 6: Other Files
#### OCR #### OCR
If you plan to use the OCR (Optical Character Recognition) functionality, you might need to install language packs for Tesseract if running non-english scanning.
If you plan to use the OCR (Optical Character Recognition) functionality, you might need to install language packs for Tesseract if running non-English scanning.
##### Installing Language Packs ##### Installing Language Packs
Easiest is to use the langpacks provided by your repositories. Skip the other steps.
Manual: The easiest method is to use the language packs provided by your repositories. Skip the other steps if they are available.
**Manual:**
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need. 1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata` 2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata`
3. Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info. 3. Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info.
**IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED. **IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED.
Debian based systems, install languages with this command: **Debian-based systems**, install languages with this command:
```bash ```bash
sudo apt update &&\ sudo apt update && \
# All languages # All languages
# sudo apt install -y 'tesseract-ocr-*' # sudo apt install -y 'tesseract-ocr-*'
@@ -183,7 +164,7 @@ apt search tesseract-ocr-
dpkg-query -W tesseract-ocr- | sed 's/tesseract-ocr-//g' dpkg-query -W tesseract-ocr- | sed 's/tesseract-ocr-//g'
``` ```
Fedora: **Fedora:**
```bash ```bash
# All languages # All languages
@@ -196,13 +177,13 @@ dnf search -C tesseract-langpack-
rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g' rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g'
``` ```
Nix: **Nix:**
```bash ```bash
nix-env -iA nixpkgs.tesseract nix-env -iA nixpkgs.tesseract
``` ```
**Note:** Nix Package Manager pre-installs almost all the language packs when tesseract is installed. **Note:** Nix Package Manager pre-installs almost all the language packs when Tesseract is installed.
### Step 7: Run Stirling-PDF ### Step 7: Run Stirling-PDF
@@ -214,11 +195,13 @@ or
java -jar /opt/Stirling-PDF/Stirling-PDF-*.jar java -jar /opt/Stirling-PDF/Stirling-PDF-*.jar
``` ```
Since libreoffice, soffice, and conversion tools have their dbus_tmp_dir set as `dbus_tmp_dir="/run/user/$(id -u)/libreoffice-dbus"`, you might get the following error when using their endpoints: Since LibreOffice, soffice, and conversion tools have their dbus_tmp_dir set as `dbus_tmp_dir="/run/user/$(id -u)/libreoffice-dbus"`, you might get the following error when using their endpoints:
``` ```
[Thread-7] INFO s.s.SPDF.utils.ProcessExecutor - mkdir: cannot create directory /run/user/1501: Permission denied [Thread-7] INFO s.s.SPDF.utils.ProcessExecutor - mkdir: cannot create directory /run/user/1501: Permission denied
``` ```
To resolve this, before starting the Stirling-PDF, you have to set the environment variable to a directory you have write access to by using the following commands:
To resolve this, before starting Stirling-PDF, you have to set the environment variable to a directory you have write access to by using the following commands:
```bash ```bash
mkdir temp mkdir temp
@@ -228,9 +211,10 @@ or
java -jar ./Stirling-PDF-*.jar java -jar ./Stirling-PDF-*.jar
``` ```
### Step 8: Adding a Desktop icon ### Step 8: Adding a Desktop Icon
This will add a modified app starter to your app menu.
This will add a modified Appstarter to your Appmenu.
```bash ```bash
location=$(pwd)/gradlew location=$(pwd)/gradlew
image=$(pwd)/docs/stirling-transparent.svg image=$(pwd)/docs/stirling-transparent.svg
@@ -251,35 +235,40 @@ EOF
Note: Currently the app will run in the background until manually closed. Note: Currently the app will run in the background until manually closed.
### Optional: Changing the host and port of the application: ### Optional: Changing the Host and Port of the Application
To override the default configuration, you can add the following to `/.git/Stirling-PDF/configs/custom_settings.yml` file: To override the default configuration, you can add the following to `/.git/Stirling-PDF/configs/custom_settings.yml` file:
```bash ```yaml
server: server:
host: 0.0.0.0 # Not working - use instead address host: 0.0.0.0 # Not working - use instead address
address: 0.0.0.0 address: 0.0.0.0
port: 3000 port: 3000
``` ```
'-Djava.net.preferIPv4Stack=true' --> To force ipv4 only in the java starting command
`-Djava.net.preferIPv4Stack=true` --> To force IPv4 only in the Java starting command
**Note:** This file is created after the first application launch. To have it before that, you can create the directory and add the file yourself. **Note:** This file is created after the first application launch. To have it before that, you can create the directory and add the file yourself.
### Optional: Run Stirling-PDF as a service (requires root). ### Optional: Run Stirling-PDF as a Service (requires root)
First create a .env file, where you can store environment variables: First create a `.env` file, where you can store environment variables:
```
```bash
touch /opt/Stirling-PDF/.env touch /opt/Stirling-PDF/.env
``` ```
In this file you can add all variables, one variable per line, as stated in the main readme (for example SYSTEM_DEFAULTLOCALE="de-DE").
Create a new file where we store our service settings and open it with nano editor: In this file, you can add all variables, one variable per line, as stated in the main readme (for example `SYSTEM_DEFAULTLOCALE="de-DE"`).
```
Create a new file where we store our service settings and open it with the nano editor:
```bash
nano /etc/systemd/system/stirlingpdf.service nano /etc/systemd/system/stirlingpdf.service
``` ```
Paste this content, make sure to update the filename of the jar-file. Press Ctrl+S and Ctrl+X to save and exit the nano editor: Paste this content, make sure to update the filename of the jar file. Press `Ctrl+S` and `Ctrl+X` to save and exit the nano editor:
```
```ini
[Unit] [Unit]
Description=Stirling-PDF service Description=Stirling-PDF service
After=syslog.target network.target After=syslog.target network.target
@@ -303,22 +292,25 @@ WantedBy=multi-user.target
Notify systemd that it has to rebuild its internal service database (you have to run this command every time you make a change in the service file): Notify systemd that it has to rebuild its internal service database (you have to run this command every time you make a change in the service file):
``` ```bash
sudo systemctl daemon-reload sudo systemctl daemon-reload
``` ```
Enable the service to tell the service to start it automatically: Enable the service to tell it to start automatically:
```
```bash
sudo systemctl enable stirlingpdf.service sudo systemctl enable stirlingpdf.service
``` ```
See the status of the service: See the status of the service:
```
```bash
sudo systemctl status stirlingpdf.service sudo systemctl status stirlingpdf.service
``` ```
Manually start/stop/restart the service: Manually start/stop/restart the service:
```
```bash
sudo systemctl start stirlingpdf.service sudo systemctl start stirlingpdf.service
sudo systemctl stop stirlingpdf.service sudo systemctl stop stirlingpdf.service
sudo systemctl restart stirlingpdf.service sudo systemctl restart stirlingpdf.service
@@ -326,12 +318,11 @@ sudo systemctl restart stirlingpdf.service
--- ---
Remember to set the necessary environment variables before running the project if you want to customize the application the list can be seen in the main readme. Remember to set the necessary environment variables before running the project if you want to customize the application. The list can be seen in the main readme.
You can do this in the terminal by using the `export` command or -D argument to java -jar command: You can do this in the terminal by using the `export` command or `-D` argument to the Java `-jar` command:
```bash ```bash
export APP_HOME_NAME="Stirling PDF" export APP_HOME_NAME="Stirling PDF"
or or
-DAPP_HOME_NAME="Stirling PDF" -DAPP_HOME_NAME="Stirling PDF"
```

View File

@@ -1,6 +1,7 @@
# Pipeline Configuration and Usage Tutorial # Pipeline Configuration and Usage Tutorial
- Configure the pipeline config file and input files to run files against it
- For reuse, download the config file and re-upload it when needed, or place it in /pipeline/defaultWebUIConfigs/ to auto-load in the web UI for all users - Configure the pipeline config file and input files to run files against it.
- For reuse, download the config file and re-upload it when needed, or place it in `/pipeline/defaultWebUIConfigs/` to auto-load in the web UI for all users.
## Steps to Configure and Use Your Pipeline ## Steps to Configure and Use Your Pipeline
@@ -26,19 +27,16 @@
- Use the **Validation** button to check your pipeline. A green indicator signifies correct setup; a pop-out error indicates issues. - Use the **Validation** button to check your pipeline. A green indicator signifies correct setup; a pop-out error indicates issues.
8. **Download Pipeline Configuration** 8. **Download Pipeline Configuration**
- To use the configuration for folder scanning (or save it for future use and reupload it), you can also download a JSON file in this menu. You can also pre-load this for future use by placing it in ``/pipeline/defaultWebUIConfigs/``. It will then appear in the dropdown menu for all users to use. - To use the configuration for folder scanning (or save it for future use and re-upload it), download a JSON file in this menu. You can also pre-load it for future use by placing it in `/pipeline/defaultWebUIConfigs/`. It will then appear in the dropdown menu for all users to use.
9. **Submit Files for Processing** 9. **Submit Files for Processing**
- If your pipeline is correctly set up close the configure menu, input the files and hit **Submit**. - If your pipeline is correctly set up, close the configure menu, input the files, and hit **Submit**.
10. **Note on Web UI Limitations** 10. **Note on Web UI Limitations**
- The current web UI version does not support operations that require multiple different types of inputs, such as adding a separate image to a PDF. - The current web UI version does not support operations that require multiple different types of inputs, such as adding a separate image to a PDF.
### Current Limitations ### Current Limitations
- Cannot have more than one of the same operation
- Cannot input additional files via UI
- All files and operations run in serial mode
- Cannot have more than one of the same operation.
- Cannot input additional files via UI.
- All files and operations run in serial mode.

440
README.md
View File

@@ -1,4 +1,4 @@
<p align="center"><img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80" ></p> <p align="center"><img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80"></p>
<h1 align="center">Stirling-PDF</h1> <h1 align="center">Stirling-PDF</h1>
[![Docker Pulls](https://img.shields.io/docker/pulls/frooodle/s-pdf)](https://hub.docker.com/r/frooodle/s-pdf) [![Docker Pulls](https://img.shields.io/docker/pulls/frooodle/s-pdf)](https://hub.docker.com/r/frooodle/s-pdf)
@@ -7,11 +7,10 @@
[![GitHub Repo stars](https://img.shields.io/github/stars/stirling-tools/stirling-pdf?style=social)](https://github.com/Stirling-Tools/stirling-pdf) [![GitHub Repo stars](https://img.shields.io/github/stars/stirling-tools/stirling-pdf?style=social)](https://github.com/Stirling-Tools/stirling-pdf)
[![Deploy to DO](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/Stirling-Tools/Stirling-PDF/tree/digitalOcean&refcode=c3210994b1af) [![Deploy to DO](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/Stirling-Tools/Stirling-PDF/tree/digitalOcean&refcode=c3210994b1af)
[<img src="https://www.ssdnodes.com/wp-content/uploads/2023/11/footer-logo.svg" alt="Name" height="40">](https://www.ssdnodes.com/manage/aff.php?aff=2216&register=true)
This is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements. [Stirling-PDF](https://www.stirlingpdf.com) is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements.
Stirling PDF does not initiate any outbound calls for record-keeping or tracking purposes. Stirling-PDF does not initiate any outbound calls for record-keeping or tracking purposes.
All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point. All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.
@@ -19,7 +18,8 @@ All files and PDFs exist either exclusively on the client side, reside in server
## Features ## Features
- Dark mode support. - Enterprise features like SSO Check [here](https://docs.stirlingpdf.com/Enterprise%20Edition)
- Dark mode support
- Custom download options - Custom download options
- Parallel file processing and downloads - Parallel file processing and downloads
- Custom 'Pipelines' to run multiple features in a queue - Custom 'Pipelines' to run multiple features in a queue
@@ -27,68 +27,76 @@ All files and PDFs exist either exclusively on the client side, reside in server
- Optional Login and Authentication support (see [here](https://github.com/Stirling-Tools/Stirling-PDF/tree/main#login-authentication) for documentation) - Optional Login and Authentication support (see [here](https://github.com/Stirling-Tools/Stirling-PDF/tree/main#login-authentication) for documentation)
- Database Backup and Import (see [here](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DATABASE.md) for documentation) - Database Backup and Import (see [here](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DATABASE.md) for documentation)
## **PDF Features**
### **Page Operations** ## PDF Features
- View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts) ### Page Operations
- Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.
- Merge multiple PDFs together into a single resultant file.
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
- Reorganize PDF pages into different orders.
- Rotate PDFs in 90-degree increments.
- Remove pages.
- Multi-page layout (Format PDFs into a multi-paged page).
- Scale page contents size by set %.
- Adjust Contrast.
- Crop PDF.
- Auto Split PDF (With physically scanned page dividers).
- Extract page(s).
- Convert PDF to a single page.
- Overlay PDFs ontop of each other
### **Conversion Operations** - View and modify PDFs - View multi-page PDFs with custom viewing, sorting, and searching. Plus on-page edit features like annotate, draw, and adding text and images. (Using PDF.js with Joxit and Liberation fonts)
- Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages
- Merge multiple PDFs into a single resultant file
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files
- Reorganize PDF pages into different orders
- Rotate PDFs in 90-degree increments
- Remove pages
- Multi-page layout (format PDFs into a multi-paged page)
- Scale page contents size by set percentage
- Adjust contrast
- Crop PDF
- Auto split PDF (with physically scanned page dividers)
- Extract page(s)
- Convert PDF to a single page
- Overlay PDFs on top of each other
- PDF to single page
- Split PDF by sections
- Convert PDFs to and from images. ### Conversion Operations
- Convert any common file to PDF (using LibreOffice).
- Convert PDF to Word/Powerpoint/Others (using LibreOffice).
- Convert HTML to PDF.
- URL to PDF.
- Markdown to PDF.
### **Security & Permissions** - Convert PDFs to and from images
- Convert any common file to PDF (using LibreOffice)
- Convert PDF to Word/PowerPoint/others (using LibreOffice)
- Convert HTML to PDF
- Convert PDF to xml
- Convert PDF to CSV
- URL to PDF
- Markdown to PDF
- Add and remove passwords. ### Security & Permissions
- Change/set PDF Permissions.
- Add watermark(s).
- Certify/sign PDFs.
- Sanitize PDFs.
- Auto-redact text.
### **Other Operations** - Add and remove passwords
- Change/set PDF permissions
- Add watermark(s)
- Certify/sign PDFs
- Sanitize PDFs
- Auto-redact text
- Add/Generate/Write signatures. ### Other Operations
- Repair PDFs.
- Detect and remove blank pages.
- Compare 2 PDFs and show differences in text.
- Add images to PDFs.
- Compress PDFs to decrease their filesize (Using OCRMyPDF).
- Extract images from PDF.
- Extract images from Scans.
- Add page numbers.
- Auto rename file by detecting PDF header text.
- OCR on PDF (Using OCRMyPDF).
- PDF/A conversion (Using OCRMyPDF).
- Edit metadata.
- Flatten PDFs.
- Get all information on a PDF to view or export as JSON.
- Show/Detect embedded Javascript
For a overview of the tasks and the technology each uses please view [Endpoint-groups.md](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md) - Add/generate/write signatures
- Split by Size or PDF
- Repair PDFs
- Detect and remove blank pages
- Compare two PDFs and show differences in text
- Add images to PDFs
- Compress PDFs to decrease their filesize (using OCRMyPDF)
- Extract images from PDF
- Remove images from PDF
- Extract images from scans
- Remove annotations
- Add page numbers
- Auto rename file by detecting PDF header text
- OCR on PDF (using OCRMyPDF)
- PDF/A conversion (using OCRMyPDF)
- Edit metadata
- Flatten PDFs
- Get all information on a PDF to view or export as JSON
- Show/detect embedded JavaScript
Demo of the app is available [here](https://stirlingpdf.io). For an overview of the tasks and the technology each uses, please view [Endpoint-groups.md](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md).
## Technologies used A demo of the app is available [here](https://stirlingpdf.io).
## Technologies Used
- Spring Boot + Thymeleaf - Spring Boot + Thymeleaf
- [PDFBox](https://github.com/apache/pdfbox/tree/trunk) - [PDFBox](https://github.com/apache/pdfbox/tree/trunk)
@@ -99,27 +107,28 @@ Demo of the app is available [here](https://stirlingpdf.io).
- [PDF.js](https://github.com/mozilla/pdf.js) - [PDF.js](https://github.com/mozilla/pdf.js)
- [PDF-LIB.js](https://github.com/Hopding/pdf-lib) - [PDF-LIB.js](https://github.com/Hopding/pdf-lib)
## How to use ## How to Use
### Windows ### Windows
For windows users download the latest Stirling-PDF.exe from our [release](https://github.com/Stirling-Tools/Stirling-PDF/releases) section or by clicking [here](https://github.com/Stirling-Tools/Stirling-PDF/releases/latest/download/Stirling-PDF.exe)
For Windows users, download the latest Stirling-PDF.exe from our [release](https://github.com/Stirling-Tools/Stirling-PDF/releases) section or by clicking [here](https://github.com/Stirling-Tools/Stirling-PDF/releases/latest/download/Stirling-PDF.exe).
### Locally ### Locally
Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md Please view the [LocalRunGuide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/LocalRunGuide.md).
### Docker / Podman ### Docker / Podman
https://hub.docker.com/r/frooodle/s-pdf > [!NOTE]
> <https://hub.docker.com/r/frooodle/s-pdf>
Stirling-PDF has three different versions: a full version, an ultra-lite version, and a 'fat' version. Depending on the types of features you use, you may want a smaller image to save on space. To see what the different versions offer, please look at our [version mapping](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Version-groups.md). For people that don't mind space optimization, just use the latest tag.
Stirling PDF has 3 different versions, a Full version and ultra-Lite version as well as a 'Fat' version. Depending on the types of features you use you may want a smaller image to save on space.
To see what the different versions offer please look at our [version mapping](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Version-groups.md)
For people that don't mind about space optimization just use the latest tag.
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest?label=Stirling-PDF%20Full) ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest?label=Stirling-PDF%20Full)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest-ultra-lite?label=Stirling-PDF%20Ultra-Lite) ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest-ultra-lite?label=Stirling-PDF%20Ultra-Lite)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest-fat?label=Stirling-PDF%20Fat) ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/frooodle/s-pdf/latest-fat?label=Stirling-PDF%20Fat)
Please note in below examples you may need to change the volume paths as needed, current examples install them to the current working directory Please note in the examples below, you may need to change the volume paths as needed, e.g., `./extraConfigs:/configs` to `/opt/stirlingpdf/extraConfigs:/configs`.
eg ``./extraConfigs:/configs`` to ``/opt/stirlingpdf/extraConfigs:/configs``
### Docker Run ### Docker Run
@@ -129,15 +138,13 @@ docker run -d \
-v ./trainingData:/usr/share/tessdata \ -v ./trainingData:/usr/share/tessdata \
-v ./extraConfigs:/configs \ -v ./extraConfigs:/configs \
-v ./logs:/logs \ -v ./logs:/logs \
# Optional customization (not required)
# -v /location/of/customFiles:/customFiles \
-e DOCKER_ENABLE_SECURITY=false \ -e DOCKER_ENABLE_SECURITY=false \
-e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \ -e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
-e LANGS=en_GB \ -e LANGS=en_GB \
--name stirling-pdf \ --name stirling-pdf \
frooodle/s-pdf:latest frooodle/s-pdf:latest
Can also add these for customisation but are not required
-v /location/of/customFiles:/customFiles \
``` ```
### Docker Compose ### Docker Compose
@@ -150,7 +157,7 @@ services:
ports: ports:
- '8080:8080' - '8080:8080'
volumes: volumes:
- ./trainingData:/usr/share/tessdata #Required for extra OCR languages - ./trainingData:/usr/share/tessdata # Required for extra OCR languages
- ./extraConfigs:/configs - ./extraConfigs:/configs
# - ./customFiles:/customFiles/ # - ./customFiles:/customFiles/
# - ./logs:/logs/ # - ./logs:/logs/
@@ -162,196 +169,257 @@ services:
Note: Podman is CLI-compatible with Docker, so simply replace "docker" with "podman". Note: Podman is CLI-compatible with Docker, so simply replace "docker" with "podman".
## Enable OCR/Compression feature ### Kubernetes
Please view https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md See the kubernetes helm chart [here](https://github.com/Stirling-Tools/Stirling-PDF-chart)
## Enable OCR/Compression Feature
Please view the [HowToUseOCR.md](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToUseOCR.md).
## Reuse Stored Files
Certain functionality like `Sign` supports pre-saved files stored at `/customFiles/signatures/`. Image files placed within here will be accessible to be used via the web UI. Currently, this supports two folder types:
- `/customFiles/signatures/ALL_USERS`: Accessible to all users, useful for organizations where many users use the same files or for users not using authentication
- `/customFiles/signatures/{username}`: Such as `/customFiles/signatures/froodle`, accessible only to the `froodle` username, private for all others
## Supported Languages ## Supported Languages
Stirling PDF currently supports 38! Stirling-PDF currently supports 36 languages!
| Language | Progress | | Language | Progress |
| ------------------------------------------- | -------------------------------------- | | -------------------------------------------- | -------------------------------------- |
| Arabic (العربية) (ar_AR) | ![93%](https://geps.dev/progress/93) | | Arabic (العربية) (ar_AR) | ![97%](https://geps.dev/progress/97) |
| Basque (Euskara) (eu_ES) | ![57%](https://geps.dev/progress/57) | | Basque (Euskara) (eu_ES) | ![55%](https://geps.dev/progress/55) |
| Bulgarian (Български) (bg_BG) | ![86%](https://geps.dev/progress/86) | | Bulgarian (Български) (bg_BG) | ![96%](https://geps.dev/progress/96) |
| Catalan (Català) (ca_CA) | ![44%](https://geps.dev/progress/44) | | Catalan (Català) (ca_CA) | ![90%](https://geps.dev/progress/90) |
| Croatian (Hrvatski) (hr_HR) | ![87%](https://geps.dev/progress/87) | | Croatian (Hrvatski) (hr_HR) | ![98%](https://geps.dev/progress/98) |
| Czech (Česky) (cs_CZ) | ![82%](https://geps.dev/progress/82) | | Czech (Česky) (cs_CZ) | ![97%](https://geps.dev/progress/97) |
| Danish (Dansk) (da_DK) | ![91%](https://geps.dev/progress/91) | | Danish (Dansk) (da_DK) | ![96%](https://geps.dev/progress/96) |
| Dutch (Nederlands) (nl_NL) | ![88%](https://geps.dev/progress/88) | | Dutch (Nederlands) (nl_NL) | ![96%](https://geps.dev/progress/96) |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) | | English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) | | English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| French (Français) (fr_FR) | ![85%](https://geps.dev/progress/85) | | French (Français) (fr_FR) | ![97%](https://geps.dev/progress/97) |
| German (Deutsch) (de_DE) | ![93%](https://geps.dev/progress/93) | | German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
| Greek (Ελληνικά) (el_GR) | ![75%](https://geps.dev/progress/75) | | Greek (Ελληνικά) (el_GR) | ![97%](https://geps.dev/progress/97) |
| Hindi (हिंदी) (hi_IN) | ![72%](https://geps.dev/progress/72) | | Hindi (हिंदी) (hi_IN) | ![95%](https://geps.dev/progress/95) |
| Hungarian (Magyar) (hu_HU) | ![69%](https://geps.dev/progress/69) | | Hungarian (Magyar) (hu_HU) | ![98%](https://geps.dev/progress/98) |
| Indonesia (Bahasa Indonesia) (id_ID) | ![70%](https://geps.dev/progress/70) | | Indonesian (Bahasa Indonesia) (id_ID) | ![97%](https://geps.dev/progress/97) |
| Irish (Gaeilge) (ga_IE) | ![90%](https://geps.dev/progress/90) | | Irish (Gaeilge) (ga_IE) | ![88%](https://geps.dev/progress/88) |
| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) | | Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) |
| Japanese (日本語) (ja_JP) | ![87%](https://geps.dev/progress/87) | | Japanese (日本語) (ja_JP) | ![85%](https://geps.dev/progress/85) |
| Korean (한국어) (ko_KR) | ![77%](https://geps.dev/progress/77) | | Korean (한국어) (ko_KR) | ![95%](https://geps.dev/progress/95) |
| Norwegian (Norsk) (no_NB) | ![90%](https://geps.dev/progress/90) | | Norwegian (Norsk) (no_NB) | ![87%](https://geps.dev/progress/87) |
| Polish (Polski) (pl_PL) | ![84%](https://geps.dev/progress/84) | | Polish (Polski) (pl_PL) | ![97%](https://geps.dev/progress/97) |
| Portuguese (Português) (pt_PT) | ![72%](https://geps.dev/progress/72) | | Portuguese (Português) (pt_PT) | ![97%](https://geps.dev/progress/97) |
| Portuguese Brazilian (Português) (pt_BR) | ![99%](https://geps.dev/progress/99) | | Portuguese Brazilian (Português) (pt_BR) | ![98%](https://geps.dev/progress/98) |
| Romanian (Română) (ro_RO) | ![92%](https://geps.dev/progress/92) | | Romanian (Română) (ro_RO) | ![90%](https://geps.dev/progress/90) |
| Russian (Русский) (ru_RU) | ![77%](https://geps.dev/progress/77) | | Russian (Русский) (ru_RU) | ![97%](https://geps.dev/progress/97) |
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![72%](https://geps.dev/progress/72) | | Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![70%](https://geps.dev/progress/70) |
| Simplified Chinese (简体中文) (zh_CN) | ![93%](https://geps.dev/progress/93) | | Simplified Chinese (简体中文) (zh_CN) | ![91%](https://geps.dev/progress/91) |
| Slovakian (Slovensky) (sk_SK) | ![84%](https://geps.dev/progress/84) | | Slovakian (Slovensky) (sk_SK) | ![82%](https://geps.dev/progress/82) |
| Spanish (Español) (es_ES) | ![93%](https://geps.dev/progress/93) | | Spanish (Español) (es_ES) | ![98%](https://geps.dev/progress/98) |
| Swedish (Svenska) (sv_SE) | ![92%](https://geps.dev/progress/92) | | Swedish (Svenska) (sv_SE) | ![97%](https://geps.dev/progress/97) |
| Thai (ไทย) (th_TH) | ![91%](https://geps.dev/progress/91) | | Thai (ไทย) (th_TH) | ![96%](https://geps.dev/progress/96) |
| Traditional Chinese (繁體中文) (zh_TW) | ![99%](https://geps.dev/progress/99) | | Traditional Chinese (繁體中文) (zh_TW) | ![98%](https://geps.dev/progress/98) |
| Turkish (Türkçe) (tr_TR) | ![94%](https://geps.dev/progress/94) | | Turkish (Türkçe) (tr_TR) | ![92%](https://geps.dev/progress/92) |
| Ukrainian (Українська) (uk_UA) | ![82%](https://geps.dev/progress/82) | | Ukrainian (Українська) (uk_UA) | ![80%](https://geps.dev/progress/80) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![90%](https://geps.dev/progress/90) | | Vietnamese (Tiếng Việt) (vi_VN) | ![88%](https://geps.dev/progress/88) |
## Contributing (creating issues, translations, fixing bugs, etc.) ## Contributing (Creating Issues, Translations, Fixing Bugs, etc.)
Please see our [Contributing Guide](CONTRIBUTING.md)! Please see our [Contributing Guide](CONTRIBUTING.md).
## Customisation ## Stirling PDF Enterprise
Stirling PDF allows easy customization of the app. Stirling PDF offers a Enterprise edition of its software, This is the same great software but with added features and comforts
Includes things like
### Whats included
- Prioritised Support tickets via support@stirlingpdf.com to reach directly to Stirling-PDF team for support and 1:1 meetings where applicable (Provided they come from same email domain registered with us)
- Prioritised Enhancements to Stirling-PDF where applicable
- Base SSO support
- Advanced SSO such as automated login handling (Coming very soon)
- SAML SSO (Coming very soon)
- Custom automated metadata handling
- Advanced user configurations (Coming soon)
- Plus other exciting features to come
Check out of [docs](https://docs.stirlingpdf.com/Enterprise%20Edition) on it or our official [website](https://www.stirlingpdf.com)
## Customization
Stirling-PDF allows easy customization of the app, including things like:
- Custom application name - Custom application name
- Custom slogans, icons, HTML, images CSS etc (via file overrides) - Custom slogans, icons, HTML, images, CSS, etc. (via file overrides)
There are two options for this, either using the generated settings file ``settings.yml`` There are two options for this, either using the generated settings file `settings.yml`, which is located in the `/configs` directory and follows standard YAML formatting, or using environment variables, which would override the settings file.
This file is located in the ``/configs`` directory and follows standard YAML formatting
Environment variables are also supported and would override the settings file For example, in `settings.yml`, you might have:
For example in the settings.yml you have
```yaml ```yaml
security: security:
enableLogin: 'true' enableLogin: 'true'
``` ```
To have this via an environment variable you would have ``SECURITY_ENABLELOGIN`` To have this via an environment variable, you would use `SECURITY_ENABLELOGIN`.
The Current list of settings is The current list of settings is:
```yaml ```yaml
security: security:
enableLogin: false # set to 'true' to enable login enableLogin: false # set to 'true' to enable login
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production) csrfDisabled: true # set to 'true' to disable CSRF protection (not recommended for production)
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1 loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
loginMethod: all # 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2) loginMethod: all # 'all' (Login Username/Password and OAuth2[must be enabled and configured]), 'normal'(only Login with Username/Password) or 'oauth2'(only Login with OAuth2)
initialLogin: initialLogin:
username: '' # Initial username for the first login username: '' # initial username for the first login
password: '' # Initial password for the first login password: '' # initial password for the first login
oauth2: oauth2:
enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work) enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
client: client:
keycloak: keycloak:
issuer: '' # URL of the Keycloak realm's OpenID Connect Discovery endpoint issuer: '' # URL of the Keycloak realm's OpenID Connect Discovery endpoint
clientId: '' # Client ID for Keycloak OAuth2 clientId: '' # client ID for Keycloak OAuth2
clientSecret: '' # Client Secret for Keycloak OAuth2 clientSecret: '' # client secret for Keycloak OAuth2
scopes: openid, profile, email # Scopes for Keycloak OAuth2 scopes: openid, profile, email # scopes for Keycloak OAuth2
useAsUsername: preferred_username # Field to use as the username for Keycloak OAuth2 useAsUsername: preferred_username # field to use as the username for Keycloak OAuth2
google: google:
clientId: '' # Client ID for Google OAuth2 clientId: '' # client ID for Google OAuth2
clientSecret: '' # Client Secret for Google OAuth2 clientSecret: '' # client secret for Google OAuth2
scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # Scopes for Google OAuth2 scopes: https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile # scopes for Google OAuth2
useAsUsername: email # Field to use as the username for Google OAuth2 useAsUsername: email # field to use as the username for Google OAuth2
github: github:
clientId: '' # Client ID for GitHub OAuth2 clientId: '' # client ID for GitHub OAuth2
clientSecret: '' # Client Secret for GitHub OAuth2 clientSecret: '' # client secret for GitHub OAuth2
scopes: read:user # Scope for GitHub OAuth2 scopes: read:user # scope for GitHub OAuth2
useAsUsername: login # Field to use as the username for GitHub OAuth2 useAsUsername: login # field to use as the username for GitHub OAuth2
issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point issuer: '' # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) endpoint
clientId: '' # Client ID from your provider clientId: '' # client ID from your provider
clientSecret: '' # Client Secret from your provider clientSecret: '' # client secret from your provider
autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
useAsUsername: email # Default is 'email'; custom fields can be used as the username useAsUsername: email # default is 'email'; custom fields can be used as the username
scopes: openid, profile, email # Specify the scopes for which the application will request permissions scopes: openid, profile, email # specify the scopes for which the application will request permissions
provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak' provider: google # set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
saml2:
enabled: false # currently in alpha, not recommended for use yet, enableAlphaFunctionality must be set to true
autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
registrationId: stirling
idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata
idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml
idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml
idpIssuer: http://www.okta.com/externalKey
idpCert: classpath:okta.crt
privateKey: classpath:saml-private-key.key
spCert: classpath:saml-public-cert.crt
enterpriseEdition:
enabled: false # set to 'true' to enable enterprise edition
key: 00000000-0000-0000-0000-000000000000
CustomMetadata:
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
creator: Stirling-PDF # supports text such as 'Company-PDF'
producer: Stirling-PDF # supports text such as 'Company-PDF'
legal:
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
impressum: '' # URL to the impressum of your application (e.g. https://example.com/impressum). Empty string to disable or filename to load from local file in static folder
system: system:
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc) defaultLocale: en-US # set the default language (e.g. 'de-DE', 'fr-FR', etc)
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes) enableAlphaFunctionality: false # set to enable functionality which might need more testing before it fully goes live (this feature might make no changes)
showUpdate: true # see when a new update is available showUpdate: false # see when a new update is available
showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true' showUpdateOnlyAdmin: false # only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
enableAnalytics: undefined # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
ui: ui:
appName: '' # Application's visible name appName: '' # application's visible name
homeDescription: '' # Short description or tagline shown on homepage. homeDescription: '' # short description or tagline shown on the homepage
appNameNavbar: '' # Name displayed on the navigation bar appNameNavbar: '' # name displayed on the navigation bar
endpoints: endpoints:
toRemove: [] # List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages']) toRemove: [] # list endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
groupsToRemove: [] # List groups to disable (e.g. ['LibreOffice']) groupsToRemove: [] # list groups to disable (e.g. ['LibreOffice'])
metrics: metrics:
enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable
# Automatically Generated Settings (Do Not Edit Directly)
AutomaticallyGenerated:
key: example
UUID: example
``` ```
There is an additional config file ``/configs/custom_settings.yml`` were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones There is an additional config file `/configs/custom_settings.yml` where users familiar with Java and Spring `application.properties` can input their own settings on top of Stirling-PDF's existing ones.
### Extra notes
- Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md)
- customStaticFilePath. Customise static files such as the app logo by placing files in the /customFiles/static/ directory. An example of customising app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF
### Environment only parameters ### Extra Notes
- ``SYSTEM_ROOTURIPATH`` ie set to ``/pdf-app`` to Set the application's root URI to ``localhost:8080/pdf-app`` - **Endpoints**: Currently, the `ENDPOINTS_TO_REMOVE` and `GROUPS_TO_REMOVE` endpoints can include comma-separated lists of endpoints and groups to disable. For example, `ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages` would disable both image-to-pdf and remove pages, while `GROUPS_TO_REMOVE=LibreOffice` would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Endpoint-groups.md).
- ``SYSTEM_CONNECTIONTIMEOUTMINUTES`` to set custom connection timeout values - **customStaticFilePath**: Customize static files such as the app logo by placing files in the `/customFiles/static/` directory. An example of customizing the app logo is placing `/customFiles/static/favicon.svg` to override the current SVG. This can be used to change any `images/icons/css/fonts/js`, etc. in Stirling-PDF.
- ``DOCKER_ENABLE_SECURITY`` to tell docker to download security jar (required as true for auth login)
- ``INSTALL_BOOK_AND_ADVANCED_HTML_OPS`` to download calibre onto stirling-pdf enabling pdf to/from book and advanced html conversion ### Environment-Only Parameters
- ``LANGS`` to define custom font libraries to install for use for document conversions
- `SYSTEM_ROOTURIPATH` - Set the application's root URI (e.g. `/pdf-app` to set the root URI to `localhost:8080/pdf-app`)
- `SYSTEM_CONNECTIONTIMEOUTMINUTES` - Set custom connection timeout values
- `DOCKER_ENABLE_SECURITY` - Set to `true` to download security jar (required for authentication login)
- `INSTALL_BOOK_AND_ADVANCED_HTML_OPS` - Download Calibre onto Stirling-PDF to enable PDF to/from book and advanced HTML conversion
- `LANGS` - Define custom font libraries to install for document conversions
## API ## API
For those wanting to use Stirling-PDFs backend API to link with their own custom scripting to edit PDFs you can view all existing API documentation For those wanting to use Stirling-PDF's backend API to link with their own custom scripting to edit PDFs, you can view all existing API documentation [here](https://app.swaggerhub.com/apis-docs/Stirling-Tools/Stirling-PDF/), or navigate to `/swagger-ui/index.html` of your Stirling-PDF instance for your version's documentation (or by following the API button in the settings of Stirling-PDF).
[here](https://app.swaggerhub.com/apis-docs/Stirling-Tools/Stirling-PDF/) or navigate to /swagger-ui/index.html of your stirling-pdf instance for your versions documentation (Or by following the API button in your settings of Stirling-PDF)
## Login authentication ## Login Authentication
![stirling-login](images/login-light.png) ![stirling-login](images/login-light.png)
### Prerequisites ### Prerequisites
- User must have the folder ./configs volumed within docker so that it is retained during updates. - User must have the folder `./configs` volumed within Docker so that it is retained during updates.
- Docker users must download the security jar version by setting ``DOCKER_ENABLE_SECURITY`` to ``true`` in environment variables. - Docker users must download the security jar version by setting `DOCKER_ENABLE_SECURITY` to `true` in environment variables.
- Then either enable login via the settings.yml file or via setting ``SECURITY_ENABLE_LOGIN`` to ``true`` - Then either enable login via the `settings.yml` file or set `SECURITY_ENABLE_LOGIN` to `true`.
- Now the initial user will be generated with username ``admin`` and password ``stirling``. On login you will be forced to change the password to a new one. You can also use the environment variables ``SECURITY_INITIALLOGIN_USERNAME`` and ``SECURITY_INITIALLOGIN_PASSWORD`` to set your own straight away (Recommended to remove them after user creation). - Now the initial user will be generated with username `admin` and password `stirling`. On login, you will be forced to change the password to a new one. You can also use the environment variables `SECURITY_INITIALLOGIN_USERNAME` and `SECURITY_INITIALLOGIN_PASSWORD` to set your own credentials straight away (recommended to remove them after user creation).
Once the above has been done, on restart, a new stirling-pdf-DB.mv.db will show if everything worked. Once the above has been done, on restart, a new `stirling-pdf-DB.mv.db` will show if everything worked.
When you login to Stirling PDF you will be redirected to /login page to login with those default credentials. After login everything should function as normal When you log in to Stirling-PDF, you will be redirected to the `/login` page to log in with those default credentials. After login, everything should function as normal.
To access your account settings go to Account settings in the settings cog menu (top right in navbar) This Account settings menu is also where you find your API key. To access your account settings, go to Account Settings in the settings cog menu (top right in the navbar). This Account Settings menu is also where you find your API key.
To add new users go to the bottom of Account settings and hit 'Admin Settings', here you can add new users. The different roles mentioned within this are for rate limiting. This is a Work in progress which will be expanding on more in future To add new users, go to the bottom of Account Settings and hit 'Admin Settings'. Here you can add new users. The different roles mentioned within this are for rate limiting. This is a work in progress and will be expanded on more in the future.
For API usage you must provide a header with 'X-API-Key' and the associated API key for that user. For API usage, you must provide a header with `X-API-Key` and the associated API key for that user.
## FAQ ## FAQ
### Q1: What are your planned features? ### Q1: What are your planned features?
- Progress bar/Tracking - Progress bar/tracking
- Full custom logic pipelines to combine multiple operations together. - Full custom logic pipelines to combine multiple operations together
- Folder support with auto scanning to perform operations on - Folder support with auto-scanning to perform operations on
- Redact text (Via UI not just automated way) - Redact text (via UI, not just automated)
- Add Forms - Add forms
- Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing - Multi-page layout (stitch PDF pages together) support x rows y columns and custom page sizing
- Fill forms manually or automatically - Fill forms manually or automatically
### Q2: Why is my application downloading .htm files? ### Q2: Why is my application downloading .htm files? Why am i getting HTTP error 413?
This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. ``client_max_body_size SIZE;`` Where "SIZE" is 50M for example for 50MB files. This is an issue commonly caused by your NGINX configuration. The default file upload size for NGINX is 1MB. You need to add the following in your Nginx sites-available file: `client_max_body_size SIZE;` (where "SIZE" is 50M for example for 50MB files).
### Q3: Why is my download timing out ### Q3: Why is my download timing out?
NGINX has timeout values by default so if you are running Stirling-PDF behind NGINX you may need to set a timeout value such as adding the config ``proxy_read_timeout 3600;`` NGINX has timeout values by default, so if you are running Stirling-PDF behind NGINX, you may need to set a timeout value, such as adding the config `proxy_read_timeout 3600;`.

View File

@@ -1,7 +1,7 @@
|All versions in a Docker environment can download Calibre as a optional extra at runtime to support `book-to-pdf` and `pdf-to-book` using parameter ``INSTALL_BOOK_AND_ADVANCED_HTML_OPS``. |All versions in a Docker environment can download Calibre as a optional extra at runtime to support `book-to-pdf` and `pdf-to-book` using parameter ``INSTALL_BOOK_AND_ADVANCED_HTML_OPS``.
The 'Fat' container contains all those found in 'Full' with security jar along with this Calibre install. The 'Fat' container contains all those found in 'Full' with security jar along with this Calibre install.
Technology | Ultra-Lite | Full | | Technology | Ultra-Lite | Full |
| ---------- | :--------: | :---: | | ---------- | :--------: | :---: |
| Java | ✔️ | ✔️ | | Java | ✔️ | ✔️ |
| JavaScript | ✔️ | ✔️ | | JavaScript | ✔️ | ✔️ |
@@ -54,3 +54,15 @@ Technology | Ultra-Lite | Full |
| ocr-pdf | | ✔️ | | ocr-pdf | | ✔️ |
| pdf-to-pdfa | | ✔️ | | pdf-to-pdfa | | ✔️ |
| remove-blanks | | ✔️ | | remove-blanks | | ✔️ |
pdf-to-text | ✔️ | ✔️
pdf-to-html | | ✔️
pdf-to-word | | ✔️
pdf-to-presentation | | ✔️
pdf-to-xml | | ✔️
remove-annotations | ✔️ | ✔️
remove-cert-sign | ✔️ | ✔️
remove-image-pdf | ✔️ | ✔️
file-to-pdf | | ✔️
html-to-pdf | | ✔️
url-to-pdf | | ✔️
repair | | ✔️

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id "java" id "java"
id "org.springframework.boot" version "3.3.4" id "org.springframework.boot" version "3.3.5"
id "io.spring.dependency-management" version "1.1.6" id "io.spring.dependency-management" version "1.1.6"
id "org.springdoc.openapi-gradle-plugin" version "1.8.0" id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
id "io.swagger.swaggerhub" version "1.3.2" id "io.swagger.swaggerhub" version "1.3.2"
@@ -13,7 +13,7 @@ plugins {
import com.github.jk1.license.render.* import com.github.jk1.license.render.*
ext { ext {
springBootVersion = "3.3.4" springBootVersion = "3.3.5"
pdfboxVersion = "3.0.3" pdfboxVersion = "3.0.3"
logbackVersion = "1.5.7" logbackVersion = "1.5.7"
imageioVersion = "3.12.0" imageioVersion = "3.12.0"
@@ -22,7 +22,7 @@ ext {
} }
group = "stirling.software" group = "stirling.software"
version = "0.30.0" version = "0.33.0"
java { java {
// 17 is lowest but we support and recommend 21 // 17 is lowest but we support and recommend 21
@@ -32,11 +32,9 @@ java {
repositories { repositories {
mavenCentral() mavenCentral()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
maven { maven { url "https://build.shibboleth.net/nexus/content/repositories/releases/" }
url "https://build.shibboleth.net/nexus/content/repositories/releases/"
}
maven { maven {
url "https://build.shibboleth.net/maven/releases/" url 'https://build.shibboleth.net/maven/releases'
} }
} }
@@ -80,7 +78,7 @@ launch4j {
errTitle="Encountered error, Do you have Java 21?" errTitle="Encountered error, Do you have Java 21?"
downloadUrl="https://download.oracle.com/java/21/latest/jdk-21_windows-x64_bin.exe" downloadUrl="https://download.oracle.com/java/21/latest/jdk-21_windows-x64_bin.exe"
variables=["BROWSER_OPEN=true", "ENDPOINTS_GROUPS_TO_REMOVE=CLI"] variables=["BROWSER_OPEN=true"]
jreMinVersion="17" jreMinVersion="17"
mutexName="Stirling-PDF" mutexName="Stirling-PDF"
@@ -121,7 +119,7 @@ configurations.all {
} }
dependencies { dependencies {
//security updates //security updates
implementation "org.springframework:spring-webmvc:6.1.13" implementation "org.springframework:spring-webmvc:6.1.14"
implementation("io.github.pixee:java-security-toolkit:1.2.0") implementation("io.github.pixee:java-security-toolkit:1.2.0")
@@ -139,15 +137,25 @@ dependencies {
if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") {
implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion"
runtimeOnly "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE" implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
implementation 'org.springframework.security:spring-security-saml2-service-provider:6.3.3' implementation 'org.springframework.security:spring-security-saml2-service-provider:6.3.4'
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5' implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
//2.2.x requires rebuild of DB file.. need migration path //2.2.x requires rebuild of DB file.. need migration path
runtimeOnly "com.h2database:h2:2.1.214" runtimeOnly "com.h2database:h2:2.1.214"
// implementation "com.h2database:h2:2.2.224" // implementation "com.h2database:h2:2.2.224"
constraints {
implementation "org.opensaml:opensaml-core"
implementation "org.opensaml:opensaml-saml-api"
implementation "org.opensaml:opensaml-saml-impl"
}
implementation "org.springframework.security:spring-security-saml2-service-provider"
implementation 'com.coveo:saml-client:5.0.0'
} }
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion" testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
@@ -173,6 +181,9 @@ dependencies {
runtimeOnly "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion" runtimeOnly "com.twelvemonkeys.imageio:imageio-webp:$imageioVersion"
// runtimeOnly "com.twelvemonkeys.imageio:imageio-xwd:$imageioVersion" // runtimeOnly "com.twelvemonkeys.imageio:imageio-xwd:$imageioVersion"
// Image metadata extractor
implementation "com.drewnoakes:metadata-extractor:2.19.0"
implementation "commons-io:commons-io:2.17.0" implementation "commons-io:commons-io:2.17.0"
implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0" implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0"
//general PDF //general PDF
@@ -198,8 +209,8 @@ dependencies {
implementation "io.micrometer:micrometer-core:1.13.6" implementation "io.micrometer:micrometer-core:1.13.6"
implementation group: "com.google.zxing", name: "core", version: "3.5.3" implementation group: "com.google.zxing", name: "core", version: "3.5.3"
// https://mvnrepository.com/artifact/org.commonmark/commonmark // https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark:0.23.0" implementation "org.commonmark:commonmark:0.24.0"
implementation "org.commonmark:commonmark-ext-gfm-tables:0.23.0" implementation "org.commonmark:commonmark-ext-gfm-tables:0.24.0"
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17 // https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0" implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
implementation "com.fathzer:javaluator:3.0.5" implementation "com.fathzer:javaluator:3.0.5"

View File

@@ -1,16 +0,0 @@
apiVersion: v2
appVersion: 0.30.0
description: locally hosted web application that allows you to perform various operations
on PDF files
home: https://github.com/Stirling-Tools/Stirling-PDF
keywords:
- stirling-pdf
- helm
- charts repo
maintainers:
- name: Stirling-Tools
url: https://github.com/Stirling-Tools/Stirling-PDF
name: stirling-pdf-chart
sources:
- https://github.com/Stirling-Tools/Stirling-PDF
version: 1.0.0

View File

@@ -1,30 +0,0 @@
** Please be patient while the chart is being deployed **
Get the stirlingpdf URL by running:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "stirlingpdf.fullname" . }})
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 }}
** Please ensure an external IP is associated to the {{ template "stirlingpdf.fullname" . }} service before proceeding **
** Watch the status using: kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "stirlingpdf.fullname" . }} **
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "stirlingpdf.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.externalPort }}/
OR
export SERVICE_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "stirlingpdf.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo http://$SERVICE_HOST:{{ .Values.service.externalPort }}/
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "stirlingpdf.name" . }}" -l "release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo http://127.0.0.1:8080/
kubectl port-forward $POD_NAME 8080:8080 --namespace {{ .Release.Namespace }}
{{- end }}

View File

@@ -1,129 +0,0 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "stirlingpdf.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "stirlingpdf.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- /*
Create chart name and version as used by the chart label.
It does minimal escaping for use in Kubernetes labels.
Example output:
stirlingpdf-0.4.5
*/ -}}
{{- define "stirlingpdf.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "stirlingpdf.labels" -}}
helm.sh/chart: {{ include "stirlingpdf.chart" . }}
{{ include "stirlingpdf.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
{{- if .Values.commonLabels}}
{{ toYaml .Values.commonLabels }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "stirlingpdf.selectorLabels" -}}
app.kubernetes.io/name: {{ include "stirlingpdf.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "stirlingpdf.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "stirlingpdf.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Return the proper image name to change the volume permissions
*/}}
{{- define "stirlingpdf.volumePermissions.image" -}}
{{- $registryName := .Values.volumePermissions.image.registry -}}
{{- $repositoryName := .Values.volumePermissions.image.repository -}}
{{- $tag := .Values.volumePermissions.image.tag | toString -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 doesn't support it, so we need to implement this if-else logic.
Also, we can't use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imageRegistry }}
{{- printf "%s/%s:%s" .Values.global.imageRegistry $repositoryName $tag -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- else -}}
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
{{- end -}}
{{- end -}}
{{/*
Return the proper Docker Image Registry Secret Names
*/}}
{{- define "stirlingpdf.imagePullSecrets" -}}
{{/*
Helm 2.11 supports the assignment of a value to a variable defined in a different scope,
but Helm 2.9 and 2.10 does not support it, so we need to implement this if-else logic.
Also, we can not use a single if because lazy evaluation is not an option
*/}}
{{- if .Values.global }}
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.global.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- else if or .Values.image.pullSecrets .Values.volumePermissions.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- range .Values.volumePermissions.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end -}}
{{- else if or .Values.image.pullSecrets .Values.volumePermissions.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- range .Values.volumePermissions.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -1,131 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "stirlingpdf.fullname" . }}
{{- with .Values.deployment.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- if .Values.deployment.labels }}
{{- toYaml .Values.deployment.labels | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- include "stirlingpdf.selectorLabels" . | nindent 6 }}
replicas: {{ .Values.replicaCount }}
strategy:
{{ toYaml .Values.strategy | indent 4 }}
revisionHistoryLimit: 10
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "stirlingpdf.selectorLabels" . | nindent 8 }}
{{- if .Values.podLabels }}
{{- toYaml .Values.podLabels | nindent 8 }}
{{- end }}
spec:
{{- if .Values.priorityClassName }}
priorityClassName: "{{ .Values.priorityClassName }}"
{{- end }}
{{- if .Values.securityContext.enabled }}
securityContext:
fsGroup: {{ .Values.securityContext.fsGroup }}
{{- if .Values.securityContext.runAsNonRoot }}
runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }}
{{- end }}
{{- if .Values.securityContext.supplementalGroups }}
supplementalGroups: {{ .Values.securityContext.supplementalGroups }}
{{- end }}
{{- else if .Values.persistence.enabled }}
initContainers:
- name: volume-permissions
image: {{ template "stirlingpdf.volumePermissions.image" . }}
imagePullPolicy: "{{ .Values.volumePermissions.image.pullPolicy }}"
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 10 }}
command: ['sh', '-c', 'chown -R {{ .Values.securityContext.fsGroup }}:{{ .Values.securityContext.fsGroup }} {{ .Values.persistence.path }}']
volumeMounts:
- mountPath: {{ .Values.persistence.path }}
name: storage-volume
{{- end }}
{{- include "stirlingpdf.imagePullSecrets" . | indent 6 }}
containers:
- name: {{ .Chart.Name }}
image: {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 10 }}
env:
- name: SYSTEM_ROOTURIPATH
value: {{ .Values.rootPath}}
{{- if .Values.envs }}
{{ toYaml .Values.envs | indent 8 }}
{{- end }}
{{- if .Values.extraArgs }}
args:
{{ toYaml .Values.extraArgs | indent 8 }}
{{- end }}
ports:
- name: http
containerPort: 8080
livenessProbe:
httpGet:
path: {{ .Values.rootPath}}
port: http
{{ toYaml .Values.probes.livenessHttpGetConfig | indent 12 }}
{{ toYaml .Values.probes.liveness | indent 10 }}
readinessProbe:
httpGet:
path: {{ .Values.rootPath}}
port: http
{{ toYaml .Values.probes.readinessHttpGetConfig | indent 12 }}
{{ toYaml .Values.probes.readiness | indent 10 }}
volumeMounts:
{{- if .Values.deployment.extraVolumeMounts }}
{{- toYaml .Values.deployment.extraVolumeMounts | nindent 8 }}
{{- end }}
{{- if .Values.deployment.sidecarContainers }}
{{- range $name, $spec := .Values.deployment.sidecarContainers }}
- name: {{ $name }}
{{- toYaml $spec | nindent 8 }}
{{- end }}
{{- end }}
{{- with .Values.resources }}
resources:
{{ toYaml . | indent 10 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if .Values.schedulerName }}
schedulerName: {{ .Values.schedulerName }}
{{- end }}
serviceAccountName: {{ include "stirlingpdf.serviceAccountName" . }}
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
volumes:
{{- if .Values.deployment.extraVolumes }}
{{- toYaml .Values.deployment.extraVolumes | nindent 6 }}
{{- end }}
- name: storage-volume
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim | default (include "stirlingpdf.fullname" .) }}
{{- else }}
emptyDir: {}
{{- end }}

View File

@@ -1,85 +0,0 @@
{{- if .Values.ingress.enabled }}
{{- $servicePort := .Values.service.externalPort -}}
{{- $serviceName := include "stirlingpdf.fullname" . -}}
{{- $ingressExtraPaths := .Values.ingress.extraPaths -}}
---
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: extensions/v1beta1
{{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: networking.k8s.io/v1beta1
{{- else }}
apiVersion: networking.k8s.io/v1
{{- end }}
kind: Ingress
metadata:
name: {{ include "stirlingpdf.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- with .Values.ingress.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.ingress.ingressClassName }}
ingressClassName: {{ . }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .name }}
http:
paths:
{{- range $ingressExtraPaths }}
- path: {{ default "/" .path | quote }}
backend:
{{- if semverCompare "<1.19-0" $.Capabilities.KubeVersion.GitVersion }}
{{- if $.Values.service.servicename }}
serviceName: {{ $.Values.service.servicename }}
{{- else }}
serviceName: {{ default $serviceName .service }}
{{- end }}
servicePort: {{ default $servicePort .port }}
{{- else }}
service:
{{- if $.Values.service.servicename }}
name: {{ $.Values.service.servicename }}
{{- else }}
name: {{ default $serviceName .service }}
{{- end }}
port:
number: {{ default $servicePort .port }}
pathType: {{ default $.Values.ingress.pathType .pathType }}
{{- end }}
{{- end }}
- path: {{ default "/" .path | quote }}
backend:
{{- if semverCompare "<1.19-0" $.Capabilities.KubeVersion.GitVersion }}
{{- if $.Values.service.servicename }}
serviceName: {{ $.Values.service.servicename }}
{{- else }}
serviceName: {{ default $serviceName .service }}
{{- end }}
servicePort: {{ default $servicePort .servicePort }}
{{- else }}
service:
{{- if $.Values.service.servicename }}
name: {{ $.Values.service.servicename }}
{{- else }}
name: {{ default $serviceName .service }}
{{- end }}
port:
number: {{ default $servicePort .port }}
pathType: {{ $.Values.ingress.pathType }}
{{- end }}
{{- end }}
tls:
{{- range .Values.ingress.hosts }}
{{- if .tls }}
- hosts:
- {{ .name }}
secretName: {{ .tlsSecret }}
{{- end }}
{{- end }}
{{- end -}}

View File

@@ -1,16 +0,0 @@
{{- if .Values.persistence.pv.enabled -}}
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ .Values.persistence.pv.pvname | default (include "stirlingpdf.fullname" .) }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
spec:
capacity:
storage: {{ .Values.persistence.pv.capacity.storage }}
accessModes:
- {{ .Values.persistence.pv.accessMode | quote }}
nfs:
server: {{ .Values.persistence.pv.nfs.server }}
path: {{ .Values.persistence.pv.nfs.path | quote }}
{{- end }}

View File

@@ -1,27 +0,0 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ include "stirlingpdf.fullname" . }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- with .Values.persistence.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistence.storageClass }}"
{{- end }}
{{- if .Values.persistence.volumeName }}
volumeName: "{{ .Values.persistence.volumeName }}"
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,48 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.service.servicename | default (include "stirlingpdf.fullname" .) }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- with .Values.service.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- if (or (eq .Values.service.type "LoadBalancer") (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort)))) }}
externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }}
{{- end }}
{{- if (and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerIP) }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
{{- if (and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges) }}
loadBalancerSourceRanges:
{{- with .Values.service.loadBalancerSourceRanges }}
{{ toYaml . | indent 2 }}
{{- end }}
{{- end }}
{{- if eq .Values.service.type "ClusterIP" }}
{{- if .Values.service.clusterIP }}
clusterIP: {{ .Values.service.clusterIP }}
{{- end }}
{{- end }}
ports:
- port: {{ .Values.service.externalPort }}
{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }}
nodePort: {{.Values.service.nodePort}}
{{- end }}
{{- if .Values.service.targetPort }}
targetPort: {{ .Values.service.targetPort }}
name: {{ .Values.service.targetPort }}
{{- else }}
targetPort: http
name: http
{{- end }}
protocol: TCP
selector:
{{- include "stirlingpdf.selectorLabels" . | nindent 4 }}

View File

@@ -1,13 +0,0 @@
{{- if .Values.serviceAccount.create -}}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "stirlingpdf.serviceAccountName" . }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{ toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- end }}

View File

@@ -1,31 +0,0 @@
{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ( .Values.serviceMonitor.enabled ) }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "stirlingpdf.fullname" . }}
namespace: {{ .Values.serviceMonitor.namespace | default .Release.Namespace }}
labels:
{{- include "stirlingpdf.labels" . | nindent 4 }}
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:
- targetPort: 8080
{{- if .Values.serviceMonitor.interval }}
interval: {{ .Values.serviceMonitor.interval }}
{{- end }}
{{- if .Values.serviceMonitor.metricsPath }}
path: {{ .Values.serviceMonitor.metricsPath }}
{{- end }}
{{- if .Values.serviceMonitor.timeout }}
scrapeTimeout: {{ .Values.serviceMonitor.timeout }}
{{- end }}
jobLabel: {{ include "stirlingpdf.fullname" . }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{- include "stirlingpdf.selectorLabels" . | nindent 6 }}
{{- end }}

View File

@@ -1,240 +0,0 @@
extraArgs: []
# - --storage-timestamp-tolerance 1s
replicaCount: 1
strategy:
type: RollingUpdate
image:
repository: frooodle/s-pdf
# took Chart appVersion by default
tag: ~
pullPolicy: IfNotPresent
secret:
labels: {}
## Labels to apply to all resources
##
commonLabels: {}
# team_name: dev
# rootpath for the application
rootPath: /
envs: []
# - name: UI_APP_NAME
# value: "Stirling PDF"
# - name: UI_HOME_DESCRIPTION
# value: "Your locally hosted one-stop-shop for all your PDF needs."
# - name: UI_APP_NAVBAR_NAME
# value: "Stirling PDF"
# - name: ALLOW_GOOGLE_VISIBILITY
# value: "true"
# - name: APP_LOCALE
# value: "en_GB"
deployment:
## stirling-pdf Deployment annotations
annotations: {}
# name: value
labels: {}
# name: value
# additional volumes
extraVolumes: []
# - name: nginx-config
# secret:
# secretName: nginx-config
# additional volumes to mount
extraVolumeMounts: []
## sidecarContainers for the stirling-pdf
# Can be used to add a proxy to the pod that does
# scanning for secrets, signing, authentication, validation
# of the chart's content, send notifications...
sidecarContainers: {}
## Example sidecarContainer which uses an extraVolume from above and
## a named port that can be referenced in the service as targetPort.
# proxy:
# image: nginx:latest
# ports:
# - name: proxy
# containerPort: 8081
# volumeMounts:
# - name: nginx-config
# readOnly: true
# mountPath: /etc/nginx
## Pod annotations
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
## Read more about kube2iam to provide access to s3 https://github.com/jtblin/kube2iam
##
podAnnotations: {}
# iam.amazonaws.com/role: role-arn
## Pod labels
## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
podLabels: {}
# name: value
service:
servicename:
type: ClusterIP
externalTrafficPolicy: Local
## Uses pre-assigned IP address from cloud provider
## Only valid if service.type: LoadBalancer
loadBalancerIP:
## Limits which cidr blocks can connect to service's load balancer
## Only valid if service.type: LoadBalancer
loadBalancerSourceRanges: []
# clusterIP: None
externalPort: 8080
## targetPort of the container to use. If a sidecar should handle the
## requests first, use the named port from the sidecar. See sidecar example
## from deployment above. Leave empty to use stirling-pdf directly.
targetPort:
nodePort:
annotations: {}
labels: {}
serviceMonitor:
enabled: false
# namespace: prometheus
labels: {}
metricsPath: "/metrics"
# timeout: 60
# interval: 60
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 80m
# memory: 64Mi
probes:
liveness:
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
livenessHttpGetConfig:
scheme: HTTP
readiness:
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
readinessHttpGetConfig:
scheme: HTTP
serviceAccount:
create: true
name: ""
automountServiceAccountToken: false
## Annotations for the Service Account
annotations: {}
# UID/GID 1000 is the default user "stirling-pdf" used in
# the container image starting in v0.8.0 and above. This
# is required for local persistent storage. If your cluster
# does not allow this, try setting securityContext: {}
securityContext:
enabled: true
fsGroup: 1000
## Optionally, specify supplementalGroups and/or
## runAsNonRoot for security purposes
# runAsNonRoot: true
# supplementalGroups: [1000]
containerSecurityContext: {}
priorityClassName: ""
nodeSelector: {}
tolerations: []
affinity: {}
persistence:
enabled: false
accessMode: ReadWriteOnce
size: 8Gi
labels: {}
# name: value
path: /tmp
## A manually managed Persistent Volume and Claim
## Requires persistence.enabled: true
## If defined, PVC must be created manually before volume will be bound
# existingClaim:
## stirling-pdf data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
# volumeName:
pv:
enabled: false
pvname:
capacity:
storage: 8Gi
accessMode: ReadWriteOnce
nfs:
server:
path:
## Init containers parameters:
## volumePermissions: Change the owner of the persistent volume mountpoint to RunAsUser:fsGroup
##
volumePermissions:
image:
registry: docker.io
repository: bitnami/minideb
tag: buster
pullPolicy: Always
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistryKeySecretName
## Ingress for load balancer
ingress:
enabled: false
pathType: "ImplementationSpecific"
## stirling-pdf Ingress labels
##
labels: {}
# dns: "route53"
## stirling-pdf Ingress annotations
##
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
## stirling-pdf Ingress hostnames
## Must be provided if Ingress is enabled
##
hosts: []
# - name: stirling-pdf.domain1.com
# path: /
# tls: false
# - name: stirling-pdf.domain2.com
# path: /
#
# ## Set this to true in order to enable TLS on the ingress record
# tls: true
#
# ## If TLS is set to true, you must declare what secret will store the key/certificate for TLS
# ## Secrets must be added manually to the namespace
# tlsSecret: stirling-pdf.domain2-tls
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
ingressClassName:

View File

@@ -13,13 +13,11 @@ ignore = [
'PDFToText.tags', 'PDFToText.tags',
'adminUserSettings.admin', 'adminUserSettings.admin',
'language.direction', 'language.direction',
'survey.button',
'watermark.type.1', 'watermark.type.1',
] ]
[cs_CZ] [cs_CZ]
ignore = [ ignore = [
'info',
'language.direction', 'language.direction',
'pipeline.header', 'pipeline.header',
'text', 'text',
@@ -39,10 +37,12 @@ ignore = [
'addPageNumbers.selectText.3', 'addPageNumbers.selectText.3',
'alphabet', 'alphabet',
'certSign.name', 'certSign.name',
'home.pipeline.title',
'language.direction', 'language.direction',
'licenses.version', 'licenses.version',
'pipeline.title', 'pipeline.title',
'pipelineOptions.pipelineHeader', 'pipelineOptions.pipelineHeader',
'pro',
'sponsor', 'sponsor',
'text', 'text',
'watermark.type.1', 'watermark.type.1',
@@ -79,7 +79,6 @@ ignore = [
'alphabet', 'alphabet',
'compare.document.1', 'compare.document.1',
'compare.document.2', 'compare.document.2',
'info',
'language.direction', 'language.direction',
'licenses.license', 'licenses.license',
'licenses.module', 'licenses.module',
@@ -87,8 +86,6 @@ ignore = [
'licenses.version', 'licenses.version',
'pdfOrganiser.mode', 'pdfOrganiser.mode',
'pipeline.title', 'pipeline.title',
'pipelineOptions.pipelineHeader',
'sponsor',
'watermark.type.2', 'watermark.type.2',
] ]
@@ -105,11 +102,8 @@ ignore = [
[hr_HR] [hr_HR]
ignore = [ ignore = [
'PDFToBook.selectText.1', 'PDFToBook.selectText.1',
'font',
'home.pipeline.title', 'home.pipeline.title',
'info',
'language.direction', 'language.direction',
'pdfOrganiser.tags',
'showJS.tags', 'showJS.tags',
] ]
@@ -125,7 +119,6 @@ ignore = [
[it_IT] [it_IT]
ignore = [ ignore = [
'font',
'language.direction', 'language.direction',
'no', 'no',
'password', 'password',
@@ -148,18 +141,10 @@ ignore = [
[nl_NL] [nl_NL]
ignore = [ ignore = [
'HTMLToPDF.print',
'adjustContrast.contrast',
'compare.document.1', 'compare.document.1',
'compare.document.2', 'compare.document.2',
'error',
'getPdfInfo.downloadJson',
'help',
'info',
'language.direction', 'language.direction',
'navbar.allTools', 'navbar.allTools',
'printFile.submit',
'showJS.downloadJS',
'sponsor', 'sponsor',
] ]
@@ -181,7 +166,6 @@ ignore = [
[pt_BR] [pt_BR]
ignore = [ ignore = [
'changeMetadata.trapped',
'language.direction', 'language.direction',
'pipelineOptions.pipelineHeader', 'pipelineOptions.pipelineHeader',
] ]
@@ -227,7 +211,6 @@ ignore = [
[th_TH] [th_TH]
ignore = [ ignore = [
'language.direction', 'language.direction',
'pipeline.title',
'pipelineOptions.pipelineHeader', 'pipelineOptions.pipelineHeader',
'showJS.tags', 'showJS.tags',
] ]

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Check if a key was provided
if [ $# -eq 0 ]; then
echo "Please provide a key to remove."
exit 1
fi
key_to_remove="$1"
for file in ../src/main/resources/messages_*.properties; do
# If the key ends with a dot, remove all keys starting with it
if [[ "$key_to_remove" == *. ]]; then
sed -i "/^${key_to_remove//./\\.}/d" "$file"
else
# Otherwise, remove only the exact key match
sed -i "/^${key_to_remove//./\\.}=/d" "$file"
fi
echo "Updated $file"
done

View File

@@ -1,22 +1,19 @@
package stirling.software.SPDF.EE; package stirling.software.SPDF.EE;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
@Configuration @Configuration
@Lazy @Lazy
@Slf4j
public class EEAppConfig { public class EEAppConfig {
private static final Logger logger = LoggerFactory.getLogger(EEAppConfig.class);
@Autowired ApplicationProperties applicationProperties; @Autowired ApplicationProperties applicationProperties;
@Autowired private LicenseKeyChecker licenseKeyChecker; @Autowired private LicenseKeyChecker licenseKeyChecker;
@Bean(name = "runningEE") @Bean(name = "runningEE")

View File

@@ -33,8 +33,12 @@ public class SPdfApplication {
@Autowired private Environment env; @Autowired private Environment env;
@Autowired ApplicationProperties applicationProperties; @Autowired ApplicationProperties applicationProperties;
private static String baseUrlStatic;
private static String serverPortStatic; private static String serverPortStatic;
@Value("${baseUrl:http://localhost}")
private String baseUrl;
@Value("${server.port:8080}") @Value("${server.port:8080}")
public void setServerPortStatic(String port) { public void setServerPortStatic(String port) {
if ("auto".equalsIgnoreCase(port)) { if ("auto".equalsIgnoreCase(port)) {
@@ -65,12 +69,13 @@ public class SPdfApplication {
@PostConstruct @PostConstruct
public void init() { public void init() {
baseUrlStatic = this.baseUrl;
// Check if the BROWSER_OPEN environment variable is set to true // Check if the BROWSER_OPEN environment variable is set to true
String browserOpenEnv = env.getProperty("BROWSER_OPEN"); String browserOpenEnv = env.getProperty("BROWSER_OPEN");
boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv); boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv);
if (browserOpen) { if (browserOpen) {
try { try {
String url = "http://localhost:" + getStaticPort(); String url = baseUrl + ":" + getStaticPort();
String os = System.getProperty("os.name").toLowerCase(); String os = System.getProperty("os.name").toLowerCase();
Runtime rt = Runtime.getRuntime(); Runtime rt = Runtime.getRuntime();
@@ -138,10 +143,18 @@ public class SPdfApplication {
private static void printStartupLogs() { private static void printStartupLogs() {
logger.info("Stirling-PDF Started."); logger.info("Stirling-PDF Started.");
String url = "http://localhost:" + getStaticPort(); String url = baseUrlStatic + ":" + getStaticPort();
logger.info("Navigate to {}", url); logger.info("Navigate to {}", url);
} }
public static String getStaticBaseUrl() {
return baseUrlStatic;
}
public String getNonStaticBaseUrl() {
return baseUrlStatic;
}
public static String getStaticPort() { public static String getStaticPort() {
return serverPortStatic; return serverPortStatic;
} }

View File

@@ -15,6 +15,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
@@ -162,12 +163,14 @@ public class AppConfig {
} }
@Bean(name = "analyticsPrompt") @Bean(name = "analyticsPrompt")
@Scope("request")
public boolean analyticsPrompt() { public boolean analyticsPrompt() {
return applicationProperties.getSystem().getEnableAnalytics() == null return applicationProperties.getSystem().getEnableAnalytics() == null
|| "undefined".equals(applicationProperties.getSystem().getEnableAnalytics()); || "undefined".equals(applicationProperties.getSystem().getEnableAnalytics());
} }
@Bean(name = "analyticsEnabled") @Bean(name = "analyticsEnabled")
@Scope("request")
public boolean analyticsEnabled() { public boolean analyticsEnabled() {
if (applicationProperties.getEnterpriseEdition().isEnabled()) return true; if (applicationProperties.getEnterpriseEdition().isEnabled()) return true;
return applicationProperties.getSystem().getEnableAnalytics() != null return applicationProperties.getSystem().getEnableAnalytics() != null

View File

@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -42,7 +43,7 @@ public class EndpointConfiguration {
public void disableEndpoint(String endpoint) { public void disableEndpoint(String endpoint) {
if (!endpointStatuses.containsKey(endpoint) || endpointStatuses.get(endpoint) != false) { if (!endpointStatuses.containsKey(endpoint) || endpointStatuses.get(endpoint) != false) {
logger.info("Disabling {}", endpoint); logger.debug("Disabling {}", endpoint);
endpointStatuses.put(endpoint, false); endpointStatuses.put(endpoint, false);
} }
} }
@@ -76,6 +77,23 @@ public class EndpointConfiguration {
} }
} }
public void logDisabledEndpointsSummary() {
List<String> disabledList =
endpointStatuses.entrySet().stream()
.filter(entry -> !entry.getValue()) // only get disabled endpoints (value
// is false)
.map(Map.Entry::getKey)
.sorted()
.collect(Collectors.toList());
if (!disabledList.isEmpty()) {
logger.info(
"Total disabled endpoints: {}. Disabled endpoints: {}",
disabledList.size(),
String.join(", ", disabledList));
}
}
public void init() { public void init() {
// Adding endpoints to "PageOps" group // Adding endpoints to "PageOps" group
addEndpointToGroup("PageOps", "remove-pages"); addEndpointToGroup("PageOps", "remove-pages");
@@ -99,7 +117,6 @@ public class EndpointConfiguration {
addEndpointToGroup("Convert", "img-to-pdf"); addEndpointToGroup("Convert", "img-to-pdf");
addEndpointToGroup("Convert", "pdf-to-pdfa"); addEndpointToGroup("Convert", "pdf-to-pdfa");
addEndpointToGroup("Convert", "file-to-pdf"); addEndpointToGroup("Convert", "file-to-pdf");
addEndpointToGroup("Convert", "xlsx-to-pdf");
addEndpointToGroup("Convert", "pdf-to-word"); addEndpointToGroup("Convert", "pdf-to-word");
addEndpointToGroup("Convert", "pdf-to-presentation"); addEndpointToGroup("Convert", "pdf-to-presentation");
addEndpointToGroup("Convert", "pdf-to-text"); addEndpointToGroup("Convert", "pdf-to-text");
@@ -145,7 +162,6 @@ public class EndpointConfiguration {
addEndpointToGroup("CLI", "repair"); addEndpointToGroup("CLI", "repair");
addEndpointToGroup("CLI", "pdf-to-pdfa"); addEndpointToGroup("CLI", "pdf-to-pdfa");
addEndpointToGroup("CLI", "file-to-pdf"); addEndpointToGroup("CLI", "file-to-pdf");
addEndpointToGroup("CLI", "xlsx-to-pdf");
addEndpointToGroup("CLI", "pdf-to-word"); addEndpointToGroup("CLI", "pdf-to-word");
addEndpointToGroup("CLI", "pdf-to-presentation"); addEndpointToGroup("CLI", "pdf-to-presentation");
addEndpointToGroup("CLI", "pdf-to-html"); addEndpointToGroup("CLI", "pdf-to-html");
@@ -163,25 +179,26 @@ public class EndpointConfiguration {
// python // python
addEndpointToGroup("Python", "extract-image-scans"); addEndpointToGroup("Python", "extract-image-scans");
addEndpointToGroup("Python", REMOVE_BLANKS);
addEndpointToGroup("Python", "html-to-pdf"); addEndpointToGroup("Python", "html-to-pdf");
addEndpointToGroup("Python", "url-to-pdf"); addEndpointToGroup("Python", "url-to-pdf");
addEndpointToGroup("Python", "pdf-to-img"); addEndpointToGroup("Python", "pdf-to-img");
addEndpointToGroup("Python", "file-to-pdf");
// openCV // openCV
addEndpointToGroup("OpenCV", "extract-image-scans"); addEndpointToGroup("OpenCV", "extract-image-scans");
addEndpointToGroup("OpenCV", REMOVE_BLANKS);
// LibreOffice // LibreOffice
addEndpointToGroup("LibreOffice", "repair"); addEndpointToGroup("LibreOffice", "repair");
addEndpointToGroup("LibreOffice", "file-to-pdf"); addEndpointToGroup("LibreOffice", "file-to-pdf");
addEndpointToGroup("LibreOffice", "xlsx-to-pdf");
addEndpointToGroup("LibreOffice", "pdf-to-word"); addEndpointToGroup("LibreOffice", "pdf-to-word");
addEndpointToGroup("LibreOffice", "pdf-to-presentation"); addEndpointToGroup("LibreOffice", "pdf-to-presentation");
addEndpointToGroup("LibreOffice", "pdf-to-rtf"); addEndpointToGroup("LibreOffice", "pdf-to-rtf");
addEndpointToGroup("LibreOffice", "pdf-to-html"); addEndpointToGroup("LibreOffice", "pdf-to-html");
addEndpointToGroup("LibreOffice", "pdf-to-xml"); addEndpointToGroup("LibreOffice", "pdf-to-xml");
// Unoconv
addEndpointToGroup("Unoconv", "file-to-pdf");
// OCRmyPDF // OCRmyPDF
addEndpointToGroup("OCRmyPDF", "compress-pdf"); addEndpointToGroup("OCRmyPDF", "compress-pdf");
addEndpointToGroup("OCRmyPDF", "pdf-to-pdfa"); addEndpointToGroup("OCRmyPDF", "pdf-to-pdfa");
@@ -230,6 +247,18 @@ public class EndpointConfiguration {
addEndpointToGroup("Javascript", "sign"); addEndpointToGroup("Javascript", "sign");
addEndpointToGroup("Javascript", "compare"); addEndpointToGroup("Javascript", "compare");
addEndpointToGroup("Javascript", "adjust-contrast"); addEndpointToGroup("Javascript", "adjust-contrast");
// Ghostscript dependent endpoints
addEndpointToGroup("Ghostscript", "compress-pdf");
addEndpointToGroup("Ghostscript", "pdf-to-pdfa");
addEndpointToGroup("Ghostscript", "repair");
// Weasyprint dependent endpoints
addEndpointToGroup("Weasyprint", "html-to-pdf");
addEndpointToGroup("Weasyprint", "url-to-pdf");
// Pdftohtml dependent endpoints
addEndpointToGroup("Pdftohtml", "pdf-to-html");
} }
private void processEnvironmentConfigs() { private void processEnvironmentConfigs() {
@@ -251,5 +280,9 @@ public class EndpointConfiguration {
} }
} }
public Set<String> getEndpointsForGroup(String group) {
return endpointGroups.getOrDefault(group, new HashSet<>());
}
private static final String REMOVE_BLANKS = "remove-blanks"; private static final String REMOVE_BLANKS = "remove-blanks";
} }

View File

@@ -0,0 +1,148 @@
package stirling.software.SPDF.config;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
@Configuration
@Slf4j
public class ExternalAppDepConfig {
@Autowired private EndpointConfiguration endpointConfiguration;
private boolean isCommandAvailable(String command) {
try {
ProcessBuilder processBuilder = new ProcessBuilder();
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
processBuilder.command("where", command);
} else {
processBuilder.command("which", command);
}
Process process = processBuilder.start();
int exitCode = process.waitFor();
return exitCode == 0;
} catch (Exception e) {
log.debug("Error checking for command {}: {}", command, e.getMessage());
return false;
}
}
private final Map<String, List<String>> commandToGroupMapping =
new HashMap<>() {
{
put("gs", List.of("Ghostscript"));
put("soffice", List.of("LibreOffice"));
put("ocrmypdf", List.of("OCRmyPDF"));
put("weasyprint", List.of("Weasyprint"));
put("pdftohtml", List.of("Pdftohtml"));
put("unoconv", List.of("Unoconv"));
}
};
private List<String> getAffectedFeatures(String group) {
return endpointConfiguration.getEndpointsForGroup(group).stream()
.map(endpoint -> formatEndpointAsFeature(endpoint))
.collect(Collectors.toList());
}
private String formatEndpointAsFeature(String endpoint) {
// First replace common terms
String feature = endpoint.replace("-", " ").replace("pdf", "PDF").replace("img", "image");
// Split into words and capitalize each word
return Arrays.stream(feature.split("\\s+"))
.map(word -> capitalizeWord(word))
.collect(Collectors.joining(" "));
}
private String capitalizeWord(String word) {
if (word.isEmpty()) {
return word;
}
if ("pdf".equalsIgnoreCase(word)) {
return "PDF";
}
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
}
private void checkDependencyAndDisableGroup(String command) {
boolean isAvailable = isCommandAvailable(command);
if (!isAvailable) {
List<String> affectedGroups = commandToGroupMapping.get(command);
if (affectedGroups != null) {
for (String group : affectedGroups) {
List<String> affectedFeatures = getAffectedFeatures(group);
endpointConfiguration.disableGroup(group);
log.warn(
"Missing dependency: {} - Disabling group: {} (Affected features: {})",
command,
group,
affectedFeatures != null && !affectedFeatures.isEmpty()
? String.join(", ", affectedFeatures)
: "unknown");
}
}
}
}
@PostConstruct
public void checkDependencies() {
// Check core dependencies
checkDependencyAndDisableGroup("gs");
checkDependencyAndDisableGroup("soffice");
checkDependencyAndDisableGroup("ocrmypdf");
checkDependencyAndDisableGroup("weasyprint");
checkDependencyAndDisableGroup("pdftohtml");
checkDependencyAndDisableGroup("unoconv");
// Special handling for Python/OpenCV dependencies
boolean pythonAvailable = isCommandAvailable("python3") || isCommandAvailable("python");
if (!pythonAvailable) {
List<String> pythonFeatures = getAffectedFeatures("Python");
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
endpointConfiguration.disableGroup("Python");
endpointConfiguration.disableGroup("OpenCV");
log.warn(
"Missing dependency: Python - Disabling Python features: {} and OpenCV features: {}",
String.join(", ", pythonFeatures),
String.join(", ", openCVFeatures));
} else {
// If Python is available, check for OpenCV
try {
ProcessBuilder processBuilder = new ProcessBuilder();
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
processBuilder.command("python", "-c", "import cv2");
} else {
processBuilder.command("python3", "-c", "import cv2");
}
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode != 0) {
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
endpointConfiguration.disableGroup("OpenCV");
log.warn(
"OpenCV not available in Python - Disabling OpenCV features: {}",
String.join(", ", openCVFeatures));
}
} catch (Exception e) {
List<String> openCVFeatures = getAffectedFeatures("OpenCV");
endpointConfiguration.disableGroup("OpenCV");
log.warn(
"Error checking OpenCV: {} - Disabling OpenCV features: {}",
e.getMessage(),
String.join(", ", openCVFeatures));
}
}
endpointConfiguration.logDisabledEndpointsSummary();
}
}

View File

@@ -8,6 +8,8 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
@@ -39,4 +41,23 @@ public class InitialSetup {
applicationProperties.getAutomaticallyGenerated().setKey(secretKey); applicationProperties.getAutomaticallyGenerated().setKey(secretKey);
} }
} }
@PostConstruct
public void initLegalUrls() throws IOException {
// Initialize Terms and Conditions
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
if (StringUtils.isEmpty(termsUrl)) {
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
GeneralUtils.saveKeyToConfig("legal.termsAndConditions", defaultTermsUrl);
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
}
// Initialize Privacy Policy
String privacyUrl = applicationProperties.getLegal().getPrivacyPolicy();
if (StringUtils.isEmpty(privacyUrl)) {
String defaultPrivacyUrl = "https://www.stirlingpdf.com/privacy-policy";
GeneralUtils.saveKeyToConfig("legal.privacyPolicy", defaultPrivacyUrl);
applicationProperties.getLegal().setPrivacyPolicy(defaultPrivacyUrl);
}
}
} }

View File

@@ -1,27 +1,237 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.io.IOException; import java.io.IOException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.List;
import org.springframework.core.io.Resource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import com.coveo.saml.SamlClient;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.SPdfApplication;
import stirling.software.SPDF.config.security.saml2.CertificateUtils;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
import stirling.software.SPDF.model.Provider;
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
import stirling.software.SPDF.utils.UrlUtils;
@Slf4j
@AllArgsConstructor
public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler { public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
private final ApplicationProperties applicationProperties;
@Override @Override
public void onLogoutSuccess( public void onLogoutSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication) HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException { throws IOException, ServletException {
if (request.getParameter("userIsDisabled") != null) { if (!response.isCommitted()) {
getRedirectStrategy() // Handle user logout due to disabled account
.sendRedirect(request, response, "/login?erroroauth=userIsDisabled"); if (request.getParameter("userIsDisabled") != null) {
return; response.sendRedirect(
request.getContextPath() + "/login?erroroauth=userIsDisabled");
return;
}
// Handle OAuth2 authentication error
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
response.sendRedirect(
request.getContextPath() + "/login?erroroauth=userAlreadyExistsWeb");
return;
}
if (authentication != null) {
// Handle SAML2 logout redirection
if (authentication instanceof Saml2Authentication) {
getRedirect_saml2(request, response, authentication);
return;
}
// Handle OAuth2 logout redirection
else if (authentication instanceof OAuth2AuthenticationToken) {
getRedirect_oauth2(request, response, authentication);
return;
}
// Handle Username/Password logout
else if (authentication instanceof UsernamePasswordAuthenticationToken) {
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
return;
}
// Handle unknown authentication types
else {
log.error(
"authentication class unknown: "
+ authentication.getClass().getSimpleName());
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
return;
}
} else {
// Redirect to login page after logout
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
return;
}
}
}
// Redirect for SAML2 authentication logout
private void getRedirect_saml2(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
String registrationId = samlConf.getRegistrationId();
Saml2Authentication samlAuthentication = (Saml2Authentication) authentication;
CustomSaml2AuthenticatedPrincipal principal =
(CustomSaml2AuthenticatedPrincipal) samlAuthentication.getPrincipal();
String nameIdValue = principal.getName();
try {
// Read certificate from the resource
Resource certificateResource = samlConf.getSpCert();
X509Certificate certificate = CertificateUtils.readCertificate(certificateResource);
List<X509Certificate> certificates = new ArrayList<>();
certificates.add(certificate);
// Construct URLs required for SAML configuration
String serverUrl =
SPdfApplication.getStaticBaseUrl() + ":" + SPdfApplication.getStaticPort();
String relyingPartyIdentifier =
serverUrl + "/saml2/service-provider-metadata/" + registrationId;
String assertionConsumerServiceUrl = serverUrl + "/login/saml2/sso/" + registrationId;
String idpUrl = samlConf.getIdpSingleLogoutUrl();
String idpIssuer = samlConf.getIdpIssuer();
// Create SamlClient instance for SAML logout
SamlClient samlClient =
new SamlClient(
relyingPartyIdentifier,
assertionConsumerServiceUrl,
idpUrl,
idpIssuer,
certificates,
SamlClient.SamlIdpBinding.POST);
// Read private key for service provider
Resource privateKeyResource = samlConf.getPrivateKey();
RSAPrivateKey privateKey = CertificateUtils.readPrivateKey(privateKeyResource);
// Set service provider keys for the SamlClient
samlClient.setSPKeys(certificate, privateKey);
// Redirect to identity provider for logout
samlClient.redirectToIdentityProvider(response, null, nameIdValue);
} catch (Exception e) {
log.error(nameIdValue, e);
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true");
}
}
// Redirect for OAuth2 authentication logout
private void getRedirect_oauth2(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
String param = "logout=true";
String registrationId = null;
String issuer = null;
String clientId = null;
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (authentication instanceof OAuth2AuthenticationToken) {
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
registrationId = oauthToken.getAuthorizedClientRegistrationId();
try {
// Get OAuth2 provider details from configuration
Provider provider = oauth.getClient().get(registrationId);
issuer = provider.getIssuer();
clientId = provider.getClientId();
} catch (UnsupportedProviderException e) {
log.error(e.getMessage());
}
} else {
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
issuer = oauth.getIssuer();
clientId = oauth.getClientId();
}
String errorMessage = "";
// Handle different error scenarios during logout
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
param = "erroroauth=oauth2AuthenticationErrorWeb";
} else if ((errorMessage = request.getParameter("error")) != null) {
param = "error=" + sanitizeInput(errorMessage);
} else if ((errorMessage = request.getParameter("erroroauth")) != null) {
param = "erroroauth=" + sanitizeInput(errorMessage);
} else if (request.getParameter("oauth2AutoCreateDisabled") != null) {
param = "error=oauth2AutoCreateDisabled";
} else if (request.getParameter("oauth2_admin_blocked_user") != null) {
param = "erroroauth=oauth2_admin_blocked_user";
} else if (request.getParameter("userIsDisabled") != null) {
param = "erroroauth=userIsDisabled";
} else if (request.getParameter("badcredentials") != null) {
param = "error=badcredentials";
} }
getRedirectStrategy().sendRedirect(request, response, "/login?logout=true"); String redirect_url = UrlUtils.getOrigin(request) + "/login?" + param;
// Redirect based on OAuth2 provider
switch (registrationId.toLowerCase()) {
case "keycloak":
// Add Keycloak specific logout URL if needed
String logoutUrl =
issuer
+ "/protocol/openid-connect/logout"
+ "?client_id="
+ clientId
+ "&post_logout_redirect_uri="
+ response.encodeRedirectURL(redirect_url);
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
response.sendRedirect(logoutUrl);
break;
case "github":
// Add GitHub specific logout URL if needed
String githubLogoutUrl = "https://github.com/logout";
log.info("Redirecting to GitHub logout URL: " + githubLogoutUrl);
response.sendRedirect(githubLogoutUrl);
break;
case "google":
// Add Google specific logout URL if needed
// String googleLogoutUrl =
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
// + response.encodeRedirectURL(redirect_url);
log.info("Google does not have a specific logout URL");
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
// response.sendRedirect(googleLogoutUrl);
// break;
default:
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
log.info("Redirecting to default logout URL: " + defaultRedirectUrl);
response.sendRedirect(defaultRedirectUrl);
break;
}
}
// Sanitize input to avoid potential security vulnerabilities
private String sanitizeInput(String input) {
return input.replaceAll("[^a-zA-Z0-9 ]", "");
} }
} }

View File

@@ -1,40 +1,63 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.security.cert.X509Certificate;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.core.io.Resource;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.security.saml2.core.Saml2X509Credential.Saml2X509CredentialType;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter; import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.savedrequest.NullRequestCache;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2LogoutSuccessHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
import stirling.software.SPDF.config.security.saml.ConvertResponseToAuthentication; import stirling.software.SPDF.config.security.saml2.CertificateUtils;
import stirling.software.SPDF.config.security.saml.CustomSAMLAuthenticationFailureHandler; import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationFailureHandler;
import stirling.software.SPDF.config.security.saml.CustomSAMLAuthenticationSuccessHandler; import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticationSuccessHandler;
import stirling.software.SPDF.config.security.saml2.CustomSaml2ResponseAuthenticationConverter;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.model.provider.GithubProvider;
import stirling.software.SPDF.model.provider.GoogleProvider;
import stirling.software.SPDF.model.provider.KeycloakProvider;
import stirling.software.SPDF.repository.JPATokenRepositoryImpl; import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
@Configuration @Configuration
@@ -45,12 +68,6 @@ public class SecurityConfiguration {
@Autowired private CustomUserDetailsService userDetailsService; @Autowired private CustomUserDetailsService userDetailsService;
@Autowired(required = false)
private GrantedAuthoritiesMapper userAuthoritiesMapper;
@Autowired(required = false)
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
@Bean @Bean
public PasswordEncoder passwordEncoder() { public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
@@ -71,17 +88,49 @@ public class SecurityConfiguration {
@Autowired private FirstLoginFilter firstLoginFilter; @Autowired private FirstLoginFilter firstLoginFilter;
@Autowired private SessionPersistentRegistry sessionRegistry; @Autowired private SessionPersistentRegistry sessionRegistry;
@Autowired private ConvertResponseToAuthentication convertResponseToAuthentication;
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authenticationManager(authenticationManager(http));
if (loginEnabledValue) { if (loginEnabledValue) {
http.addFilterBefore( http.addFilterBefore(
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
if (applicationProperties.getSecurity().getCsrfDisabled()) { if (applicationProperties.getSecurity().getCsrfDisabled()) {
http.csrf(csrf -> csrf.disable()); http.csrf(csrf -> csrf.disable());
} else {
CookieCsrfTokenRepository cookieRepo =
CookieCsrfTokenRepository.withHttpOnlyFalse();
CsrfTokenRequestAttributeHandler requestHandler =
new CsrfTokenRequestAttributeHandler();
requestHandler.setCsrfRequestAttributeName(null);
http.csrf(
csrf ->
csrf.ignoringRequestMatchers(
request -> {
String apiKey = request.getHeader("X-API-Key");
// If there's no API key, don't ignore CSRF
// (return false)
if (apiKey == null || apiKey.trim().isEmpty()) {
return false;
}
// Validate API key using existing UserService
try {
Optional<User> user =
userService.getUserByApiKey(apiKey);
// If API key is valid, ignore CSRF (return
// true)
// If API key is invalid, don't ignore CSRF
// (return false)
return user.isPresent();
} catch (Exception e) {
// If there's any error validating the API
// key, don't ignore CSRF
return false;
}
})
.csrfTokenRepository(cookieRepo)
.csrfTokenRequestHandler(requestHandler));
} }
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
@@ -94,134 +143,138 @@ public class SecurityConfiguration {
.sessionRegistry(sessionRegistry) .sessionRegistry(sessionRegistry)
.expiredUrl("/login?logout=true")); .expiredUrl("/login?logout=true"));
http.formLogin( http.authenticationProvider(daoAuthenticationProvider());
formLogin -> http.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache()));
formLogin http.logout(
.loginPage("/login") logout ->
.successHandler( logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
new CustomAuthenticationSuccessHandler( .logoutSuccessHandler(
loginAttemptService, userService)) new CustomLogoutSuccessHandler(applicationProperties))
.defaultSuccessUrl("/") .clearAuthentication(true)
.failureHandler( .invalidateHttpSession(true) // Invalidate session
new CustomAuthenticationFailureHandler( .deleteCookies("JSESSIONID", "remember-me"));
loginAttemptService, userService)) http.rememberMe(
.permitAll()) rememberMeConfigurer ->
.requestCache(requestCache -> requestCache.requestCache(new NullRequestCache())) rememberMeConfigurer // Use the configurator directly
.logout( .tokenRepository(persistentTokenRepository())
logout -> .tokenValiditySeconds(14 * 24 * 60 * 60) // 14 days
logout.logoutRequestMatcher( .userDetailsService(
new AntPathRequestMatcher("/logout")) userDetailsService) // Your existing UserDetailsService
.logoutSuccessHandler(new CustomLogoutSuccessHandler()) .useSecureCookie(true) // Enable secure cookie
.invalidateHttpSession(true) // Invalidate session .rememberMeParameter("remember-me") // Form parameter name
.deleteCookies("JSESSIONID", "remember-me")) .rememberMeCookieName("remember-me") // Cookie name
.rememberMe( .alwaysRemember(false));
rememberMeConfigurer -> http.authorizeHttpRequests(
rememberMeConfigurer // Use the configurator directly authz ->
.key("uniqueAndSecret") authz.requestMatchers(
.tokenRepository(persistentTokenRepository()) req -> {
.tokenValiditySeconds(1209600) // 2 weeks String uri = req.getRequestURI();
) String contextPath = req.getContextPath();
.authorizeHttpRequests(
authz ->
authz.requestMatchers(
req -> {
String uri = req.getRequestURI();
String contextPath = req.getContextPath();
// Remove the context path from the URI // Remove the context path from the URI
String trimmedUri = String trimmedUri =
uri.startsWith(contextPath) uri.startsWith(contextPath)
? uri.substring( ? uri.substring(
contextPath contextPath.length())
.length()) : uri;
: uri;
return trimmedUri.startsWith("/login") return trimmedUri.startsWith("/login")
|| trimmedUri.startsWith("/oauth") || trimmedUri.startsWith("/oauth")
|| trimmedUri.startsWith("/saml2") || trimmedUri.startsWith("/saml2")
|| trimmedUri.endsWith(".svg") || trimmedUri.endsWith(".svg")
|| trimmedUri.startsWith( || trimmedUri.startsWith("/register")
"/register") || trimmedUri.startsWith("/error")
|| trimmedUri.startsWith("/error") || trimmedUri.startsWith("/images/")
|| trimmedUri.startsWith("/images/") || trimmedUri.startsWith("/public/")
|| trimmedUri.startsWith("/public/") || trimmedUri.startsWith("/css/")
|| trimmedUri.startsWith("/css/") || trimmedUri.startsWith("/fonts/")
|| trimmedUri.startsWith("/fonts/") || trimmedUri.startsWith("/js/")
|| trimmedUri.startsWith("/js/") || trimmedUri.startsWith(
|| trimmedUri.startsWith( "/api/v1/info/status");
"/api/v1/info/status"); })
}) .permitAll()
.permitAll() .anyRequest()
.anyRequest() .authenticated());
.authenticated());
// Handle User/Password Logins
if (applicationProperties.getSecurity().isUserPass()) {
http.formLogin(
formLogin ->
formLogin
.loginPage("/login")
.successHandler(
new CustomAuthenticationSuccessHandler(
loginAttemptService, userService))
.failureHandler(
new CustomAuthenticationFailureHandler(
loginAttemptService, userService))
.defaultSuccessUrl("/")
.permitAll());
}
// Handle OAUTH2 Logins // Handle OAUTH2 Logins
if (applicationProperties.getSecurity().getOauth2() != null if (applicationProperties.getSecurity().isOauth2Activ()) {
&& applicationProperties.getSecurity().getOauth2().getEnabled()
&& !applicationProperties
.getSecurity()
.getLoginMethod()
.equalsIgnoreCase("normal")) {
http.oauth2Login( http.oauth2Login(
oauth2 -> oauth2 ->
oauth2.loginPage("/oauth2") oauth2.loginPage("/oauth2")
/* /*
This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database. This Custom handler is used to check if the OAUTH2 user trying to log in, already exists in the database.
If user exists, login proceeds as usual. If user does not exist, then it is autocreated but only if 'OAUTH2AutoCreateUser' If user exists, login proceeds as usual. If user does not exist, then it is autocreated but only if 'OAUTH2AutoCreateUser'
is set as true, else login fails with an error message advising the same. is set as true, else login fails with an error message advising the same.
*/ */
.successHandler(
new CustomOAuth2AuthenticationSuccessHandler(
loginAttemptService,
applicationProperties,
userService))
.failureHandler(
new CustomOAuth2AuthenticationFailureHandler())
// Add existing Authorities from the database
.userInfoEndpoint(
userInfoEndpoint ->
userInfoEndpoint
.oidcUserService(
new CustomOAuth2UserService(
applicationProperties,
userService,
loginAttemptService))
.userAuthoritiesMapper(
userAuthoritiesMapper()))
.permitAll());
}
// Handle SAML
if (applicationProperties.getSecurity().isSaml2Activ()
&& applicationProperties.getSystem().getEnableAlphaFunctionality()) {
http.authenticationProvider(samlAuthenticationProvider());
http.saml2Login(
saml2 ->
saml2.loginPage("/saml2")
.successHandler( .successHandler(
new CustomOAuth2AuthenticationSuccessHandler( new CustomSaml2AuthenticationSuccessHandler(
loginAttemptService, loginAttemptService,
applicationProperties, applicationProperties,
userService)) userService))
.failureHandler( .failureHandler(
new CustomOAuth2AuthenticationFailureHandler()) new CustomSaml2AuthenticationFailureHandler())
// Add existing Authorities from the database .permitAll())
.userInfoEndpoint(
userInfoEndpoint ->
userInfoEndpoint
.oidcUserService(
new CustomOAuth2UserService(
applicationProperties,
userService,
loginAttemptService))
.userAuthoritiesMapper(
userAuthoritiesMapper)))
.logout(
logout ->
logout.logoutSuccessHandler(
new CustomOAuth2LogoutSuccessHandler(
applicationProperties)));
}
// Handle SAML
if (applicationProperties.getSecurity().getSaml() != null
&& applicationProperties.getSecurity().getSaml().getEnabled()
&& !applicationProperties
.getSecurity()
.getLoginMethod()
.equalsIgnoreCase("normal")) {
http.saml2Login(
saml2 -> {
saml2.loginPage("/saml2")
.relyingPartyRegistrationRepository(
relyingPartyRegistrationRepository)
.successHandler(
new CustomSAMLAuthenticationSuccessHandler(
loginAttemptService,
userService,
applicationProperties))
.failureHandler(
new CustomSAMLAuthenticationFailureHandler());
})
.addFilterBefore( .addFilterBefore(
userAuthenticationFilter, Saml2WebSsoAuthenticationFilter.class); userAuthenticationFilter, Saml2WebSsoAuthenticationFilter.class);
} }
} else { } else {
if (applicationProperties.getSecurity().getCsrfDisabled()) { if (applicationProperties.getSecurity().getCsrfDisabled()) {
http.csrf(csrf -> csrf.disable()); http.csrf(csrf -> csrf.disable());
} else {
CookieCsrfTokenRepository cookieRepo =
CookieCsrfTokenRepository.withHttpOnlyFalse();
CsrfTokenRequestAttributeHandler requestHandler =
new CsrfTokenRequestAttributeHandler();
requestHandler.setCsrfRequestAttributeName(null);
http.csrf(
csrf ->
csrf.csrfTokenRepository(cookieRepo)
.csrfTokenRequestHandler(requestHandler));
} }
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()); http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
} }
@@ -231,39 +284,234 @@ public class SecurityConfiguration {
@Bean @Bean
@ConditionalOnProperty( @ConditionalOnProperty(
name = "security.saml.enabled", name = "security.saml2.enabled",
havingValue = "true", havingValue = "true",
matchIfMissing = false) matchIfMissing = false)
public AuthenticationProvider samlAuthenticationProvider() { public AuthenticationProvider samlAuthenticationProvider() {
OpenSaml4AuthenticationProvider authenticationProvider = OpenSaml4AuthenticationProvider authenticationProvider =
new OpenSaml4AuthenticationProvider(); new OpenSaml4AuthenticationProvider();
authenticationProvider.setResponseAuthenticationConverter(convertResponseToAuthentication); authenticationProvider.setResponseAuthenticationConverter(
new CustomSaml2ResponseAuthenticationConverter(userService));
return authenticationProvider; return authenticationProvider;
} }
// @Bean // Client Registration Repository for OAUTH2 OIDC Login
// public AuthenticationProvider daoAuthenticationProvider() { @Bean
// DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); @ConditionalOnProperty(
// provider.setUserDetailsService(userDetailsService); // UserDetailsService value = "security.oauth2.enabled",
// provider.setPasswordEncoder(passwordEncoder()); // PasswordEncoder havingValue = "true",
// return provider; matchIfMissing = false)
// } public ClientRegistrationRepository clientRegistrationRepository() {
List<ClientRegistration> registrations = new ArrayList<>();
githubClientRegistration().ifPresent(registrations::add);
oidcClientRegistration().ifPresent(registrations::add);
googleClientRegistration().ifPresent(registrations::add);
keycloakClientRegistration().ifPresent(registrations::add);
if (registrations.isEmpty()) {
log.error("At least one OAuth2 provider must be configured");
System.exit(1);
}
return new InMemoryClientRegistrationRepository(registrations);
}
private Optional<ClientRegistration> googleClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
GoogleProvider google = client.getGoogle();
return google != null && google.isSettingsValid()
? Optional.of(
ClientRegistration.withRegistrationId(google.getName())
.clientId(google.getClientId())
.clientSecret(google.getClientSecret())
.scope(google.getScopes())
.authorizationUri(google.getAuthorizationuri())
.tokenUri(google.getTokenuri())
.userInfoUri(google.getUserinfouri())
.userNameAttributeName(google.getUseAsUsername())
.clientName(google.getClientName())
.redirectUri("{baseUrl}/login/oauth2/code/" + google.getName())
.authorizationGrantType(
org.springframework.security.oauth2.core
.AuthorizationGrantType.AUTHORIZATION_CODE)
.build())
: Optional.empty();
}
private Optional<ClientRegistration> keycloakClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
KeycloakProvider keycloak = client.getKeycloak();
return keycloak != null && keycloak.isSettingsValid()
? Optional.of(
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
.registrationId(keycloak.getName())
.clientId(keycloak.getClientId())
.clientSecret(keycloak.getClientSecret())
.scope(keycloak.getScopes())
.userNameAttributeName(keycloak.getUseAsUsername())
.clientName(keycloak.getClientName())
.build())
: Optional.empty();
}
private Optional<ClientRegistration> githubClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
GithubProvider github = client.getGithub();
return github != null && github.isSettingsValid()
? Optional.of(
ClientRegistration.withRegistrationId(github.getName())
.clientId(github.getClientId())
.clientSecret(github.getClientSecret())
.scope(github.getScopes())
.authorizationUri(github.getAuthorizationuri())
.tokenUri(github.getTokenuri())
.userInfoUri(github.getUserinfouri())
.userNameAttributeName(github.getUseAsUsername())
.clientName(github.getClientName())
.redirectUri("{baseUrl}/login/oauth2/code/" + github.getName())
.authorizationGrantType(
org.springframework.security.oauth2.core
.AuthorizationGrantType.AUTHORIZATION_CODE)
.build())
: Optional.empty();
}
private Optional<ClientRegistration> oidcClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null
|| oauth.getIssuer() == null
|| oauth.getIssuer().isEmpty()
|| oauth.getClientId() == null
|| oauth.getClientId().isEmpty()
|| oauth.getClientSecret() == null
|| oauth.getClientSecret().isEmpty()
|| oauth.getScopes() == null
|| oauth.getScopes().isEmpty()
|| oauth.getUseAsUsername() == null
|| oauth.getUseAsUsername().isEmpty()) {
return Optional.empty();
}
return Optional.of(
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
.registrationId("oidc")
.clientId(oauth.getClientId())
.clientSecret(oauth.getClientSecret())
.scope(oauth.getScopes())
.userNameAttributeName(oauth.getUseAsUsername())
.clientName("OIDC")
.build());
}
@Bean @Bean
public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { @ConditionalOnProperty(
AuthenticationManagerBuilder authenticationManagerBuilder = name = "security.saml2.enabled",
http.getSharedObject(AuthenticationManagerBuilder.class); havingValue = "true",
matchIfMissing = false)
public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exception {
// authenticationManagerBuilder = SAML2 samlConf = applicationProperties.getSecurity().getSaml2();
// authenticationManagerBuilder.authenticationProvider(
// daoAuthenticationProvider()); // Benutzername/Passwort
if (applicationProperties.getSecurity().getSaml() != null Resource privateKeyResource = samlConf.getPrivateKey();
&& applicationProperties.getSecurity().getSaml().getEnabled()) {
authenticationManagerBuilder.authenticationProvider( Resource certificateResource = samlConf.getSpCert();
samlAuthenticationProvider()); // SAML
} Saml2X509Credential signingCredential =
return authenticationManagerBuilder.build(); new Saml2X509Credential(
CertificateUtils.readPrivateKey(privateKeyResource),
CertificateUtils.readCertificate(certificateResource),
Saml2X509CredentialType.SIGNING);
X509Certificate idpCert = CertificateUtils.readCertificate(samlConf.getidpCert());
Saml2X509Credential verificationCredential = Saml2X509Credential.verification(idpCert);
RelyingPartyRegistration rp =
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
.signingX509Credentials((c) -> c.add(signingCredential))
.assertingPartyDetails(
(details) ->
details.entityId(samlConf.getIdpIssuer())
.singleSignOnServiceLocation(
samlConf.getIdpSingleLoginUrl())
.verificationX509Credentials(
(c) -> c.add(verificationCredential))
.wantAuthnRequestsSigned(true))
.build();
return new InMemoryRelyingPartyRegistrationRepository(rp);
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
/*
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
This is required for the internal; 'hasRole()' function to give out the correct role.
*/
@Bean
@ConditionalOnProperty(
value = "security.oauth2.enabled",
havingValue = "true",
matchIfMissing = false)
GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach(
authority -> {
// Add existing OAUTH2 Authorities
mappedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
// Add Authorities from database for existing user, if user is present.
if (authority instanceof OAuth2UserAuthority oauth2Auth) {
String useAsUsername =
applicationProperties
.getSecurity()
.getOauth2()
.getUseAsUsername();
Optional<User> userOpt =
userService.findByUsernameIgnoreCase(
(String) oauth2Auth.getAttributes().get(useAsUsername));
if (userOpt.isPresent()) {
User user = userOpt.get();
if (user != null) {
mappedAuthorities.add(
new SimpleGrantedAuthority(
userService.findRole(user).getAuthority()));
}
}
}
});
return mappedAuthorities;
};
} }
@Bean @Bean

View File

@@ -22,6 +22,7 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.ApiKeyAuthenticationToken; import stirling.software.SPDF.model.ApiKeyAuthenticationToken;
import stirling.software.SPDF.model.User; import stirling.software.SPDF.model.User;
@@ -111,7 +112,9 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter() response.getWriter()
.write( .write(
"Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternatively you can disable authentication if this is unexpected"); "Authentication required. Please provide a X-API-KEY in request header.\n"
+ "This is found in Settings -> Account Settings -> API Key\n"
+ "Alternatively you can disable authentication if this is unexpected");
return; return;
} }
} }
@@ -124,6 +127,8 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
username = ((UserDetails) principal).getUsername(); username = ((UserDetails) principal).getUsername();
} else if (principal instanceof OAuth2User) { } else if (principal instanceof OAuth2User) {
username = ((OAuth2User) principal).getName(); username = ((OAuth2User) principal).getName();
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
username = ((CustomSaml2AuthenticatedPrincipal) principal).getName();
} else if (principal instanceof String) { } else if (principal instanceof String) {
username = (String) principal; username = (String) principal;
} }

View File

@@ -19,9 +19,12 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface; import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface; import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.AuthenticationType; import stirling.software.SPDF.model.AuthenticationType;
import stirling.software.SPDF.model.Authority; import stirling.software.SPDF.model.Authority;
import stirling.software.SPDF.model.Role; import stirling.software.SPDF.model.Role;
@@ -30,6 +33,7 @@ import stirling.software.SPDF.repository.AuthorityRepository;
import stirling.software.SPDF.repository.UserRepository; import stirling.software.SPDF.repository.UserRepository;
@Service @Service
@Slf4j
public class UserService implements UserServiceInterface { public class UserService implements UserServiceInterface {
@Autowired private UserRepository userRepository; @Autowired private UserRepository userRepository;
@@ -44,9 +48,7 @@ public class UserService implements UserServiceInterface {
@Autowired DatabaseBackupInterface databaseBackupHelper; @Autowired DatabaseBackupInterface databaseBackupHelper;
public long getTotalUserCount() { @Autowired ApplicationProperties applicationProperties;
return userRepository.count();
}
// Handle OAUTH2 login and user auto creation. // Handle OAUTH2 login and user auto creation.
public boolean processOAuth2PostLogin(String username, boolean autoCreateUser) public boolean processOAuth2PostLogin(String username, boolean autoCreateUser)
@@ -302,7 +304,13 @@ public class UserService implements UserServiceInterface {
boolean isValidEmail = boolean isValidEmail =
username.matches( username.matches(
"^(?=.{1,64}@)[A-Za-z0-9]+(\\.[A-Za-z0-9_+.-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$"); "^(?=.{1,64}@)[A-Za-z0-9]+(\\.[A-Za-z0-9_+.-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$");
return isValidSimpleUsername || isValidEmail;
List<String> notAllowedUserList = new ArrayList<>();
notAllowedUserList.add("ALL_USERS".toLowerCase());
boolean notAllowedUser = notAllowedUserList.contains(username.toLowerCase());
return (isValidSimpleUsername || isValidEmail) && !notAllowedUser;
} }
private String getInvalidUsernameMessage() { private String getInvalidUsernameMessage() {
@@ -338,6 +346,10 @@ public class UserService implements UserServiceInterface {
} else if (principal instanceof OAuth2User) { } else if (principal instanceof OAuth2User) {
OAuth2User oAuth2User = (OAuth2User) principal; OAuth2User oAuth2User = (OAuth2User) principal;
usernameP = oAuth2User.getName(); usernameP = oAuth2User.getName();
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
CustomSaml2AuthenticatedPrincipal saml2User =
(CustomSaml2AuthenticatedPrincipal) principal;
usernameP = saml2User.getName();
} else if (principal instanceof String) { } else if (principal instanceof String) {
usernameP = (String) principal; usernameP = (String) principal;
} }
@@ -353,8 +365,21 @@ public class UserService implements UserServiceInterface {
if (principal instanceof UserDetails) { if (principal instanceof UserDetails) {
return ((UserDetails) principal).getUsername(); return ((UserDetails) principal).getUsername();
} else if (principal instanceof OAuth2User) {
return ((OAuth2User) principal)
.getAttribute(
applicationProperties.getSecurity().getOauth2().getUseAsUsername());
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
return ((CustomSaml2AuthenticatedPrincipal) principal).getName();
} else if (principal instanceof String) {
return (String) principal;
} else { } else {
return principal.toString(); return principal.toString();
} }
} }
@Override
public long getTotalUsersCount() {
return userRepository.count();
}
} }

View File

@@ -51,8 +51,7 @@ public class CustomOAuth2AuthenticationFailureHandler
} }
log.error("OAuth2 Authentication error: " + errorCode); log.error("OAuth2 Authentication error: " + errorCode);
log.error("OAuth2AuthenticationException", exception); log.error("OAuth2AuthenticationException", exception);
getRedirectStrategy() getRedirectStrategy().sendRedirect(request, response, "/login?erroroauth=" + errorCode);
.sendRedirect(request, response, "/logout?erroroauth=" + errorCode);
return; return;
} }
log.error("Unhandled authentication exception", exception); log.error("Unhandled authentication exception", exception);

View File

@@ -75,6 +75,11 @@ public class CustomOAuth2AuthenticationSuccessHandler
throw new LockedException( throw new LockedException(
"Your account has been locked due to too many failed login attempts."); "Your account has been locked due to too many failed login attempts.");
} }
if (userService.isUserDisabled(username)) {
getRedirectStrategy()
.sendRedirect(request, response, "/logout?userIsDisabled=true");
return;
}
if (userService.usernameExistsIgnoreCase(username) if (userService.usernameExistsIgnoreCase(username)
&& userService.hasPassword(username) && userService.hasPassword(username)
&& !userService.isAuthenticationTypeByUsername( && !userService.isAuthenticationTypeByUsername(

View File

@@ -1,122 +0,0 @@
package stirling.software.SPDF.config.security.oauth2;
import java.io.IOException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.Provider;
import stirling.software.SPDF.model.provider.UnsupportedProviderException;
import stirling.software.SPDF.utils.UrlUtils;
@Slf4j
public class CustomOAuth2LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
private final ApplicationProperties applicationProperties;
public CustomOAuth2LogoutSuccessHandler(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
@Override
public void onLogoutSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String param = "logout=true";
String registrationId = null;
String issuer = null;
String clientId = null;
if (authentication == null) {
if (request.getParameter("userIsDisabled") != null) {
response.sendRedirect(
request.getContextPath() + "/login?erroroauth=userIsDisabled");
} else {
super.onLogoutSuccess(request, response, authentication);
}
return;
}
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (authentication instanceof OAuth2AuthenticationToken) {
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
registrationId = oauthToken.getAuthorizedClientRegistrationId();
try {
Provider provider = oauth.getClient().get(registrationId);
issuer = provider.getIssuer();
clientId = provider.getClientId();
} catch (UnsupportedProviderException e) {
log.error(e.getMessage());
}
} else {
registrationId = oauth.getProvider() != null ? oauth.getProvider() : "";
issuer = oauth.getIssuer();
clientId = oauth.getClientId();
}
String errorMessage = "";
if (request.getParameter("oauth2AuthenticationErrorWeb") != null) {
param = "erroroauth=oauth2AuthenticationErrorWeb";
} else if ((errorMessage = request.getParameter("error")) != null) {
param = "error=" + sanitizeInput(errorMessage);
} else if ((errorMessage = request.getParameter("erroroauth")) != null) {
param = "erroroauth=" + sanitizeInput(errorMessage);
} else if (request.getParameter("oauth2AutoCreateDisabled") != null) {
param = "error=oauth2AutoCreateDisabled";
} else if (request.getParameter("oauth2_admin_blocked_user") != null) {
param = "erroroauth=oauth2_admin_blocked_user";
} else if (request.getParameter("userIsDisabled") != null) {
param = "erroroauth=userIsDisabled";
} else if (request.getParameter("badcredentials") != null) {
param = "error=badcredentials";
}
String redirect_url = UrlUtils.getOrigin(request) + "/login?" + param;
switch (registrationId.toLowerCase()) {
case "keycloak":
// Add Keycloak specific logout URL if needed
String logoutUrl =
issuer
+ "/protocol/openid-connect/logout"
+ "?client_id="
+ clientId
+ "&post_logout_redirect_uri="
+ response.encodeRedirectURL(redirect_url);
log.info("Redirecting to Keycloak logout URL: " + logoutUrl);
response.sendRedirect(logoutUrl);
break;
case "github":
// Add GitHub specific logout URL if needed
String githubLogoutUrl = "https://github.com/logout";
log.info("Redirecting to GitHub logout URL: " + githubLogoutUrl);
response.sendRedirect(githubLogoutUrl);
break;
case "google":
// Add Google specific logout URL if needed
// String googleLogoutUrl =
// "https://accounts.google.com/Logout?continue=https://appengine.google.com/_ah/logout?continue="
// + response.encodeRedirectURL(redirect_url);
log.info("Google does not have a specific logout URL");
// log.info("Redirecting to Google logout URL: " + googleLogoutUrl);
// response.sendRedirect(googleLogoutUrl);
// break;
default:
String defaultRedirectUrl = request.getContextPath() + "/login?" + param;
log.info("Redirecting to default logout URL: " + defaultRedirectUrl);
response.sendRedirect(defaultRedirectUrl);
break;
}
}
private String sanitizeInput(String input) {
return input.replaceAll("[^a-zA-Z0-9 ]", "");
}
}

View File

@@ -1,68 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.opensaml.saml.saml2.core.Assertion;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class ConvertResponseToAuthentication
implements Converter<ResponseToken, Saml2Authentication> {
private final Saml2AuthorityAttributeLookup saml2AuthorityAttributeLookup;
public ConvertResponseToAuthentication(
Saml2AuthorityAttributeLookup saml2AuthorityAttributeLookup) {
this.saml2AuthorityAttributeLookup = saml2AuthorityAttributeLookup;
}
@Override
public Saml2Authentication convert(ResponseToken responseToken) {
final Assertion assertion =
CollectionUtils.firstElement(responseToken.getResponse().getAssertions());
final Map<String, List<Object>> attributes =
SamlAssertionUtils.getAssertionAttributes(assertion);
final String registrationId =
responseToken.getToken().getRelyingPartyRegistration().getRegistrationId();
final ScimSaml2AuthenticatedPrincipal principal =
new ScimSaml2AuthenticatedPrincipal(
assertion,
attributes,
saml2AuthorityAttributeLookup.getIdentityMappings(registrationId));
final Collection<? extends GrantedAuthority> assertionAuthorities =
getAssertionAuthorities(
attributes,
saml2AuthorityAttributeLookup.getAuthorityAttribute(registrationId));
return new Saml2Authentication(
principal, responseToken.getToken().getSaml2Response(), assertionAuthorities);
}
private static Collection<? extends GrantedAuthority> getAssertionAuthorities(
final Map<String, List<Object>> attributes, final String authoritiesAttributeName) {
if (attributes == null || attributes.isEmpty()) {
return Collections.emptySet();
}
final List<Object> groups = new ArrayList<>(attributes.get(authoritiesAttributeName));
return groups.stream()
.filter(String.class::isInstance)
.map(String.class::cast)
.map(String::toLowerCase)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toSet());
}
}

View File

@@ -1,51 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.io.IOException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CustomSAMLAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
if (exception instanceof BadCredentialsException) {
log.error("BadCredentialsException", exception);
getRedirectStrategy().sendRedirect(request, response, "/login?error=badcredentials");
return;
}
if (exception instanceof DisabledException) {
log.error("User is deactivated: ", exception);
getRedirectStrategy().sendRedirect(request, response, "/logout?userIsDisabled=true");
return;
}
if (exception instanceof LockedException) {
log.error("Account locked: ", exception);
getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked");
return;
}
if (exception instanceof Saml2AuthenticationException) {
log.error("SAML2 Authentication error: ", exception);
getRedirectStrategy()
.sendRedirect(request, response, "/logout?error=saml2AuthenticationError");
return;
}
log.error("Unhandled authentication exception", exception);
super.onAuthenticationFailure(request, response, exception);
}
}

View File

@@ -1,108 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.io.IOException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.LoginAttemptService;
import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.AuthenticationType;
import stirling.software.SPDF.utils.RequestUriUtils;
@Slf4j
public class CustomSAMLAuthenticationSuccessHandler
extends SavedRequestAwareAuthenticationSuccessHandler {
private LoginAttemptService loginAttemptService;
private UserService userService;
private ApplicationProperties applicationProperties;
public CustomSAMLAuthenticationSuccessHandler(
LoginAttemptService loginAttemptService,
UserService userService,
ApplicationProperties applicationProperties) {
this.loginAttemptService = loginAttemptService;
this.userService = userService;
this.applicationProperties = applicationProperties;
}
@Override
public void onAuthenticationSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
Object principal = authentication.getPrincipal();
String username = "";
if (principal instanceof OAuth2User) {
OAuth2User oauthUser = (OAuth2User) principal;
username = oauthUser.getName();
} else if (principal instanceof UserDetails) {
UserDetails oauthUser = (UserDetails) principal;
username = oauthUser.getUsername();
} else if (principal instanceof ScimSaml2AuthenticatedPrincipal) {
ScimSaml2AuthenticatedPrincipal samlPrincipal =
(ScimSaml2AuthenticatedPrincipal) principal;
username = samlPrincipal.getName();
}
// Get the saved request
HttpSession session = request.getSession(false);
String contextPath = request.getContextPath();
SavedRequest savedRequest =
(session != null)
? (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")
: null;
if (savedRequest != null
&& !RequestUriUtils.isStaticResource(contextPath, savedRequest.getRedirectUrl())) {
// Redirect to the original destination
super.onAuthenticationSuccess(request, response, authentication);
} else {
OAUTH2 oAuth = applicationProperties.getSecurity().getOauth2();
if (loginAttemptService.isBlocked(username)) {
if (session != null) {
session.removeAttribute("SPRING_SECURITY_SAVED_REQUEST");
}
throw new LockedException(
"Your account has been locked due to too many failed login attempts.");
}
if (userService.usernameExistsIgnoreCase(username)
&& userService.hasPassword(username)
&& !userService.isAuthenticationTypeByUsername(
username, AuthenticationType.OAUTH2)
&& oAuth.getAutoCreateUser()) {
response.sendRedirect(contextPath + "/logout?oauth2AuthenticationErrorWeb=true");
return;
}
try {
if (oAuth.getBlockRegistration()
&& !userService.usernameExistsIgnoreCase(username)) {
response.sendRedirect(contextPath + "/logout?oauth2_admin_blocked_user=true");
return;
}
if (principal instanceof OAuth2User) {
userService.processOAuth2PostLogin(username, oAuth.getAutoCreateUser());
}
response.sendRedirect(contextPath + "/");
return;
} catch (IllegalArgumentException e) {
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
return;
}
}
}
}

View File

@@ -1,38 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.io.IOException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SAMLLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Override
public void onLogoutSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String redirectUrl = determineTargetUrl(request, response, authentication);
if (response.isCommitted()) {
log.debug("Response has already been committed. Unable to redirect to " + redirectUrl);
return;
}
getRedirectStrategy().sendRedirect(request, response, redirectUrl);
}
protected String determineTargetUrl(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {
// Default to the root URL
return "/";
}
}

View File

@@ -1,7 +0,0 @@
package stirling.software.SPDF.config.security.saml;
public interface Saml2AuthorityAttributeLookup {
String getAuthorityAttribute(String registrationId);
SimpleScimMappings getIdentityMappings(String registrationId);
}

View File

@@ -1,17 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import org.springframework.stereotype.Component;
@Component
public class Saml2AuthorityAttributeLookupImpl implements Saml2AuthorityAttributeLookup {
@Override
public String getAuthorityAttribute(String registrationId) {
return "authorityAttributeName";
}
@Override
public SimpleScimMappings getIdentityMappings(String registrationId) {
return new SimpleScimMappings();
}
}

View File

@@ -1,63 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.time.Instant;
import java.util.*;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.schema.*;
import org.opensaml.saml.saml2.core.Assertion;
public class SamlAssertionUtils {
public static Map<String, List<Object>> getAssertionAttributes(Assertion assertion) {
Map<String, List<Object>> attributeMap = new LinkedHashMap<>();
assertion
.getAttributeStatements()
.forEach(
attributeStatement -> {
attributeStatement
.getAttributes()
.forEach(
attribute -> {
List<Object> attributeValues = new ArrayList<>();
attribute
.getAttributeValues()
.forEach(
xmlObject -> {
Object attributeValue =
getXmlObjectValue(
xmlObject);
if (attributeValue != null) {
attributeValues.add(
attributeValue);
}
});
attributeMap.put(
attribute.getName(), attributeValues);
});
});
return attributeMap;
}
public static Object getXmlObjectValue(XMLObject xmlObject) {
if (xmlObject instanceof XSAny) {
return ((XSAny) xmlObject).getTextContent();
} else if (xmlObject instanceof XSString) {
return ((XSString) xmlObject).getValue();
} else if (xmlObject instanceof XSInteger) {
return ((XSInteger) xmlObject).getValue();
} else if (xmlObject instanceof XSURI) {
return ((XSURI) xmlObject).getURI();
} else if (xmlObject instanceof XSBoolean) {
return ((XSBoolean) xmlObject).getValue().getValue();
} else if (xmlObject instanceof XSDateTime) {
Instant dateTime = ((XSDateTime) xmlObject).getValue();
return (dateTime != null) ? Instant.ofEpochMilli(dateTime.toEpochMilli()) : null;
}
return null;
}
}

View File

@@ -1,42 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.security.cert.CertificateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
@Configuration
@Slf4j
public class SamlConfig {
@Autowired ApplicationProperties applicationProperties;
@Bean
@ConditionalOnProperty(
value = "security.saml.enabled",
havingValue = "true",
matchIfMissing = false)
public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository()
throws CertificateException {
RelyingPartyRegistration registration =
RelyingPartyRegistrations.fromMetadataLocation(
applicationProperties
.getSecurity()
.getSaml()
.getIdpMetadataLocation())
.entityId(applicationProperties.getSecurity().getSaml().getEntityId())
.registrationId(
applicationProperties.getSecurity().getSaml().getRegistrationId())
.build();
return new InMemoryRelyingPartyRegistrationRepository(registration);
}
}

View File

@@ -1,89 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.opensaml.saml.saml2.core.Assertion;
import org.springframework.security.core.AuthenticatedPrincipal;
import org.springframework.util.Assert;
import com.unboundid.scim2.common.types.Email;
import com.unboundid.scim2.common.types.Name;
import com.unboundid.scim2.common.types.UserResource;
public class ScimSaml2AuthenticatedPrincipal implements AuthenticatedPrincipal, Serializable {
private static final long serialVersionUID = 1L;
private final transient UserResource userResource;
public ScimSaml2AuthenticatedPrincipal(
final Assertion assertion,
final Map<String, List<Object>> attributes,
final SimpleScimMappings attributeMappings) {
Assert.notNull(assertion, "assertion cannot be null");
Assert.notNull(assertion.getSubject(), "assertion subject cannot be null");
Assert.notNull(
assertion.getSubject().getNameID(), "assertion subject NameID cannot be null");
Assert.notNull(attributes, "attributes cannot be null");
Assert.notNull(attributeMappings, "attributeMappings cannot be null");
final Name name =
new Name()
.setFamilyName(
getAttribute(
attributes,
attributeMappings,
SimpleScimMappings::getFamilyName))
.setGivenName(
getAttribute(
attributes,
attributeMappings,
SimpleScimMappings::getGivenName));
final List<Email> emails = new ArrayList<>(1);
emails.add(
new Email()
.setValue(
getAttribute(
attributes,
attributeMappings,
SimpleScimMappings::getEmail))
.setPrimary(true));
userResource =
new UserResource()
.setUserName(assertion.getSubject().getNameID().getValue())
.setName(name)
.setEmails(emails);
}
private static String getAttribute(
final Map<String, List<Object>> attributes,
final SimpleScimMappings simpleScimMappings,
final Function<SimpleScimMappings, String> attributeMapper) {
final String key = attributeMapper.apply(simpleScimMappings);
final List<Object> values = attributes.getOrDefault(key, Collections.emptyList());
return values.stream()
.filter(String.class::isInstance)
.map(String.class::cast)
.findFirst()
.orElse(null);
}
@Override
public String getName() {
return this.userResource.getUserName();
}
public UserResource getUserResource() {
return this.userResource;
}
}

View File

@@ -1,10 +0,0 @@
package stirling.software.SPDF.config.security.saml;
import lombok.Data;
@Data
public class SimpleScimMappings {
String givenName;
String familyName;
String email;
}

View File

@@ -0,0 +1,42 @@
package stirling.software.SPDF.config.security.saml2;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.springframework.core.io.Resource;
public class CertificateUtils {
public static X509Certificate readCertificate(Resource certificateResource) throws Exception {
try (PemReader pemReader =
new PemReader(
new InputStreamReader(
certificateResource.getInputStream(), StandardCharsets.UTF_8))) {
PemObject pemObject = pemReader.readPemObject();
byte[] decodedCert = pemObject.getContent();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(decodedCert));
}
}
public static RSAPrivateKey readPrivateKey(Resource privateKeyResource) throws Exception {
try (PemReader pemReader =
new PemReader(
new InputStreamReader(
privateKeyResource.getInputStream(), StandardCharsets.UTF_8))) {
PemObject pemObject = pemReader.readPemObject();
byte[] decodedKey = pemObject.getContent();
return (RSAPrivateKey)
KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(decodedKey));
}
}
}

View File

@@ -0,0 +1,45 @@
package stirling.software.SPDF.config.security.saml2;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
public class CustomSaml2AuthenticatedPrincipal
implements Saml2AuthenticatedPrincipal, Serializable {
private final String name;
private final Map<String, List<Object>> attributes;
private final String nameId;
private final List<String> sessionIndexes;
public CustomSaml2AuthenticatedPrincipal(
String name,
Map<String, List<Object>> attributes,
String nameId,
List<String> sessionIndexes) {
this.name = name;
this.attributes = attributes;
this.nameId = nameId;
this.sessionIndexes = sessionIndexes;
}
@Override
public String getName() {
return this.name;
}
@Override
public Map<String, List<Object>> getAttributes() {
return this.attributes;
}
public String getNameId() {
return this.nameId;
}
public List<String> getSessionIndexes() {
return this.sessionIndexes;
}
}

View File

@@ -0,0 +1,38 @@
package stirling.software.SPDF.config.security.saml2;
import java.io.IOException;
import org.springframework.security.authentication.ProviderNotFoundException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CustomSaml2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception)
throws IOException, ServletException {
if (exception instanceof Saml2AuthenticationException) {
Saml2Error error = ((Saml2AuthenticationException) exception).getSaml2Error();
getRedirectStrategy()
.sendRedirect(request, response, "/login?erroroauth=" + error.getErrorCode());
} else if (exception instanceof ProviderNotFoundException) {
getRedirectStrategy()
.sendRedirect(
request,
response,
"/login?erroroauth=not_authentication_provider_found");
}
log.error("AuthenticationException: " + exception);
}
}

View File

@@ -0,0 +1,91 @@
package stirling.software.SPDF.config.security.saml2;
import java.io.IOException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import stirling.software.SPDF.config.security.LoginAttemptService;
import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
import stirling.software.SPDF.model.AuthenticationType;
import stirling.software.SPDF.utils.RequestUriUtils;
@AllArgsConstructor
public class CustomSaml2AuthenticationSuccessHandler
extends SavedRequestAwareAuthenticationSuccessHandler {
private LoginAttemptService loginAttemptService;
private ApplicationProperties applicationProperties;
private UserService userService;
@Override
public void onAuthenticationSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
Object principal = authentication.getPrincipal();
if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
String username = ((CustomSaml2AuthenticatedPrincipal) principal).getName();
// Get the saved request
HttpSession session = request.getSession(false);
String contextPath = request.getContextPath();
SavedRequest savedRequest =
(session != null)
? (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")
: null;
if (savedRequest != null
&& !RequestUriUtils.isStaticResource(
contextPath, savedRequest.getRedirectUrl())) {
// Redirect to the original destination
super.onAuthenticationSuccess(request, response, authentication);
} else {
SAML2 saml2 = applicationProperties.getSecurity().getSaml2();
if (loginAttemptService.isBlocked(username)) {
if (session != null) {
session.removeAttribute("SPRING_SECURITY_SAVED_REQUEST");
}
throw new LockedException(
"Your account has been locked due to too many failed login attempts.");
}
if (userService.usernameExistsIgnoreCase(username)
&& userService.hasPassword(username)
&& !userService.isAuthenticationTypeByUsername(
username, AuthenticationType.OAUTH2)
&& saml2.getAutoCreateUser()) {
response.sendRedirect(
contextPath + "/logout?oauth2AuthenticationErrorWeb=true");
return;
}
try {
if (saml2.getBlockRegistration()
&& !userService.usernameExistsIgnoreCase(username)) {
response.sendRedirect(
contextPath + "/login?erroroauth=oauth2_admin_blocked_user");
return;
}
userService.processOAuth2PostLogin(username, saml2.getAutoCreateUser());
response.sendRedirect(contextPath + "/");
return;
} catch (IllegalArgumentException e) {
response.sendRedirect(contextPath + "/logout?invalidUsername=true");
return;
}
}
} else {
super.onAuthenticationSuccess(request, response, authentication);
}
}
}

View File

@@ -0,0 +1,86 @@
package stirling.software.SPDF.config.security.saml2;
import java.util.*;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.schema.XSBoolean;
import org.opensaml.core.xml.schema.XSString;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Attribute;
import org.opensaml.saml.saml2.core.AttributeStatement;
import org.opensaml.saml.saml2.core.AuthnStatement;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider.ResponseToken;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.model.User;
@Component
@Slf4j
public class CustomSaml2ResponseAuthenticationConverter
implements Converter<ResponseToken, Saml2Authentication> {
private UserService userService;
public CustomSaml2ResponseAuthenticationConverter(UserService userService) {
this.userService = userService;
}
@Override
public Saml2Authentication convert(ResponseToken responseToken) {
// Extract the assertion from the response
Assertion assertion = responseToken.getResponse().getAssertions().get(0);
// Extract the NameID
String nameId = assertion.getSubject().getNameID().getValue();
Optional<User> userOpt = userService.findByUsernameIgnoreCase(nameId);
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("ROLE_USER");
if (userOpt.isPresent()) {
User user = userOpt.get();
if (user != null) {
simpleGrantedAuthority =
new SimpleGrantedAuthority(userService.findRole(user).getAuthority());
}
}
// Extract the SessionIndexes
List<String> sessionIndexes = new ArrayList<>();
for (AuthnStatement authnStatement : assertion.getAuthnStatements()) {
sessionIndexes.add(authnStatement.getSessionIndex());
}
// Extract the Attributes
Map<String, List<Object>> attributes = extractAttributes(assertion);
// Create the custom principal
CustomSaml2AuthenticatedPrincipal principal =
new CustomSaml2AuthenticatedPrincipal(nameId, attributes, nameId, sessionIndexes);
// Create the Saml2Authentication
return new Saml2Authentication(
principal,
responseToken.getToken().getSaml2Response(),
Collections.singletonList(simpleGrantedAuthority));
}
private Map<String, List<Object>> extractAttributes(Assertion assertion) {
Map<String, List<Object>> attributes = new HashMap<>();
for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) {
for (Attribute attribute : attributeStatement.getAttributes()) {
String attributeName = attribute.getName();
List<Object> values = new ArrayList<>();
for (XMLObject xmlObject : attribute.getAttributeValues()) {
log.info("BOOL: " + ((XSBoolean) xmlObject).getValue());
values.add(((XSString) xmlObject).getValue());
}
attributes.put(attributeName, values);
}
}
return attributes;
}
}

View File

@@ -16,6 +16,7 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.model.SessionEntity; import stirling.software.SPDF.model.SessionEntity;
@Component @Component
@@ -50,6 +51,8 @@ public class SessionPersistentRegistry implements SessionRegistry {
principalName = ((UserDetails) principal).getUsername(); principalName = ((UserDetails) principal).getUsername();
} else if (principal instanceof OAuth2User) { } else if (principal instanceof OAuth2User) {
principalName = ((OAuth2User) principal).getName(); principalName = ((OAuth2User) principal).getName();
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
principalName = ((CustomSaml2AuthenticatedPrincipal) principal).getName();
} else if (principal instanceof String) { } else if (principal instanceof String) {
principalName = (String) principal; principalName = (String) principal;
} }
@@ -79,6 +82,8 @@ public class SessionPersistentRegistry implements SessionRegistry {
principalName = ((UserDetails) principal).getUsername(); principalName = ((UserDetails) principal).getUsername();
} else if (principal instanceof OAuth2User) { } else if (principal instanceof OAuth2User) {
principalName = ((OAuth2User) principal).getName(); principalName = ((OAuth2User) principal).getName();
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
principalName = ((CustomSaml2AuthenticatedPrincipal) principal).getName();
} else if (principal instanceof String) { } else if (principal instanceof String) {
principalName = (String) principal; principalName = (String) principal;
} }

View File

@@ -0,0 +1,65 @@
package stirling.software.SPDF.controller.api;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletResponse;
import stirling.software.SPDF.service.LanguageService;
@RestController
@RequestMapping("/js")
public class AdditionalLanguageJsController {
@Autowired private LanguageService languageService;
@Hidden
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
List<String> supportedLanguages = languageService.getSupportedLanguages();
response.setContentType("application/javascript");
PrintWriter writer = response.getWriter();
// Erstelle das JavaScript dynamisch
writer.println("const supportedLanguages = " + toJsonArray(supportedLanguages) + ";");
// Generiere die `getDetailedLanguageCode`-Funktion
writer.println(
"""
function getDetailedLanguageCode() {
const userLanguages = navigator.languages ? navigator.languages : [navigator.language];
for (let lang of userLanguages) {
let matchedLang = supportedLanguages.find(supportedLang => supportedLang.startsWith(lang.replace('-', '_')));
if (matchedLang) {
return matchedLang;
}
}
// Fallback
return "en_GB";
}
""");
writer.flush();
}
// Hilfsfunktion zum Konvertieren der Liste in ein JSON-Array
private String toJsonArray(List<String> list) {
StringBuilder jsonArray = new StringBuilder("[");
for (int i = 0; i < list.size(); i++) {
jsonArray.append("\"").append(list.get(i)).append("\"");
if (i < list.size() - 1) {
jsonArray.append(",");
}
}
jsonArray.append("]");
return jsonArray.toString();
}
}

View File

@@ -32,6 +32,7 @@ public class SettingsController {
} }
GeneralUtils.saveKeyToConfig("system.enableAnalytics", String.valueOf(enabled), false); GeneralUtils.saveKeyToConfig("system.enableAnalytics", String.valueOf(enabled), false);
applicationProperties.getSystem().setEnableAnalytics(String.valueOf(enabled)); applicationProperties.getSystem().setEnableAnalytics(String.valueOf(enabled));
return ResponseEntity.ok("Updated"); return ResponseEntity.ok("Updated");
} }
} }

View File

@@ -32,6 +32,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.UserService; import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.AuthenticationType; import stirling.software.SPDF.model.AuthenticationType;
import stirling.software.SPDF.model.Role; import stirling.software.SPDF.model.Role;
@@ -336,6 +337,8 @@ public class UserController {
userNameP = ((UserDetails) principal).getUsername(); userNameP = ((UserDetails) principal).getUsername();
} else if (principal instanceof OAuth2User) { } else if (principal instanceof OAuth2User) {
userNameP = ((OAuth2User) principal).getName(); userNameP = ((OAuth2User) principal).getName();
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
userNameP = ((CustomSaml2AuthenticatedPrincipal) principal).getName();
} else if (principal instanceof String) { } else if (principal instanceof String) {
userNameP = (String) principal; userNameP = (String) principal;
} }

View File

@@ -13,12 +13,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest; import stirling.software.SPDF.model.api.misc.ReplaceAndInvertColorRequest;
import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService; import stirling.software.SPDF.service.misc.ReplaceAndInvertColorService;
@RestController @RestController
@RequestMapping("/api/v1/misc") @RequestMapping("/api/v1/misc")
@Tag(name = "Misc", description = "Miscellaneous APIs")
public class ReplaceAndInvertColorController { public class ReplaceAndInvertColorController {
private ReplaceAndInvertColorService replaceAndInvertColorService; private ReplaceAndInvertColorService replaceAndInvertColorService;

View File

@@ -4,4 +4,6 @@ public interface UserServiceInterface {
String getApiKeyForUser(String username); String getApiKeyForUser(String username);
String getCurrentUsername(); String getCurrentUsername();
long getTotalUsersCount();
} }

View File

@@ -1,10 +1,14 @@
package stirling.software.SPDF.controller.api.security; package stirling.software.SPDF.controller.api.security;
import java.awt.Color;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@@ -14,12 +18,39 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Calendar; import java.util.Calendar;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.examples.signature.CreateSignatureBase; import org.apache.pdfbox.examples.signature.CreateSignatureBase;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName;
import org.apache.pdfbox.pdmodel.graphics.blend.BlendMode;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.apache.pdfbox.util.Matrix;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider; import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair; import org.bouncycastle.openssl.PEMEncryptedKeyPair;
@@ -35,6 +66,7 @@ import org.bouncycastle.pkcs.PKCSException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@@ -62,6 +94,8 @@ public class CertSignController {
} }
class CreateSignature extends CreateSignatureBase { class CreateSignature extends CreateSignatureBase {
File logoFile;
public CreateSignature(KeyStore keystore, char[] pin) public CreateSignature(KeyStore keystore, char[] pin)
throws KeyStoreException, throws KeyStoreException,
UnrecoverableKeyException, UnrecoverableKeyException,
@@ -69,6 +103,101 @@ public class CertSignController {
IOException, IOException,
CertificateException { CertificateException {
super(keystore, pin); super(keystore, pin);
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
try (InputStream is = resource.getInputStream()) {
logoFile = Files.createTempFile("signature", ".png").toFile();
FileUtils.copyInputStreamToFile(is, logoFile);
} catch (IOException e) {
logger.error("Failed to load image signature file");
throw e;
}
}
public InputStream createVisibleSignature(
PDDocument srcDoc, PDSignature signature, Integer pageNumber, Boolean showLogo)
throws IOException {
// modified from org.apache.pdfbox.examples.signature.CreateVisibleSignature2
try (PDDocument doc = new PDDocument()) {
PDPage page = new PDPage(srcDoc.getPage(pageNumber).getMediaBox());
doc.addPage(page);
PDAcroForm acroForm = new PDAcroForm(doc);
doc.getDocumentCatalog().setAcroForm(acroForm);
PDSignatureField signatureField = new PDSignatureField(acroForm);
PDAnnotationWidget widget = signatureField.getWidgets().get(0);
List<PDField> acroFormFields = acroForm.getFields();
acroForm.setSignaturesExist(true);
acroForm.setAppendOnly(true);
acroForm.getCOSObject().setDirect(true);
acroFormFields.add(signatureField);
PDRectangle rect = new PDRectangle(0, 0, 200, 50);
widget.setRectangle(rect);
// from PDVisualSigBuilder.createHolderForm()
PDStream stream = new PDStream(doc);
PDFormXObject form = new PDFormXObject(stream);
PDResources res = new PDResources();
form.setResources(res);
form.setFormType(1);
PDRectangle bbox = new PDRectangle(rect.getWidth(), rect.getHeight());
float height = bbox.getHeight();
form.setBBox(bbox);
PDFont font = new PDType1Font(FontName.TIMES_BOLD);
// from PDVisualSigBuilder.createAppearanceDictionary()
PDAppearanceDictionary appearance = new PDAppearanceDictionary();
appearance.getCOSObject().setDirect(true);
PDAppearanceStream appearanceStream = new PDAppearanceStream(form.getCOSObject());
appearance.setNormalAppearance(appearanceStream);
widget.setAppearance(appearance);
try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream)) {
if (showLogo) {
cs.saveGraphicsState();
PDExtendedGraphicsState extState = new PDExtendedGraphicsState();
extState.setBlendMode(BlendMode.MULTIPLY);
extState.setNonStrokingAlphaConstant(0.5f);
cs.setGraphicsStateParameters(extState);
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
PDImageXObject img =
PDImageXObject.createFromFileByExtension(logoFile, doc);
cs.drawImage(img, 100, 0);
cs.restoreGraphicsState();
}
// show text
float fontSize = 10;
float leading = fontSize * 1.5f;
cs.beginText();
cs.setFont(font, fontSize);
cs.setNonStrokingColor(Color.black);
cs.newLineAtOffset(fontSize, height - leading);
cs.setLeading(leading);
X509Certificate cert = (X509Certificate) getCertificateChain()[0];
// https://stackoverflow.com/questions/2914521/
X500Name x500Name = new X500Name(cert.getSubjectX500Principal().getName());
RDN cn = x500Name.getRDNs(BCStyle.CN)[0];
String name = IETFUtils.valueToString(cn.getFirst().getValue());
String date = signature.getSignDate().getTime().toString();
String reason = signature.getReason();
cs.showText("Signed by " + name);
cs.newLine();
cs.showText(date);
cs.newLine();
cs.showText(reason);
cs.endText();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
return new ByteArrayInputStream(baos.toByteArray());
}
} }
} }
@@ -97,7 +226,8 @@ public class CertSignController {
String reason = request.getReason(); String reason = request.getReason();
String location = request.getLocation(); String location = request.getLocation();
String name = request.getName(); String name = request.getName();
Integer pageNumber = request.getPageNumber(); Integer pageNumber = request.getPageNumber() - 1;
Boolean showLogo = request.isShowLogo();
if (certType == null) { if (certType == null) {
throw new IllegalArgumentException("Cert type must be provided"); throw new IllegalArgumentException("Cert type must be provided");
@@ -126,11 +256,19 @@ public class CertSignController {
throw new IllegalArgumentException("Invalid cert type: " + certType); throw new IllegalArgumentException("Invalid cert type: " + certType);
} }
// TODO: page number
CreateSignature createSignature = new CreateSignature(ks, password.toCharArray()); CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, name, location, reason); sign(
pdfDocumentFactory,
pdf.getBytes(),
baos,
createSignature,
showSignature,
pageNumber,
name,
location,
reason,
showLogo);
return WebResponseUtils.boasToWebResponse( return WebResponseUtils.boasToWebResponse(
baos, baos,
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "") Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
@@ -142,9 +280,12 @@ public class CertSignController {
byte[] input, byte[] input,
OutputStream output, OutputStream output,
CreateSignature instance, CreateSignature instance,
Boolean showSignature,
Integer pageNumber,
String name, String name,
String location, String location,
String reason) { String reason,
Boolean showLogo) {
try (PDDocument doc = pdfDocumentFactory.load(input)) { try (PDDocument doc = pdfDocumentFactory.load(input)) {
PDSignature signature = new PDSignature(); PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
@@ -154,7 +295,17 @@ public class CertSignController {
signature.setReason(reason); signature.setReason(reason);
signature.setSignDate(Calendar.getInstance()); signature.setSignDate(Calendar.getInstance());
doc.addSignature(signature, instance); if (showSignature) {
SignatureOptions signatureOptions = new SignatureOptions();
signatureOptions.setVisualSignature(
instance.createVisibleSignature(doc, signature, pageNumber, showLogo));
signatureOptions.setPage(pageNumber);
doc.addSignature(signature, instance, signatureOptions);
} else {
doc.addSignature(signature, instance);
}
doc.saveIncremental(output); doc.saveIncremental(output);
} catch (Exception e) { } catch (Exception e) {
logger.error("exception", e); logger.error("exception", e);

View File

@@ -187,18 +187,31 @@ public class WatermarkController {
float watermarkHeight = heightSpacer + fontSize * textLines.length; float watermarkHeight = heightSpacer + fontSize * textLines.length;
float pageWidth = page.getMediaBox().getWidth(); float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight(); float pageHeight = page.getMediaBox().getHeight();
int watermarkRows = (int) (pageHeight / watermarkHeight + 1);
int watermarkCols = (int) (pageWidth / watermarkWidth + 1); // Calculating the new width and height depending on the angle.
float radians = (float) Math.toRadians(rotation);
float newWatermarkWidth =
(float)
(Math.abs(watermarkWidth * Math.cos(radians))
+ Math.abs(watermarkHeight * Math.sin(radians)));
float newWatermarkHeight =
(float)
(Math.abs(watermarkWidth * Math.sin(radians))
+ Math.abs(watermarkHeight * Math.cos(radians)));
// Calculating the number of rows and columns.
int watermarkRows = (int) (pageHeight / newWatermarkHeight + 1);
int watermarkCols = (int) (pageWidth / newWatermarkWidth + 1);
// Add the text watermark // Add the text watermark
for (int i = 0; i < watermarkRows; i++) { for (int i = 0; i <= watermarkRows; i++) {
for (int j = 0; j < watermarkCols; j++) { for (int j = 0; j <= watermarkCols; j++) {
contentStream.beginText(); contentStream.beginText();
contentStream.setTextMatrix( contentStream.setTextMatrix(
Matrix.getRotateInstance( Matrix.getRotateInstance(
(float) Math.toRadians(rotation), (float) Math.toRadians(rotation),
j * watermarkWidth, j * newWatermarkWidth,
i * watermarkHeight)); i * newWatermarkHeight));
for (int k = 0; k < textLines.length; ++k) { for (int k = 0; k < textLines.length; ++k) {
contentStream.showText(textLines[k]); contentStream.showText(textLines[k]);

View File

@@ -21,10 +21,13 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.saml2.CustomSaml2AuthenticatedPrincipal;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.*; import stirling.software.SPDF.model.*;
import stirling.software.SPDF.model.ApplicationProperties.Security;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client; import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
import stirling.software.SPDF.model.ApplicationProperties.Security.SAML2;
import stirling.software.SPDF.model.provider.GithubProvider; import stirling.software.SPDF.model.provider.GithubProvider;
import stirling.software.SPDF.model.provider.GoogleProvider; import stirling.software.SPDF.model.provider.GoogleProvider;
import stirling.software.SPDF.model.provider.KeycloakProvider; import stirling.software.SPDF.model.provider.KeycloakProvider;
@@ -51,38 +54,54 @@ public class AccountWebController {
Map<String, String> providerList = new HashMap<>(); Map<String, String> providerList = new HashMap<>();
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2(); Security securityProps = applicationProperties.getSecurity();
OAUTH2 oauth = securityProps.getOauth2();
if (oauth != null) { if (oauth != null) {
if (oauth.isSettingsValid()) { if (oauth.getEnabled()) {
providerList.put("oidc", oauth.getProvider()); if (oauth.isSettingsValid()) {
} providerList.put("/oauth2/authorization/oidc", oauth.getProvider());
Client client = oauth.getClient();
if (client != null) {
GoogleProvider google = client.getGoogle();
if (google.isSettingsValid()) {
providerList.put(google.getName(), google.getClientName());
} }
Client client = oauth.getClient();
if (client != null) {
GoogleProvider google = client.getGoogle();
if (google.isSettingsValid()) {
providerList.put(
"/oauth2/authorization/" + google.getName(),
google.getClientName());
}
GithubProvider github = client.getGithub(); GithubProvider github = client.getGithub();
if (github.isSettingsValid()) { if (github.isSettingsValid()) {
providerList.put(github.getName(), github.getClientName()); providerList.put(
} "/oauth2/authorization/" + github.getName(),
github.getClientName());
}
KeycloakProvider keycloak = client.getKeycloak(); KeycloakProvider keycloak = client.getKeycloak();
if (keycloak.isSettingsValid()) { if (keycloak.isSettingsValid()) {
providerList.put(keycloak.getName(), keycloak.getClientName()); providerList.put(
"/oauth2/authorization/" + keycloak.getName(),
keycloak.getClientName());
}
} }
} }
} }
SAML2 saml2 = securityProps.getSaml2();
if (securityProps.isSaml2Activ()
&& applicationProperties.getSystem().getEnableAlphaFunctionality()) {
providerList.put("/saml2/authenticate/" + saml2.getRegistrationId(), "SAML 2");
}
// Remove any null keys/values from the providerList // Remove any null keys/values from the providerList
providerList providerList
.entrySet() .entrySet()
.removeIf(entry -> entry.getKey() == null || entry.getValue() == null); .removeIf(entry -> entry.getKey() == null || entry.getValue() == null);
model.addAttribute("providerlist", providerList); model.addAttribute("providerlist", providerList);
model.addAttribute("loginMethod", applicationProperties.getSecurity().getLoginMethod()); model.addAttribute("loginMethod", securityProps.getLoginMethod());
model.addAttribute( boolean altLogin = providerList.size() > 0 ? securityProps.isAltLogin() : false;
"oAuth2Enabled", applicationProperties.getSecurity().getOauth2().getEnabled()); model.addAttribute("altLogin", altLogin);
model.addAttribute("currentPage", "login"); model.addAttribute("currentPage", "login");
@@ -145,6 +164,17 @@ public class AccountWebController {
case "userIsDisabled": case "userIsDisabled":
erroroauth = "login.userIsDisabled"; erroroauth = "login.userIsDisabled";
break; break;
case "invalid_destination":
erroroauth = "login.invalid_destination";
break;
// Valid InResponseTo was not available from the validation context, unable to
// evaluate
case "invalid_in_response_to":
erroroauth = "login.invalid_in_response_to";
break;
case "not_authentication_provider_found":
erroroauth = "login.not_authentication_provider_found";
break;
default: default:
break; break;
} }
@@ -349,6 +379,17 @@ public class AccountWebController {
// Add oAuth2 Login attributes to the model // Add oAuth2 Login attributes to the model
model.addAttribute("oAuth2Login", true); model.addAttribute("oAuth2Login", true);
} }
if (principal instanceof CustomSaml2AuthenticatedPrincipal) {
// Cast the principal object to OAuth2User
CustomSaml2AuthenticatedPrincipal userDetails =
(CustomSaml2AuthenticatedPrincipal) principal;
// Retrieve username and other attributes
username = userDetails.getName();
// Add oAuth2 Login attributes to the model
model.addAttribute("oAuth2Login", true);
}
if (username != null) { if (username != null) {
// Fetch user details from the database // Fetch user details from the database
Optional<User> user = Optional<User> user =

View File

@@ -31,6 +31,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.SignatureFile;
import stirling.software.SPDF.service.SignatureService;
@Controller @Controller
@Tag(name = "General", description = "General APIs") @Tag(name = "General", description = "General APIs")
public class GeneralWebController { public class GeneralWebController {
@@ -171,11 +175,28 @@ public class GeneralWebController {
return "split-pdfs"; return "split-pdfs";
} }
private static final String SIGNATURE_BASE_PATH = "customFiles/static/signatures/";
private static final String ALL_USERS_FOLDER = "ALL_USERS";
@Autowired private SignatureService signatureService;
@Autowired(required = false)
private UserServiceInterface userService;
@GetMapping("/sign") @GetMapping("/sign")
@Hidden @Hidden
public String signForm(Model model) { public String signForm(Model model) {
String username = "";
if (userService != null) {
username = userService.getCurrentUsername();
}
// Get signatures from both personal and ALL_USERS folders
List<SignatureFile> signatures = signatureService.getAvailableSignatures(username);
model.addAttribute("currentPage", "sign"); model.addAttribute("currentPage", "sign");
model.addAttribute("fonts", getFontNames()); model.addAttribute("fonts", getFontNames());
model.addAttribute("signatures", signatures);
return "sign"; return "sign";
} }

View File

@@ -0,0 +1,44 @@
package stirling.software.SPDF.controller.web;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.service.SignatureService;
@Controller
@RequestMapping("/api/v1/general")
public class SignatureController {
@Autowired private SignatureService signatureService;
@Autowired(required = false)
private UserServiceInterface userService;
@GetMapping("/sign/{fileName}")
public ResponseEntity<byte[]> getSignature(@PathVariable(name = "fileName") String fileName)
throws IOException {
String username = "NON_SECURITY_USER";
if (userService != null) {
username = userService.getCurrentUsername();
}
// Verify access permission
if (!signatureService.hasAccessToFile(username, fileName)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
byte[] imageBytes = signatureService.getSignatureBytes(username, fileName);
return ResponseEntity.ok()
.contentType(MediaType.IMAGE_JPEG) // Adjust based on file type
.body(imageBytes);
}
}

View File

@@ -1,13 +1,17 @@
package stirling.software.SPDF.model; package stirling.software.SPDF.model;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
@@ -18,6 +22,8 @@ import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import lombok.Data; import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import stirling.software.SPDF.config.YamlPropertySourceFactory; import stirling.software.SPDF.config.YamlPropertySourceFactory;
import stirling.software.SPDF.model.provider.GithubProvider; import stirling.software.SPDF.model.provider.GithubProvider;
@@ -41,7 +47,7 @@ public class ApplicationProperties {
private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated(); private AutomaticallyGenerated automaticallyGenerated = new AutomaticallyGenerated();
private EnterpriseEdition enterpriseEdition = new EnterpriseEdition(); private EnterpriseEdition enterpriseEdition = new EnterpriseEdition();
private AutoPipeline autoPipeline = new AutoPipeline(); private AutoPipeline autoPipeline = new AutoPipeline();
private static final Logger logger = LoggerFactory.getLogger(ApplicationProperties.class); private ProcessExecutor processExecutor = new ProcessExecutor();
@Data @Data
public static class AutoPipeline { public static class AutoPipeline {
@@ -63,41 +69,108 @@ public class ApplicationProperties {
private Boolean csrfDisabled; private Boolean csrfDisabled;
private InitialLogin initialLogin = new InitialLogin(); private InitialLogin initialLogin = new InitialLogin();
private OAUTH2 oauth2 = new OAUTH2(); private OAUTH2 oauth2 = new OAUTH2();
private SAML saml = new SAML(); private SAML2 saml2 = new SAML2();
private int loginAttemptCount; private int loginAttemptCount;
private long loginResetTimeMinutes; private long loginResetTimeMinutes;
private String loginMethod = "all"; private String loginMethod = "all";
public Boolean isAltLogin() {
return saml2.getEnabled() || oauth2.getEnabled();
}
public enum LoginMethods {
ALL("all"),
NORMAL("normal"),
OAUTH2("oauth2"),
SAML2("saml2");
private String method;
LoginMethods(String method) {
this.method = method;
}
@Override
public String toString() {
return method;
}
}
public boolean isUserPass() {
return (loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString())
|| loginMethod.equalsIgnoreCase(LoginMethods.ALL.toString()));
}
public boolean isOauth2Activ() {
return (oauth2 != null
&& oauth2.getEnabled()
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
}
public boolean isSaml2Activ() {
return (saml2 != null
&& saml2.getEnabled()
&& !loginMethod.equalsIgnoreCase(LoginMethods.NORMAL.toString()));
}
@Data @Data
public static class InitialLogin { public static class InitialLogin {
private String username; private String username;
@ToString.Exclude private String password; @ToString.Exclude private String password;
} }
@Data @Getter
public static class SAML { @Setter
public static class SAML2 {
private Boolean enabled = false; private Boolean enabled = false;
private String entityId; private Boolean autoCreateUser = false;
private String registrationId; private Boolean blockRegistration = false;
private String spBaseUrl; private String registrationId = "stirling";
private String idpMetadataLocation; private String idpMetadataUri;
private KeyStore keystore; private String idpSingleLogoutUrl;
private String idpSingleLoginUrl;
private String idpIssuer;
private String idpCert;
private String privateKey;
private String spCert;
@Data public InputStream getIdpMetadataUri() throws IOException {
public static class KeyStore { if (idpMetadataUri.startsWith("classpath:")) {
private String keystoreLocation; return new ClassPathResource(idpMetadataUri.substring("classpath".length()))
private String keystorePassword; .getInputStream();
private String keyAlias; }
private String keyPassword; try {
private String realmCertificateAlias; URI uri = new URI(idpMetadataUri);
URL url = uri.toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
return connection.getInputStream();
} catch (URISyntaxException e) {
throw new IOException("Invalid URI format: " + idpMetadataUri, e);
}
}
public Resource getKeystoreResource() { public Resource getSpCert() {
if (keystoreLocation.startsWith("classpath:")) { if (spCert.startsWith("classpath:")) {
return new ClassPathResource( return new ClassPathResource(spCert.substring("classpath:".length()));
keystoreLocation.substring("classpath:".length())); } else {
} else { return new FileSystemResource(spCert);
return new FileSystemResource(keystoreLocation); }
} }
public Resource getidpCert() {
if (idpCert.startsWith("classpath:")) {
return new ClassPathResource(idpCert.substring("classpath:".length()));
} else {
return new FileSystemResource(idpCert);
}
}
public Resource getPrivateKey() {
if (privateKey.startsWith("classpath:")) {
return new ClassPathResource(privateKey.substring("classpath:".length()));
} else {
return new FileSystemResource(privateKey);
} }
} }
} }
@@ -237,4 +310,98 @@ public class ApplicationProperties {
} }
} }
} }
@Data
public static class ProcessExecutor {
private SessionLimit sessionLimit = new SessionLimit();
private TimeoutMinutes timeoutMinutes = new TimeoutMinutes();
@Data
public static class SessionLimit {
private int libreOfficeSessionLimit;
private int pdfToHtmlSessionLimit;
private int ocrMyPdfSessionLimit;
private int pythonOpenCvSessionLimit;
private int ghostScriptSessionLimit;
private int weasyPrintSessionLimit;
private int installAppSessionLimit;
private int calibreSessionLimit;
public int getLibreOfficeSessionLimit() {
return libreOfficeSessionLimit > 0 ? libreOfficeSessionLimit : 1;
}
public int getPdfToHtmlSessionLimit() {
return pdfToHtmlSessionLimit > 0 ? pdfToHtmlSessionLimit : 1;
}
public int getOcrMyPdfSessionLimit() {
return ocrMyPdfSessionLimit > 0 ? ocrMyPdfSessionLimit : 2;
}
public int getPythonOpenCvSessionLimit() {
return pythonOpenCvSessionLimit > 0 ? pythonOpenCvSessionLimit : 8;
}
public int getGhostScriptSessionLimit() {
return ghostScriptSessionLimit > 0 ? ghostScriptSessionLimit : 16;
}
public int getWeasyPrintSessionLimit() {
return weasyPrintSessionLimit > 0 ? weasyPrintSessionLimit : 16;
}
public int getInstallAppSessionLimit() {
return installAppSessionLimit > 0 ? installAppSessionLimit : 1;
}
public int getCalibreSessionLimit() {
return calibreSessionLimit > 0 ? calibreSessionLimit : 1;
}
}
@Data
public static class TimeoutMinutes {
private long libreOfficeTimeoutMinutes;
private long pdfToHtmlTimeoutMinutes;
private long ocrMyPdfTimeoutMinutes;
private long pythonOpenCvTimeoutMinutes;
private long ghostScriptTimeoutMinutes;
private long weasyPrintTimeoutMinutes;
private long installAppTimeoutMinutes;
private long calibreTimeoutMinutes;
public long getLibreOfficeTimeoutMinutes() {
return libreOfficeTimeoutMinutes > 0 ? libreOfficeTimeoutMinutes : 30;
}
public long getPdfToHtmlTimeoutMinutes() {
return pdfToHtmlTimeoutMinutes > 0 ? pdfToHtmlTimeoutMinutes : 20;
}
public long getOcrMyPdfTimeoutMinutes() {
return ocrMyPdfTimeoutMinutes > 0 ? ocrMyPdfTimeoutMinutes : 30;
}
public long getPythonOpenCvTimeoutMinutes() {
return pythonOpenCvTimeoutMinutes > 0 ? pythonOpenCvTimeoutMinutes : 30;
}
public long getGhostScriptTimeoutMinutes() {
return ghostScriptTimeoutMinutes > 0 ? ghostScriptTimeoutMinutes : 30;
}
public long getWeasyPrintTimeoutMinutes() {
return weasyPrintTimeoutMinutes > 0 ? weasyPrintTimeoutMinutes : 30;
}
public long getInstallAppTimeoutMinutes() {
return installAppTimeoutMinutes > 0 ? installAppTimeoutMinutes : 60;
}
public long getCalibreTimeoutMinutes() {
return calibreTimeoutMinutes > 0 ? calibreTimeoutMinutes : 30;
}
}
}
} }

View File

@@ -19,7 +19,6 @@ public class Provider implements ProviderInterface {
return true; return true;
} }
return false; return false;
// throw new IllegalArgumentException(getName() + ": " + name + " is required!");
} }
protected boolean isValid(Collection<String> value, String name) { protected boolean isValid(Collection<String> value, String name) {
@@ -27,66 +26,55 @@ public class Provider implements ProviderInterface {
return true; return true;
} }
return false; return false;
// throw new IllegalArgumentException(getName() + ": " + name + " is required!");
} }
@Override @Override
public Collection<String> getScopes() { public Collection<String> getScopes() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getScope'"); throw new UnsupportedOperationException("Unimplemented method 'getScope'");
} }
@Override @Override
public void setScopes(String scopes) { public void setScopes(String scopes) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'setScope'"); throw new UnsupportedOperationException("Unimplemented method 'setScope'");
} }
@Override @Override
public String getUseAsUsername() { public String getUseAsUsername() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getUseAsUsername'"); throw new UnsupportedOperationException("Unimplemented method 'getUseAsUsername'");
} }
@Override @Override
public void setUseAsUsername(String useAsUsername) { public void setUseAsUsername(String useAsUsername) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'setUseAsUsername'"); throw new UnsupportedOperationException("Unimplemented method 'setUseAsUsername'");
} }
@Override @Override
public String getIssuer() { public String getIssuer() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getIssuer'"); throw new UnsupportedOperationException("Unimplemented method 'getIssuer'");
} }
@Override @Override
public void setIssuer(String issuer) { public void setIssuer(String issuer) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'setIssuer'"); throw new UnsupportedOperationException("Unimplemented method 'setIssuer'");
} }
@Override @Override
public String getClientSecret() { public String getClientSecret() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getClientSecret'"); throw new UnsupportedOperationException("Unimplemented method 'getClientSecret'");
} }
@Override @Override
public void setClientSecret(String clientSecret) { public void setClientSecret(String clientSecret) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'setClientSecret'"); throw new UnsupportedOperationException("Unimplemented method 'setClientSecret'");
} }
@Override @Override
public String getClientId() { public String getClientId() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getClientId'"); throw new UnsupportedOperationException("Unimplemented method 'getClientId'");
} }
@Override @Override
public void setClientId(String clientId) { public void setClientId(String clientId) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'setClientId'"); throw new UnsupportedOperationException("Unimplemented method 'setClientId'");
} }
} }

View File

@@ -0,0 +1,11 @@
package stirling.software.SPDF.model;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class SignatureFile {
private String fileName;
private String category; // "Personal" or "Shared"
}

View File

@@ -50,4 +50,7 @@ public class SignPDFWithCertRequest extends PDFFile {
description = description =
"The page number where the signature should be visible. This is required if showSignature is set to true") "The page number where the signature should be visible. This is required if showSignature is set to true")
private Integer pageNumber; private Integer pageNumber;
@Schema(description = "Whether to visually show a signature logo along with the signature")
private boolean showLogo;
} }

View File

@@ -5,6 +5,7 @@ import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken; import org.springframework.security.web.authentication.rememberme.PersistentRememberMeToken;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.transaction.annotation.Transactional;
import stirling.software.SPDF.model.PersistentLogin; import stirling.software.SPDF.model.PersistentLogin;
@@ -13,6 +14,7 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
@Autowired private PersistentLoginRepository persistentLoginRepository; @Autowired private PersistentLoginRepository persistentLoginRepository;
@Override @Override
@Transactional
public void createNewToken(PersistentRememberMeToken token) { public void createNewToken(PersistentRememberMeToken token) {
PersistentLogin newToken = new PersistentLogin(); PersistentLogin newToken = new PersistentLogin();
newToken.setSeries(token.getSeries()); newToken.setSeries(token.getSeries());
@@ -23,6 +25,7 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
} }
@Override @Override
@Transactional
public void updateToken(String series, String tokenValue, Date lastUsed) { public void updateToken(String series, String tokenValue, Date lastUsed) {
PersistentLogin existingToken = persistentLoginRepository.findById(series).orElse(null); PersistentLogin existingToken = persistentLoginRepository.findById(series).orElse(null);
if (existingToken != null) { if (existingToken != null) {
@@ -43,11 +46,11 @@ public class JPATokenRepositoryImpl implements PersistentTokenRepository {
} }
@Override @Override
@Transactional
public void removeUserTokens(String username) { public void removeUserTokens(String username) {
for (PersistentLogin token : persistentLoginRepository.findAll()) { try {
if (token.getUsername().equals(username)) { persistentLoginRepository.deleteByUsername(username);
persistentLoginRepository.delete(token); } catch (Exception e) {
}
} }
} }
} }

View File

@@ -6,4 +6,6 @@ import org.springframework.stereotype.Repository;
import stirling.software.SPDF.model.PersistentLogin; import stirling.software.SPDF.model.PersistentLogin;
@Repository @Repository
public interface PersistentLoginRepository extends JpaRepository<PersistentLogin, String> {} public interface PersistentLoginRepository extends JpaRepository<PersistentLogin, String> {
void deleteByUsername(String username);
}

View File

@@ -0,0 +1,41 @@
package stirling.software.SPDF.service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Service;
@Service
public class LanguageService {
private final PathMatchingResourcePatternResolver resourcePatternResolver =
new PathMatchingResourcePatternResolver();
public List<String> getSupportedLanguages() {
List<String> supportedLanguages = new ArrayList<>();
try {
Resource[] resources =
resourcePatternResolver.getResources("classpath*:messages_*.properties");
for (Resource resource : resources) {
if (resource.exists() && resource.isReadable()) {
String filename = resource.getFilename();
if (filename != null
&& filename.startsWith("messages_")
&& filename.endsWith(".properties")) {
String languageCode =
filename.replace("messages_", "").replace(".properties", "");
supportedLanguages.add(languageCode);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return supportedLanguages;
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
import com.posthog.java.PostHog; import com.posthog.java.PostHog;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
@Service @Service
@@ -26,20 +27,23 @@ public class PostHogService {
private final PostHog postHog; private final PostHog postHog;
private final String uniqueId; private final String uniqueId;
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final UserServiceInterface userService;
@Autowired @Autowired
public PostHogService( public PostHogService(
PostHog postHog, PostHog postHog,
@Qualifier("UUID") String uuid, @Qualifier("UUID") String uuid,
ApplicationProperties applicationProperties) { ApplicationProperties applicationProperties,
@Autowired(required = false) UserServiceInterface userService) {
this.postHog = postHog; this.postHog = postHog;
this.uniqueId = uuid; this.uniqueId = uuid;
this.applicationProperties = applicationProperties; this.applicationProperties = applicationProperties;
this.userService = userService;
captureSystemInfo(); captureSystemInfo();
} }
private void captureSystemInfo() { private void captureSystemInfo() {
if (!Boolean.getBoolean(applicationProperties.getSystem().getEnableAnalytics())) { if (!Boolean.parseBoolean(applicationProperties.getSystem().getEnableAnalytics())) {
return; return;
} }
try { try {
@@ -50,7 +54,7 @@ public class PostHogService {
} }
public void captureEvent(String eventName, Map<String, Object> properties) { public void captureEvent(String eventName, Map<String, Object> properties) {
if (!Boolean.getBoolean(applicationProperties.getSystem().getEnableAnalytics())) { if (!Boolean.parseBoolean(applicationProperties.getSystem().getEnableAnalytics())) {
return; return;
} }
postHog.capture(uniqueId, eventName, properties); postHog.capture(uniqueId, eventName, properties);
@@ -134,6 +138,10 @@ public class PostHogService {
} }
metrics.put("application_properties", captureApplicationProperties()); metrics.put("application_properties", captureApplicationProperties());
if (userService != null) {
metrics.put("total_users_created", userService.getTotalUsersCount());
}
} catch (Exception e) { } catch (Exception e) {
metrics.put("error", e.getMessage()); metrics.put("error", e.getMessage());
} }

View File

@@ -0,0 +1,100 @@
package stirling.software.SPDF.service;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.SignatureFile;
@Service
@Slf4j
public class SignatureService {
private static final String SIGNATURE_BASE_PATH = "customFiles/signatures/";
private static final String ALL_USERS_FOLDER = "ALL_USERS";
public boolean hasAccessToFile(String username, String fileName) throws IOException {
validateFileName(fileName);
// Check if file exists in user's personal folder or ALL_USERS folder
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
return Files.exists(userPath) || Files.exists(allUsersPath);
}
public List<SignatureFile> getAvailableSignatures(String username) {
List<SignatureFile> signatures = new ArrayList<>();
// Get signatures from user's personal folder
if (!StringUtils.isEmptyOrWhitespace(username)) {
Path userFolder = Paths.get(SIGNATURE_BASE_PATH, username);
if (Files.exists(userFolder)) {
try {
signatures.addAll(getSignaturesFromFolder(userFolder, "Personal"));
} catch (IOException e) {
log.error("Error reading user signatures folder", e);
}
}
}
// Get signatures from ALL_USERS folder
Path allUsersFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
if (Files.exists(allUsersFolder)) {
try {
signatures.addAll(getSignaturesFromFolder(allUsersFolder, "Shared"));
} catch (IOException e) {
log.error("Error reading shared signatures folder", e);
}
}
return signatures;
}
private List<SignatureFile> getSignaturesFromFolder(Path folder, String category)
throws IOException {
return Files.list(folder)
.filter(path -> isImageFile(path))
.map(path -> new SignatureFile(path.getFileName().toString(), category))
.collect(Collectors.toList());
}
public byte[] getSignatureBytes(String username, String fileName) throws IOException {
validateFileName(fileName);
// First try user's personal folder
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
if (Files.exists(userPath)) {
return Files.readAllBytes(userPath);
}
// Then try ALL_USERS folder
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
if (Files.exists(allUsersPath)) {
return Files.readAllBytes(allUsersPath);
}
throw new FileNotFoundException("Signature file not found");
}
private boolean isImageFile(Path path) {
String fileName = path.getFileName().toString().toLowerCase();
return fileName.endsWith(".jpg")
|| fileName.endsWith(".jpeg")
|| fileName.endsWith(".png")
|| fileName.endsWith(".gif");
}
private void validateFileName(String fileName) {
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
throw new IllegalArgumentException("Invalid filename");
}
}
}

View File

@@ -1,13 +1,31 @@
package stirling.software.SPDF.utils; package stirling.software.SPDF.utils;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer; import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte; import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt; import java.awt.image.DataBufferInt;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifSubIFDDirectory;
public class ImageProcessingUtils { public class ImageProcessingUtils {
private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
static BufferedImage convertColorType(BufferedImage sourceImage, String colorType) { static BufferedImage convertColorType(BufferedImage sourceImage, String colorType) {
BufferedImage convertedImage; BufferedImage convertedImage;
switch (colorType) { switch (colorType) {
@@ -59,4 +77,51 @@ public class ImageProcessingUtils {
return data; return data;
} }
} }
public static double extractImageOrientation(InputStream is) throws IOException {
try {
Metadata metadata = ImageMetadataReader.readMetadata(is);
ExifSubIFDDirectory directory =
metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
if (directory == null) {
return 0;
}
int orientationTag = directory.getInt(ExifSubIFDDirectory.TAG_ORIENTATION);
switch (orientationTag) {
case 1:
return 0;
case 6:
return 90;
case 3:
return 180;
case 8:
return 270;
default:
logger.warn("Unknown orientation tag: {}", orientationTag);
return 0;
}
} catch (ImageProcessingException | MetadataException e) {
return 0;
}
}
public static BufferedImage applyOrientation(BufferedImage image, double orientation) {
if (orientation == 0) {
return image;
}
AffineTransform transform =
AffineTransform.getRotateInstance(
Math.toRadians(orientation),
image.getWidth() / 2.0,
image.getHeight() / 2.0);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return op.filter(image, null);
}
public static BufferedImage loadImageWithExifOrientation(MultipartFile file)
throws IOException {
BufferedImage image = ImageIO.read(file.getInputStream());
double orientation = extractImageOrientation(file.getInputStream());
return applyOrientation(image, orientation);
}
} }

View File

@@ -194,7 +194,8 @@ public class PdfUtils {
pdfDocument.close(); pdfDocument.close();
// Assumes the expectedPageSize is in the format "widthxheight", e.g. "595x842" for A4 // Assumes the expectedPageSize is in the format "widthxheight", e.g. "595x842"
// for A4
String[] dimensions = expectedPageSize.split("x"); String[] dimensions = expectedPageSize.split("x");
float expectedPageWidth = Float.parseFloat(dimensions[0]); float expectedPageWidth = Float.parseFloat(dimensions[0]);
float expectedPageHeight = Float.parseFloat(dimensions[1]); float expectedPageHeight = Float.parseFloat(dimensions[1]);
@@ -407,7 +408,7 @@ public class PdfUtils {
addImageToDocument(doc, pdImage, fitOption, autoRotate); addImageToDocument(doc, pdImage, fitOption, autoRotate);
} }
} else { } else {
BufferedImage image = ImageIO.read(file.getInputStream()); BufferedImage image = ImageProcessingUtils.loadImageWithExifOrientation(file);
BufferedImage convertedImage = BufferedImage convertedImage =
ImageProcessingUtils.convertColorType(image, colorType); ImageProcessingUtils.convertColorType(image, colorType);
// Use JPEGFactory if it's JPEG since JPEG is lossy // Use JPEGFactory if it's JPEG since JPEG is lossy

View File

@@ -18,10 +18,14 @@ import org.slf4j.LoggerFactory;
import io.github.pixee.security.BoundedLineReader; import io.github.pixee.security.BoundedLineReader;
import stirling.software.SPDF.model.ApplicationProperties;
public class ProcessExecutor { public class ProcessExecutor {
private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class); private static final Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);
private static ApplicationProperties applicationProperties = new ApplicationProperties();
public enum Processes { public enum Processes {
LIBRE_OFFICE, LIBRE_OFFICE,
PDFTOHTML, PDFTOHTML,
@@ -45,26 +49,90 @@ public class ProcessExecutor {
key -> { key -> {
int semaphoreLimit = int semaphoreLimit =
switch (key) { switch (key) {
case LIBRE_OFFICE -> 1; case LIBRE_OFFICE ->
case PDFTOHTML -> 1; applicationProperties
case OCR_MY_PDF -> 2; .getProcessExecutor()
case PYTHON_OPENCV -> 8; .getSessionLimit()
case GHOSTSCRIPT -> 16; .getLibreOfficeSessionLimit();
case WEASYPRINT -> 16; case PDFTOHTML ->
case INSTALL_APP -> 1; applicationProperties
case CALIBRE -> 1; .getProcessExecutor()
.getSessionLimit()
.getPdfToHtmlSessionLimit();
case OCR_MY_PDF ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getOcrMyPdfSessionLimit();
case PYTHON_OPENCV ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getPythonOpenCvSessionLimit();
case GHOSTSCRIPT ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getGhostScriptSessionLimit();
case WEASYPRINT ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getWeasyPrintSessionLimit();
case INSTALL_APP ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getInstallAppSessionLimit();
case CALIBRE ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getCalibreSessionLimit();
}; };
long timeoutMinutes = long timeoutMinutes =
switch (key) { switch (key) {
case LIBRE_OFFICE -> 30; case LIBRE_OFFICE ->
case PDFTOHTML -> 20; applicationProperties
case OCR_MY_PDF -> 30; .getProcessExecutor()
case PYTHON_OPENCV -> 30; .getTimeoutMinutes()
case GHOSTSCRIPT -> 30; .getLibreOfficeTimeoutMinutes();
case WEASYPRINT -> 30; case PDFTOHTML ->
case INSTALL_APP -> 60; applicationProperties
case CALIBRE -> 30; .getProcessExecutor()
.getTimeoutMinutes()
.getPdfToHtmlTimeoutMinutes();
case OCR_MY_PDF ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getOcrMyPdfTimeoutMinutes();
case PYTHON_OPENCV ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getPythonOpenCvTimeoutMinutes();
case GHOSTSCRIPT ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getGhostScriptTimeoutMinutes();
case WEASYPRINT ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getWeasyPrintTimeoutMinutes();
case INSTALL_APP ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getInstallAppTimeoutMinutes();
case CALIBRE ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getCalibreTimeoutMinutes();
}; };
return new ProcessExecutor(semaphoreLimit, liveUpdates, timeoutMinutes); return new ProcessExecutor(semaphoreLimit, liveUpdates, timeoutMinutes);
}); });

View File

@@ -5,6 +5,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -53,7 +54,7 @@ public class CustomColorReplaceStrategy extends ReplaceAndInvertColorStrategy {
} }
// Create a temporary file, with the original filename from the multipart file // Create a temporary file, with the original filename from the multipart file
File file = File.createTempFile("temp", getFileInput().getOriginalFilename()); File file = Files.createTempFile("temp", getFileInput().getOriginalFilename()).toFile();
// Transfer the content of the multipart file to the file // Transfer the content of the multipart file to the file
getFileInput().transferTo(file); getFileInput().transferTo(file);

View File

@@ -6,6 +6,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@@ -30,7 +31,7 @@ public class InvertFullColorStrategy extends ReplaceAndInvertColorStrategy {
public InputStreamResource replace() throws IOException { public InputStreamResource replace() throws IOException {
// Create a temporary file, with the original filename from the multipart file // Create a temporary file, with the original filename from the multipart file
File file = File.createTempFile("temp", getFileInput().getOriginalFilename()); File file = Files.createTempFile("temp", getFileInput().getOriginalFilename()).toFile();
// Transfer the content of the multipart file to the file // Transfer the content of the multipart file to the file
getFileInput().transferTo(file); getFileInput().transferTo(file);

View File

@@ -76,15 +76,18 @@ donate=تبرع
color=لون color=لون
sponsor=راعٍ sponsor=راعٍ
info=معلومات info=معلومات
pro=Pro pro=محترف
page=Page page=صفحة
pages=Pages pages=صفحات
loading=جارٍ التحميل...
addToDoc=إضافة إلى المستند
reset=Reset
legal.privacy=Privacy Policy legal.privacy=سياسة الخصوصية
legal.terms=Terms and Conditions legal.terms=شروط الاستخدام
legal.accessibility=Accessibility legal.accessibility=Accessibility
legal.cookie=Cookie Policy legal.cookie=سياسة ملفات تعريف الارتباط
legal.impressum=Impressum legal.impressum=بيان الهوية
############### ###############
# Pipeline # # Pipeline #
@@ -114,8 +117,8 @@ pipelineOptions.validateButton=تحقق
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=ترقية إلى محترف
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=هذه الخاصية متوفرة فقط للمستخدمين المحترفين.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
@@ -123,12 +126,12 @@ enterpriseEdition.ssoAdvert=Looking for more user management features? Check out
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=هل تريد تحسين Stirling PDF؟
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF يحتوي على إحصائيات مختصة للمساعدة في تحسين المنتج. لا نتبع أي معلومات شخصية أو محتوى الملفات.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=يرجى مراعاة تفعيل الإحصائيات لمساعدتنا على نمو Stirling-PDF وتوفير فهم أفضل لمستخدمينا.
analytics.enable=Enable analytics analytics.enable=تفعيل الإحصائيات
analytics.disable=Disable analytics analytics.disable=تعطيل الإحصائيات
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=يمكنك تغيير إعدادات الإحصائيات في ملف config/settings.yml
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=اللغات
navbar.settings=إعدادات navbar.settings=إعدادات
navbar.allTools=أدوات navbar.allTools=أدوات
navbar.multiTool=أدوات متعددة navbar.multiTool=أدوات متعددة
navbar.search=Search
navbar.sections.organize=تنظيم navbar.sections.organize=تنظيم
navbar.sections.convertTo=تحويل الى PDF navbar.sections.convertTo=تحويل الى PDF
navbar.sections.convertFrom=تحويل من PDF navbar.sections.convertFrom=تحويل من PDF
navbar.sections.security=التوقيع والأمان navbar.sections.security=التوقيع والأمان
navbar.sections.advance=متقدم navbar.sections.advance=متقدم
navbar.sections.edit=عرض وتعديل navbar.sections.edit=عرض وتعديل
navbar.sections.popular=Popular navbar.sections.popular=المفضل
############# #############
# SETTINGS # # SETTINGS #
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خ
database.failedImportFile=فشل استيراد الملف database.failedImportFile=فشل استيراد الملف
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -503,28 +508,28 @@ home.removeImagePdf.desc=إزالة الصورة من PDF لتقليل حجم ا
removeImagePdf.tags=إزالة الصورة,عمليات الصفحة,الخلفية,جانب الخادم removeImagePdf.tags=إزالة الصورة,عمليات الصفحة,الخلفية,جانب الخادم
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=تجزئة المستندات PDF حسب الفصول
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=قسم مستند PDF إلى ملفات متعددة بناءً على هيكل فصوله.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=تجزئة، فصول، علامات تبويب، تنظيم
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=استبدال-إلغاء مirro لون PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=استبدال الألوان للنصوص والخلفيات في المستندات PDF وإلغاء تعكير اللون الكامل للمستند لتقليل حجم الملف
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=استبدال اللون، عمليات الصفحة، الخلفية، جانب الخادم
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=خيارات استبدال-إلغاء مirro لون
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Default(Default high contrast colors)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=خصيصة (ألوان شخصية)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Full-Invert(Invert all colors)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=خيارات ألوان التباين العالي
replace-color.selectText.6=white text on black background replace-color.selectText.6=نص أبيض على خلفية سوداء
replace-color.selectText.7=Black text on white background replace-color.selectText.7=نص أسود على خلفية بيضاء
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=نص صفرة على خلفية سوداء
replace-color.selectText.9=Green text on black background replace-color.selectText.9=نص أخضر على خلفية سوداء
replace-color.selectText.10=Choose text Color replace-color.selectText.10=اختر لون النص
replace-color.selectText.11=Choose background Color replace-color.selectText.11=اختر لون الخلفية
replace-color.submit=Replace replace-color.submit=استبدال
@@ -551,10 +556,9 @@ login.oauth2AccessDenied=تم رفض الوصول
login.oauth2InvalidTokenResponse=استجابة الرمز المميز غير صالحة login.oauth2InvalidTokenResponse=استجابة الرمز المميز غير صالحة
login.oauth2InvalidIdToken=رمز الهوية غير صالح login.oauth2InvalidIdToken=رمز الهوية غير صالح
login.userIsDisabled=تم تعطيل المستخدم، تم حظر تسجيل الدخول حاليًا باستخدام اسم المستخدم هذا. يرجى الاتصال بالمسؤول. login.userIsDisabled=تم تعطيل المستخدم، تم حظر تسجيل الدخول حاليًا باستخدام اسم المستخدم هذا. يرجى الاتصال بالمسؤول.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=لقد تسجل دخولًا إلى
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=أجهزة أخرى. يرجى تسجيل الخروج من الأجهزة وحاول مرة أخرى.
login.toManySessions=You have too many active sessions login.toManySessions=لديك عدة جلسات نشطة
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=حجب تلقائي autoRedact.title=حجب تلقائي
@@ -729,7 +733,7 @@ pageLayout.submit=إرسال
scalePages.title=ضبط مقياس الصفحة scalePages.title=ضبط مقياس الصفحة
scalePages.header=ضبط مقياس الصفحة scalePages.header=ضبط مقياس الصفحة
scalePages.pageSize=حجم صفحة المستند. scalePages.pageSize=حجم صفحة المستند.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=الحجم الأصلي
scalePages.scaleFactor=مستوى التكبير (الاقتصاص) للصفحة. scalePages.scaleFactor=مستوى التكبير (الاقتصاص) للصفحة.
scalePages.submit=إرسال scalePages.submit=إرسال
@@ -749,6 +753,7 @@ certSign.showSig=إظهار التوقيع
certSign.reason=السبب certSign.reason=السبب
certSign.location=الموقع certSign.location=الموقع
certSign.name=الاسم certSign.name=الاسم
certSign.showLogo=عرض الشعار
certSign.submit=توقيع PDF certSign.submit=توقيع PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=لون التظليل 2:
compare.document.1=المستند 1 compare.document.1=المستند 1
compare.document.2=المستند 2 compare.document.2=المستند 2
compare.submit=مقارنة compare.submit=مقارنة
compare.complex.message=أو كلا المستندين المقدمين كبيران حجمًا، مما يؤدي إلى تقليل دقة المقارنة
compare.large.file.message=أو كلا المستندين المقدمين كبيرة حجمهما للتعامل معهما
compare.no.text.message=أحد أو كلي المستندات المرجوة للمقارنة لا يحتوي على محتوى نصي. يرجى اختيار مستندات تحتوي على نص لم يتم التعرف عليه.
#BookToPDF #BookToPDF
BookToPDF.title=الكتب والكوميكس إلى PDF BookToPDF.title=الكتب والكوميكس إلى PDF
@@ -805,6 +813,11 @@ sign.draw=رسم التوقيع
sign.text=إدخال النص sign.text=إدخال النص
sign.clear=مسح sign.clear=مسح
sign.add=إضافة sign.add=إضافة
sign.saved=توقيعات تم حفظها
sign.save=حفظ توقيع
sign.personalSigs=توقيعات شخصية
sign.sharedSigs=توقيعات مشتركة
sign.noSavedSigs=لم يتم العثور على توقيعات محفوظة
#repair #repair
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(مثال: 1,3,2 أو 4-8,2,10-12 أو 2n-1)
multiTool.title=أداة متعددة PDF multiTool.title=أداة متعددة PDF
multiTool.header=أداة متعددة PDF multiTool.header=أداة متعددة PDF
multiTool.uploadPrompts=اسم الملف multiTool.uploadPrompts=اسم الملف
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=عرض PDF viewPdf.title=عرض PDF
@@ -1182,8 +1206,8 @@ licenses.license=الترخيص
survey.nav=استطلاع survey.nav=استطلاع
survey.title=استطلاع Stirling-PDF survey.title=استطلاع Stirling-PDF
survey.description=Stirling-PDF لا يحتوي على تتبع لذا نريد أن نسمع من مستخدمينا لتحسين Stirling-PDF! survey.description=Stirling-PDF لا يحتوي على تتبع لذا نريد أن نسمع من مستخدمينا لتحسين Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=تحديث Stirling-PDF منذ آخر استبيان! للحصول على المزيد من المعلومات الرجاء زيارة مقالتنا في المدونة هنا:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=مع هذه التحديثات، نستفيد من الدعم العملي والمنحة المالية
survey.please=يرجى النظر في المشاركة في استطلاعنا! survey.please=يرجى النظر في المشاركة في استطلاعنا!
survey.disabled=(سيتم تعطيل النافذة المنبثقة للاستطلاع في التحديثات التالية ولكنها ستكون متاحة في أسفل الصفحة) survey.disabled=(سيتم تعطيل النافذة المنبثقة للاستطلاع في التحديثات التالية ولكنها ستكون متاحة في أسفل الصفحة)
survey.button=المشاركة في الاستطلاع survey.button=المشاركة في الاستطلاع
@@ -1211,15 +1235,13 @@ removeImage.removeImage=إزالة الصورة
removeImage.submit=إزالة الصورة removeImage.submit=إزالة الصورة
splitByChapters.title=Split PDF by Chapters splitByChapters.title=تجزئة المستند حسب الفصول
splitByChapters.header=Split PDF by Chapters splitByChapters.header=تجزئة المستند حسب الفصول
splitByChapters.bookmarkLevel=Bookmark Level splitByChapters.bookmarkLevel=مستوى العلامات التذكارية
splitByChapters.includeMetadata=Include Metadata splitByChapters.includeMetadata=شامل البيانات المرفقة
splitByChapters.allowDuplicates=Allow Duplicates splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure. splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.). splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=تمثيل البيانات الأصلية: إذا تم اختيارها، سترمز البيانات المرجعية الأصلية إلى كل PDF مجزأ.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=سماح بالتكرار: إذا تم اختياره، يسمح بوجود معاينات متعددة في الصفحة نفسها لخلق ملفات PDF منفصلة.
splitByChapters.submit=Split PDF splitByChapters.submit=تقطيع ملف PDF

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Размер на шрифт
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Име на шрифт
pdfPrompt=Изберете PDF(и) pdfPrompt=Изберете PDF(и)
multiPdfPrompt=Изберете PDF (2+) multiPdfPrompt=Изберете PDF (2+)
multiPdfDropPrompt=Изберете (или плъзнете и пуснете) всички PDF файлове, от които се нуждаете multiPdfDropPrompt=Изберете (или плъзнете и пуснете) всички PDF файлове, от които се нуждаете
@@ -56,12 +56,12 @@ userNotFoundMessage=Потребителят не е намерен
incorrectPasswordMessage=Текущата парола е неправилна. incorrectPasswordMessage=Текущата парола е неправилна.
usernameExistsMessage=Новият потребител вече съществува. usernameExistsMessage=Новият потребител вече съществува.
invalidUsernameMessage=Невалидно потребителско име, потребителското име може да съдържа само букви, цифри и следните специални знаци @._+- или трябва да е валиден имейл адрес. invalidUsernameMessage=Невалидно потребителско име, потребителското име може да съдържа само букви, цифри и следните специални знаци @._+- или трябва да е валиден имейл адрес.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=Паролата не трябва да е празна и не трябва да има интервали в началото или в края.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Нова парола и Потвърждаване на новата парола трябва да съвпадат.
deleteCurrentUserMessage=Не може да се изтрие вписания в момента потребител. deleteCurrentUserMessage=Не може да се изтрие вписания в момента потребител.
deleteUsernameExistsMessage=Потребителското име не съществува и не може да бъде изтрито. deleteUsernameExistsMessage=Потребителското име не съществува и не може да бъде изтрито.
downgradeCurrentUserMessage=Не може да се понижи ролята на текущия потребител downgradeCurrentUserMessage=Не може да се понижи ролята на текущия потребител
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=Текущият потребител не може да бъде деактивиран
downgradeCurrentUserLongMessage=Не може да се понижи ролята на текущия потребител. Следователно текущият потребител няма да бъде показан. downgradeCurrentUserLongMessage=Не може да се понижи ролята на текущия потребител. Следователно текущият потребител няма да бъде показан.
userAlreadyExistsOAuthMessage=Потребителят вече съществува като OAuth2 потребител. userAlreadyExistsOAuthMessage=Потребителят вече съществува като OAuth2 потребител.
userAlreadyExistsWebMessage=Потребителят вече съществува като уеб-потребител. userAlreadyExistsWebMessage=Потребителят вече съществува като уеб-потребител.
@@ -75,16 +75,19 @@ visitGithub=Посетете Github Repository
donate=Направете дарение donate=Направете дарение
color=Цвят color=Цвят
sponsor=Спонсор sponsor=Спонсор
info=Info info=Информация
pro=Pro pro=Pro
page=Page page=Страница
pages=Pages pages=Страници
loading=Loading...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Политика за поверителност
legal.terms=Terms and Conditions legal.terms=Правила и условия
legal.accessibility=Accessibility legal.accessibility=Достъпност
legal.cookie=Cookie Policy legal.cookie=Политика за бисквитки
legal.impressum=Impressum legal.impressum=Отпечатък
############### ###############
# Pipeline # # Pipeline #
@@ -96,7 +99,7 @@ pipeline.defaultOption=Персонализиран
pipeline.submitButton=Подайте pipeline.submitButton=Подайте
pipeline.help=Pipeline Помощ pipeline.help=Pipeline Помощ
pipeline.scanHelp=Помощ за сканиране на папки pipeline.scanHelp=Помощ за сканиране на папки
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Сигурни ли сте, че искате да изтриете pipeline
###################### ######################
# Pipeline Options # # Pipeline Options #
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Валидирай
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Направете надстройка до Pro версията
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Тази функция е достъпна само за потребители на Pro версията.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro поддържа YAML конфигурационни файлове и други SSO функции.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Търсите повече функции за управление на потребителите? Погледнете за Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Искате ли да подобрите Stirling PDF?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF включва анализи, за да ни помогне да подобрим продукта. Ние не проследяваме лична информация или съдържание на файлове.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Моля, обмислете възможността за анализ, за ​​да помогнете на Stirling-PDF да расте и да ни позволи да разберем по-добре нашите потребители.
analytics.enable=Enable analytics analytics.enable=Активиране на анализа
analytics.disable=Disable analytics analytics.disable=Деактивиране на анализа
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Можете да промените настройките за анализ във config/settings.yml файла
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Езици
navbar.settings=Настройки navbar.settings=Настройки
navbar.allTools=Инструменти navbar.allTools=Инструменти
navbar.multiTool=Мулти инструменти navbar.multiTool=Мулти инструменти
navbar.search=Search
navbar.sections.organize=Организирайте navbar.sections.organize=Организирайте
navbar.sections.convertTo=Преобразуване в PDF navbar.sections.convertTo=Преобразуване в PDF
navbar.sections.convertFrom=Преобразуване от PDF navbar.sections.convertFrom=Преобразуване от PDF
navbar.sections.security=Подписване и сигурност navbar.sections.security=Подписване и сигурност
navbar.sections.advance=Разширено navbar.sections.advance=Разширено
navbar.sections.edit=Преглед и редактиране navbar.sections.edit=Преглед и редактиране
navbar.sections.popular=Popular navbar.sections.popular=Популярни
############# #############
# SETTINGS # # SETTINGS #
@@ -202,9 +206,9 @@ adminUserSettings.header=Настройки за администраторск
adminUserSettings.admin=Администратор adminUserSettings.admin=Администратор
adminUserSettings.user=Потребител adminUserSettings.user=Потребител
adminUserSettings.addUser=Добавяне на нов потребител adminUserSettings.addUser=Добавяне на нов потребител
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Изтриване на потребител
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=Трябва ли потребителят да бъде изтрит?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Трябва ли потребителят да бъде деактивиран/активиран?
adminUserSettings.usernameInfo=Потребителското име може да съдържа само букви, цифри и следните специални символи @._+- или трябва да е валиден имейл адрес. adminUserSettings.usernameInfo=Потребителското име може да съдържа само букви, цифри и следните специални символи @._+- или трябва да е валиден имейл адрес.
adminUserSettings.roles=Роли adminUserSettings.roles=Роли
adminUserSettings.role=Роля adminUserSettings.role=Роля
@@ -218,32 +222,33 @@ adminUserSettings.forceChange=Принудете потребителя да п
adminUserSettings.submit=Съхранете потребителя adminUserSettings.submit=Съхранете потребителя
adminUserSettings.changeUserRole=Промяна на ролята на потребителя adminUserSettings.changeUserRole=Промяна на ролята на потребителя
adminUserSettings.authenticated=Удостоверен adminUserSettings.authenticated=Удостоверен
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Редактиране на собствен профил
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=активиран потребител
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=деактивиран потребител
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Активни потребители:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Деактивирани потребители:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Общо потребители:
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Последна заявка
database.title=Database Import/Export database.title=Импорт/Експорт на база данни
database.header=Database Import/Export database.header=Импорт/Експорт на база данни
database.fileName=File Name database.fileName=Име на файл
database.creationDate=Creation Date database.creationDate=Дата на създаване
database.fileSize=File Size database.fileSize=Размер на файла
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Изтриване на архивен файл
database.importBackupFile=Import Backup File database.importBackupFile=Импортиране на архивен файл
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Изтеглете архивен файл
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=Когато импортирате данни, е от решаващо значение да осигурите правилната структура. Ако не сте сигурни в това, което правите, потърсете съвет и подкрепа от професионалист. Грешка в структурата може да причини неизправност на приложението, включително пълна невъзможност за стартиране на приложението.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=Името на файла няма значение при качване. След това ще бъде преименуван, за да следва формата backup_user_yyyyMMddHHmm.sql, осигурявайки последователна конвенция за именуване.
database.submit=Import Backup database.submit=Импортиране на резервно копие
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Импортирането в базата данни бе успешно
database.fileNotFound=File not Found database.fileNotFound=Файлът не е намерен
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Файлът не трябва да е нулев или празен
database.failedImportFile=Failed Import File database.failedImportFile=Неуспешно импортиране на файл
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Вашата сесия е изтекла. Моля, опреснете страницата и опитайте отново.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -390,9 +395,9 @@ home.certSign.title=Подпишете със сертификат
home.certSign.desc=Подписва PDF със сертификат/ключ (PEM/P12) home.certSign.desc=Подписва PDF със сертификат/ключ (PEM/P12)
certSign.tags=удостоверяване,PEM,P12,официален,шифроване certSign.tags=удостоверяване,PEM,P12,официален,шифроване
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Премахване на знака за сертификат
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=Премахване на подпис на сертификат от PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=удостоверяване,PEM,P12,официален,декриптиране
home.pageLayout.title=Оформление с няколко страници home.pageLayout.title=Оформление с няколко страници
home.pageLayout.desc=Слейте няколко страници от PDF документ в една страница home.pageLayout.desc=Слейте няколко страници от PDF документ в една страница
@@ -498,33 +503,33 @@ home.BookToPDF.title=Книга към PDF
home.BookToPDF.desc=Преобразува формати на книги/комикси в PDF с помощта на calibre home.BookToPDF.desc=Преобразува формати на книги/комикси в PDF с помощта на calibre
BookToPDF.tags=Книга,комикс,calibre,конвертиране,манга,Amazon,Kindle BookToPDF.tags=Книга,комикс,calibre,конвертиране,манга,Amazon,Kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Премахване на изображение
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Премахнете изображението от PDF, за да намалите размера на файла
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Премахване на изображение, операции на страници, админ страна, страна на сървъра
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Разделете PDF по глави
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Разделете PDF на множество файлове въз основа на неговата структура на глави.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=разделяне, глави, отметки, организиране
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Замени-инвертиране-на-цвят
replace-color.header=Replace-Invert Color PDF replace-color.header=Замяна-инвертиране на цвят PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Замяна и обръщане на цвят
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Заменете цвета на текста и фона в PDF и обърнете пълния цвят на PDF, за да намалите размера на файла
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Замяна на цвят, операции на страници, заден край, страна на сървъра
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Опции за замяна или инвертиране на цвят
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=По подразбиране (цветове с висок контраст по подразбиране)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=По избор (персонализирани цветове)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Пълно инвертиране (Инвертиране на всички цветове)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Цветови опции с висок контраст
replace-color.selectText.6=white text on black background replace-color.selectText.6=Бял текст на черен фон
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Черен текст на бял фон
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Жълт текст на черен фон
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Зелен текст на черен фон
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Изберете цвят на текста
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Изберете цвят на фона
replace-color.submit=Replace replace-color.submit=Замени
@@ -543,18 +548,17 @@ login.locked=Вашият акаунт е заключен.
login.signinTitle=Моля впишете се login.signinTitle=Моля впишете се
login.ssoSignIn=Влизане чрез еднократно влизане login.ssoSignIn=Влизане чрез еднократно влизане
login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=Регистрацията или влизането на нерегистрирани потребители в момента е блокирано. Моля, свържете се с администратора.
login.oauth2RequestNotFound=Заявката за оторизация не е намерена login.oauth2RequestNotFound=Заявката за оторизация не е намерена
login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя
login.oauth2invalidRequest=Невалидна заявка login.oauth2invalidRequest=Невалидна заявка
login.oauth2AccessDenied=Отказан достъп login.oauth2AccessDenied=Отказан достъп
login.oauth2InvalidTokenResponse=Невалиден отговор на токена login.oauth2InvalidTokenResponse=Невалиден отговор на токена
login.oauth2InvalidIdToken=Невалиден токен за идентификатор login.oauth2InvalidIdToken=Невалиден токен за идентификатор
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=Потребителят е деактивиран, влизането в момента е блокирано с това потребителско име. Моля, свържете се с администратора.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Вече сте влезли в
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=устройства. Моля, излезте от устройствата и опитайте отново.
login.toManySessions=You have too many active sessions login.toManySessions=Имате твърде много активни сесии
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Автоматично редактиране autoRedact.title=Автоматично редактиране
@@ -729,7 +733,7 @@ pageLayout.submit=Подайте
scalePages.title=Коригиране на мащаба на страницата scalePages.title=Коригиране на мащаба на страницата
scalePages.header=Коригиране на мащаба на страницата scalePages.header=Коригиране на мащаба на страницата
scalePages.pageSize=Размер на страница от документа. scalePages.pageSize=Размер на страница от документа.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Оригинален размер
scalePages.scaleFactor=Ниво на мащабиране (изрязване) на страница. scalePages.scaleFactor=Ниво на мащабиране (изрязване) на страница.
scalePages.submit=Подайте scalePages.submit=Подайте
@@ -749,14 +753,15 @@ certSign.showSig=Показване на подпис
certSign.reason=Причина certSign.reason=Причина
certSign.location=Местоположение certSign.location=Местоположение
certSign.name=Име certSign.name=Име
certSign.showLogo=Show Logo
certSign.submit=Подпишете PDF certSign.submit=Подпишете PDF
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Премахване на подписа на сертификата
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=Премахнете цифровия сертификат от PDF
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=Изберете PDF файл:
removeCertSign.submit=Remove Signature removeCertSign.submit=Премахване на подпис
#removeBlanks #removeBlanks
@@ -778,11 +783,14 @@ removeAnnotations.submit=Премахване
#compare #compare
compare.title=Сравнявай compare.title=Сравнявай
compare.header=Сравнявай PDF-и compare.header=Сравнявай PDF-и
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Цвят на маркирането 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Цвят на маркирането 2:
compare.document.1=Документ 1 compare.document.1=Документ 1
compare.document.2=Документ 2 compare.document.2=Документ 2
compare.submit=Сравнявай compare.submit=Сравнявай
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
#BookToPDF #BookToPDF
BookToPDF.title=Книги и комикси в PDF BookToPDF.title=Книги и комикси в PDF
@@ -805,6 +813,11 @@ sign.draw=Начертайте подпис
sign.text=Въвеждане на текст sign.text=Въвеждане на текст
sign.clear=Изчисти sign.clear=Изчисти
sign.add=Добави sign.add=Добави
sign.saved=Saved Signatures
sign.save=Save Signature
sign.personalSigs=Personal Signatures
sign.sharedSigs=Shared Signatures
sign.noSavedSigs=No saved signatures found
#repair #repair
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=Минимална контурна площ:
ScannerImageSplit.selectText.8=Задава минималния праг на контурната площ за изображение ScannerImageSplit.selectText.8=Задава минималния праг на контурната площ за изображение
ScannerImageSplit.selectText.9=Размер на рамката: ScannerImageSplit.selectText.9=Размер на рамката:
ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1). ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Python не е инсталиран. Изисква се да се изпълнява.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=Обработка на PDF чрез OCR
extractImages.title=Извличане на изображения extractImages.title=Извличане на изображения
extractImages.header=Извличане на изображения extractImages.header=Извличане на изображения
extractImages.selectText=Изберете формат на изображението, в който да преобразувате извлечените изображения extractImages.selectText=Изберете формат на изображението, в който да преобразувате извлечените изображения
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Запазване на дублирани изображения
extractImages.submit=Извличане extractImages.submit=Извличане
@@ -896,7 +909,7 @@ merge.title=Обединяване
merge.header=Обединяване на множество PDF файлове (2+) merge.header=Обединяване на множество PDF файлове (2+)
merge.sortByName=Сортиране по име merge.sortByName=Сортиране по име
merge.sortByDate=Сортиране по дата merge.sortByDate=Сортиране по дата
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Премахване на цифровия подпис в обединения файл?
merge.submit=Обединяване merge.submit=Обединяване
@@ -914,7 +927,7 @@ pdfOrganiser.mode.6=Четно-нечетно разделяне
pdfOrganiser.mode.7=Премахни първо pdfOrganiser.mode.7=Премахни първо
pdfOrganiser.mode.8=Премахване на последния pdfOrganiser.mode.8=Премахване на последния
pdfOrganiser.mode.9=Премахване на първия и последния pdfOrganiser.mode.9=Премахване на първия и последния
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Обединяване на четно и нечетно
pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1) pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
multiTool.title=PDF Мулти инструмент multiTool.title=PDF Мулти инструмент
multiTool.header=PDF Мулти инструмент multiTool.header=PDF Мулти инструмент
multiTool.uploadPrompts=Име на файл multiTool.uploadPrompts=Име на файл
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Преглед на PDF viewPdf.title=Преглед на PDF
@@ -983,7 +1007,7 @@ pdfToImage.color=Цвят
pdfToImage.grey=Скала на сивото pdfToImage.grey=Скала на сивото
pdfToImage.blackwhite=Черно и бяло (може да загубите данни!) pdfToImage.blackwhite=Черно и бяло (може да загубите данни!)
pdfToImage.submit=Преобразуване pdfToImage.submit=Преобразуване
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Python не е инсталиран. Изисква се за конвертиране на WebP.
#addPassword #addPassword
@@ -1020,7 +1044,7 @@ watermark.selectText.6=дължинаSpacer (Разстояние между в
watermark.selectText.7=Непрозрачност (0% - 100%): watermark.selectText.7=Непрозрачност (0% - 100%):
watermark.selectText.8=Тип воден знак: watermark.selectText.8=Тип воден знак:
watermark.selectText.9=Изображение за воден знак: watermark.selectText.9=Изображение за воден знак:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=Конвертирайте PDF в PDF-изображение
watermark.submit=Добавяне на воден знак watermark.submit=Добавяне на воден знак
watermark.type.1=Текст watermark.type.1=Текст
watermark.type.2=Изображение watermark.type.2=Изображение
@@ -1077,7 +1101,7 @@ pdfToPDFA.credit=Тази услуга използва ghostscript за PDF/A
pdfToPDFA.submit=Преобразуване pdfToPDFA.submit=Преобразуване
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
pdfToPDFA.outputFormat=Изходен формат pdfToPDFA.outputFormat=Изходен формат
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=PDF файлът съдържа цифров подпис. Това ще бъде премахнато в следващата стъпка.
#PDFToWord #PDFToWord
@@ -1118,10 +1142,10 @@ PDFToXML.credit=Тази услуга използва LibreOffice за прео
PDFToXML.submit=Преобразуване PDFToXML.submit=Преобразуване
#PDFToCSV #PDFToCSV
PDFToCSV.title=PDF ??? CSV PDFToCSV.title=PDF към CSV
PDFToCSV.header=PDF ??? CSV PDFToCSV.header=PDF към CSV
PDFToCSV.prompt=Изберете страница за извличане на таблица PDFToCSV.prompt=Изберете страница за извличане на таблица
PDFToCSV.submit=???? PDFToCSV.submit=Преобразуване
#split-by-size-or-count #split-by-size-or-count
split-by-size-or-count.title=Разделяне на PDF по размер или брой split-by-size-or-count.title=Разделяне на PDF по размер или брой
@@ -1179,15 +1203,15 @@ licenses.version=Версия
licenses.license=Лиценз licenses.license=Лиценз
#survey #survey
survey.nav=Survey survey.nav=Анкета
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Анкета
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF няма проследяване, така че искаме да чуем мнението на нашите потребители за подобряване на Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF се промени от последното проучване! За да научите повече, моля, проверете публикацията в нашия блог тук:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=С тези промени получаваме платена бизнес подкрепа и финансиране
survey.please=Please consider taking our survey! survey.please=Моля, помислете дали да не участвате в нашата анкета!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Изскачащият прозорец с анкетата ще бъде деактивиран при следващите актуализации, но ще бъде наличен в долната част на страницата)
survey.button=Take Survey survey.button=Участвайте в анкетата
survey.dontShowAgain=Don't show again survey.dontShowAgain=Не показвай повече
#error #error
@@ -1205,21 +1229,19 @@ error.discordSubmit=Discord - Изпратете запитване за под
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Премахване на изображението
removeImage.header=Remove image removeImage.header=Премахване на изображението
removeImage.removeImage=Remove image removeImage.removeImage=Премахване на изображението
removeImage.submit=Remove image removeImage.submit=Премахване на изображението
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=Разделете PDF по глави
splitByChapters.header=Разделете PDF по глави
splitByChapters.bookmarkLevel=Ниво на отметка
splitByChapters.includeMetadata=Включете метаданни
splitByChapters.allowDuplicates=Разрешаване на дубликати
splitByChapters.desc.1=Този инструмент разделя PDF файл на множество PDF файлове въз основа на неговата структура на глави.
splitByChapters.desc.2=Ниво на отметка: Изберете нивото на отметките, които да използвате за разделяне (0 за най-високо ниво, 1 за второ ниво и т.н.).
splitByChapters.desc.3=Включване на метаданни: Ако е отметнато, метаданните на оригиналния PDF ще бъдат включени във всеки разделен PDF.
splitByChapters.desc.4=Разрешаване на дубликати: Ако е отметнато, позволява множество отметки на една и съща страница за създаване на отделни PDF файлове.
splitByChapters.submit=Разделяне на PDF

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Velikost písma
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Název písma
pdfPrompt=Vyberte PDF soubory pdfPrompt=Vyberte PDF soubory
multiPdfPrompt=Vyberte PDF soubory (2+) multiPdfPrompt=Vyberte PDF soubory (2+)
multiPdfDropPrompt=Vyberte (nebo přetáhněte) všechny požadované PDF soubory multiPdfDropPrompt=Vyberte (nebo přetáhněte) všechny požadované PDF soubory
@@ -56,12 +56,12 @@ userNotFoundMessage=Uživatel nenalezen.
incorrectPasswordMessage=Současné heslo není správné. incorrectPasswordMessage=Současné heslo není správné.
usernameExistsMessage=Nové uživatelské jméno již existuje. usernameExistsMessage=Nové uživatelské jméno již existuje.
invalidUsernameMessage=Nesprávné uživatelské jméno, smí obsahovat pouze písmena, číslice a následující speciální znaky @._+- nebo musí být validní emailová adresa. invalidUsernameMessage=Nesprávné uživatelské jméno, smí obsahovat pouze písmena, číslice a následující speciální znaky @._+- nebo musí být validní emailová adresa.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=Heslo nemůže být prázdné a nemůže mít mezery na začátku nebo konci.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Nové heslo musí shodovat s potvrzujícím novým heslem.
deleteCurrentUserMessage=Nelze smazat aktuální přihlášeného uživatele. deleteCurrentUserMessage=Nelze smazat aktuální přihlášeného uživatele.
deleteUsernameExistsMessage=Uživatelské jméno neexistuje a nelze ho smazat. deleteUsernameExistsMessage=Uživatelské jméno neexistuje a nelze ho smazat.
downgradeCurrentUserMessage=Nelze snížit roli aktuálního uživatele. downgradeCurrentUserMessage=Nelze snížit roli aktuálního uživatele.
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=Současný uživatel nemůže být zakázán
downgradeCurrentUserLongMessage=Nelze snížit roli aktuálního uživatele. Proto nebude aktuální uživatel zobrazen. downgradeCurrentUserLongMessage=Nelze snížit roli aktuálního uživatele. Proto nebude aktuální uživatel zobrazen.
userAlreadyExistsOAuthMessage=Uživatel již existuje jako OAuth2 uživatel. userAlreadyExistsOAuthMessage=Uživatel již existuje jako OAuth2 uživatel.
userAlreadyExistsWebMessage=Uživatel již existuje jako webový uživatel. userAlreadyExistsWebMessage=Uživatel již existuje jako webový uživatel.
@@ -75,16 +75,19 @@ visitGithub=Navštivte Github repozitář
donate=Přispějte donate=Přispějte
color=Barva color=Barva
sponsor=Sponzor sponsor=Sponzor
info=Info info=Informace
pro=Pro pro=Pro
page=Page page=Strana
pages=Pages pages=Strany
loading=Načítání...
addToDoc=Přidat do dokumentu
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Politika soukromí
legal.terms=Terms and Conditions legal.terms=Podmínky použití
legal.accessibility=Accessibility legal.accessibility=Snaha o přístupnost
legal.cookie=Cookie Policy legal.cookie=Zásada cookies
legal.impressum=Impressum legal.impressum=Odborné prohlášení
############### ###############
# Pipeline # # Pipeline #
@@ -96,7 +99,7 @@ pipeline.defaultOption=Vlastní
pipeline.submitButton=Odeslat pipeline.submitButton=Odeslat
pipeline.help=Pomoc s pipeline pipeline.help=Pomoc s pipeline
pipeline.scanHelp=Pomoc se skenováním adresáře pipeline.scanHelp=Pomoc se skenováním adresáře
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Opravdu chcete smazat tento kanál?
###################### ######################
# Pipeline Options # # Pipeline Options #
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Ověřit
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Upgradujte na Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Tato funkce je k dispozici pouze pro uživatelé s předplatným Pro.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro podporuje konfigurační soubory YAML a další funkce SSO.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Hledáte větší počet správních funkcí uživatelů? Podívejte se na Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Chcete-li zlepšit Stirling PDF, pomozte nám.
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF má povolené analýzy pro to, abychom mohli zlepšovat produkt. Nezaznamenáváme žádné osobní informace nebo obsah souborů.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Považte za možnost povolení analýz k tomu, abychom mohli růst Stirling-PDF a lépe pochopit naši skupinu uživatelů.
analytics.enable=Enable analytics analytics.enable=Zapnout analýzy
analytics.disable=Disable analytics analytics.disable=Vypnout analýzy
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Můžete změnit nastavení pro analýzy v souboru config/settings.yml
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Jazyky
navbar.settings=Nastavení navbar.settings=Nastavení
navbar.allTools=Nástroje navbar.allTools=Nástroje
navbar.multiTool=Multifunkční nástroje navbar.multiTool=Multifunkční nástroje
navbar.search=Search
navbar.sections.organize=Organizovat navbar.sections.organize=Organizovat
navbar.sections.convertTo=Převést do PDF navbar.sections.convertTo=Převést do PDF
navbar.sections.convertFrom=Převést z PDF navbar.sections.convertFrom=Převést z PDF
navbar.sections.security=Podpis a Bezpečnost navbar.sections.security=Podpis a Bezpečnost
navbar.sections.advance=Pokročilé navbar.sections.advance=Pokročilé
navbar.sections.edit=Prohlédnout a Upravit navbar.sections.edit=Prohlédnout a Upravit
navbar.sections.popular=Popular navbar.sections.popular=Populární
############# #############
# SETTINGS # # SETTINGS #
@@ -162,7 +166,7 @@ settings.zipThreshold=Zazipuj soubory, když překročí počet stažených soub
settings.signOut=Odhlásit settings.signOut=Odhlásit
settings.accountSettings=Nastavení Účtu settings.accountSettings=Nastavení Účtu
settings.bored.help=Umožňuje hru s easter eggy settings.bored.help=Umožňuje hru s easter eggy
settings.cacheInputs.name=Save form inputs settings.cacheInputs.name=Ukládání vstupů formuláře
settings.cacheInputs.help=Umožňuje uložit dříve použité vstupy pro budoucí použití settings.cacheInputs.help=Umožňuje uložit dříve použité vstupy pro budoucí použití
changeCreds.title=Změnit pověření changeCreds.title=Změnit pověření
@@ -198,13 +202,13 @@ account.syncToAccount=Synchronizovat Účet <- Prohlížeč
adminUserSettings.title=Nastavení Uživatelského Nastavení adminUserSettings.title=Nastavení Uživatelského Nastavení
adminUserSettings.header=Admin User Control Settings adminUserSettings.header=Nastavení správce uživatelů
adminUserSettings.admin=Admin adminUserSettings.admin=Správce
adminUserSettings.user=Uživatel adminUserSettings.user=Uživatel
adminUserSettings.addUser=Přidat Nového Uživatele adminUserSettings.addUser=Přidat Nového Uživatele
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Smazat uživatele
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=Měli by se uživatel smazat?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Měli by se změnit stav uživatele (vytřída/aktivace)?
adminUserSettings.usernameInfo=Uživatelské Jméno může obsahovat pouze písmena, čísla a následující speciální znaky @._+- nebo musí být správná emailová adresa. adminUserSettings.usernameInfo=Uživatelské Jméno může obsahovat pouze písmena, čísla a následující speciální znaky @._+- nebo musí být správná emailová adresa.
adminUserSettings.roles=Role adminUserSettings.roles=Role
adminUserSettings.role=Role adminUserSettings.role=Role
@@ -218,32 +222,33 @@ adminUserSettings.forceChange=Vynutit uživateli změnu hesla při přihlášen
adminUserSettings.submit=Uložit Uživatele adminUserSettings.submit=Uložit Uživatele
adminUserSettings.changeUserRole=Zmenit Roli Uživatele adminUserSettings.changeUserRole=Zmenit Roli Uživatele
adminUserSettings.authenticated=Ověřeno adminUserSettings.authenticated=Ověřeno
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Upravit vlastní profil
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=povolený uživatel
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=zakázáný uživatel
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Aktivní uživatelé:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Zakázанные uživatelé:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Celkem uživatelů:
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Poslední žádost
database.title=Database Import/Export database.title=Import/Export databáze
database.header=Database Import/Export database.header=Import/Export databáze
database.fileName=File Name database.fileName=Název souboru
database.creationDate=Creation Date database.creationDate=Datum vytvoření
database.fileSize=File Size database.fileSize=Velikost souboru
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Smazat záložní soubor
database.importBackupFile=Import Backup File database.importBackupFile=Import zálohy souboru
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Stáhnout zálohový soubor
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=Při importu dat je důležité zajistit správnou strukturu. Pokud jste nejistí, jak se chovat, hledajte konzultaci a podporu od profesionala. Chyba v struktuře může vést k selhání aplikace, dokonce i k tomu, že by aplikace nemohla být spuštěna.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=Název souboru nezáleží při nahrávání. Bude jeho zpětně znovu pojmenován podle formáту backup_user_yyyyMMddHHmm.sql, což zajišťuje konzistentní pravidlo označení.
database.submit=Import Backup database.submit=Import zálohy
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Import do databáze byl úspěšný
database.fileNotFound=File not Found database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Soubor nemůže být null nebo prázdný
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Vaše sesace vypršela. Prosím obnovte stránku a zkusit to znovu.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -347,7 +352,7 @@ PDFToPresentation.tags=snímky,přehled,kancelář,microsoft
home.PDFToText.title=PDF na RTF (Text) home.PDFToText.title=PDF na RTF (Text)
home.PDFToText.desc=Převod PDF do formátu Textu nebo RTF home.PDFToText.desc=Převod PDF do formátu Textu nebo RTF
PDFToText.tags=richformat,richtextformat,rich text format PDFToText.tags=bohatý formátování, bohaté formátování, bohatej formátkace textu
home.PDFToHTML.title=PDF na HTML home.PDFToHTML.title=PDF na HTML
home.PDFToHTML.desc=Převod PDF do formátu HTML home.PDFToHTML.desc=Převod PDF do formátu HTML
@@ -390,9 +395,9 @@ home.certSign.title=Podpis s certifikátem
home.certSign.desc=Podpis PDF s certifikátem/klíčem (PEM/P12) home.certSign.desc=Podpis PDF s certifikátem/klíčem (PEM/P12)
certSign.tags=autentizace,PEM,P12,oficiální,šifrování certSign.tags=autentizace,PEM,P12,oficiální,šifrování
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Odstranit certifikátovou podepsanost
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=Odstranit certifikátovou podepsanost z PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=autentizace, PEM, P12, úřední, dešifrování
home.pageLayout.title=Vícestránkové rozložení home.pageLayout.title=Vícestránkové rozložení
home.pageLayout.desc=Sloučení více stránek dokumentu PDF do jedné stránky home.pageLayout.desc=Sloučení více stránek dokumentu PDF do jedné stránky
@@ -498,33 +503,33 @@ home.BookToPDF.title=Kniha na PDF
home.BookToPDF.desc=Převádí formáty knih/komiksů do PDF pomocí calibre home.BookToPDF.desc=Převádí formáty knih/komiksů do PDF pomocí calibre
BookToPDF.tags=Kniha,Komiks,Calibre,Konvertovat,manga,amazon,kindle,epub,mobi,azw3,docx,rtf,txt,html,lit,fb2,pdb,lrf BookToPDF.tags=Kniha,Komiks,Calibre,Konvertovat,manga,amazon,kindle,epub,mobi,azw3,docx,rtf,txt,html,lit,fb2,pdb,lrf
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Odstranit obrázek
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Odstranit obrázek z PDF k snížení velikosti souboru
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Odstranit obrázek, operace na stránkách, záložní strana, serverové čidla
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Rozdělit PDF podle kapitol
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Rozdělit PDF do více souborů na základě jeho struktury kapitol.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=rozdělení, kapitoly, zápisky, organizace
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Nahradit inverzní barvu PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Nahradit barvy pro text a pozadí v PDF a inverzní celý barvový spektrum PDF k snižení velikosti souboru
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Nahrazovat barvu, operace na stránkách, záložní strana, serverové čidla
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Možnosti nahrazení nebo inverze barev
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Výchozí (vysoká kontrastová barva)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Vlastní (vlastní barvy)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Celé inverzní (inverzní všechny barvy)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Možnosti vysoké kontrastové barvy
replace-color.selectText.6=white text on black background replace-color.selectText.6=Bílá text na černém pozadí
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Černý text na bílé pozadí
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Zlutý text na černém pozadí
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Zelený text na černém pozadí
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Vyberte barvu textu
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Vyberte barvu pozadí
replace-color.submit=Replace replace-color.submit=Nahradit
@@ -534,46 +539,45 @@ replace-color.submit=Replace
# # # #
########################### ###########################
#login #login
login.title=Sign in login.title=Přihlášení
login.header=Sign in login.header=Přihlášení
login.signin=Sign in login.signin=Přihlásit se
login.rememberme=Remember me login.rememberme=Zapamatovat si mě
login.invalid=Invalid username or password. login.invalid=Neplatné uživatelské jméno nebo heslo.
login.locked=Your account has been locked. login.locked=Vaše účto bylo zablokováno.
login.signinTitle=Please sign in login.signinTitle=Prosím, přihlaste se
login.ssoSignIn=Login via Single Sign-on login.ssoSignIn=Přihlášení prostřednictvím jednotného přihlašovacího systému
login.oauth2AutoCreateDisabled=OAUTH2 Auto-Create User Disabled login.oauth2AutoCreateDisabled=Automatické vytvoření uživatele OAUTH2 je vypnuté
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=Registrace nebo přihlášení nepozitrovených uživatelů aktuálně jsou zablokovaná. Štěňte na správce.
login.oauth2RequestNotFound=Authorization request not found login.oauth2RequestNotFound=Požadavek na autorizaci nenalezen
login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2InvalidUserInfoResponse=Neplatný odpověď s informacemi o uživateli
login.oauth2invalidRequest=Invalid Request login.oauth2invalidRequest=Neplatný požadavek
login.oauth2AccessDenied=Access Denied login.oauth2AccessDenied=Přístup zazobán
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Neplatná odpověď tokenu
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Neplatný identifikační token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=Uživatel je deaktivován, přihlášení aktuálně pro tuto uživatelskou jmena je zakázáno. Kontaktujte správce.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Jste již přihlášeni na
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=zariadení. Odhlašujte se z těchto zařízení a zkuste to znovu.
login.toManySessions=You have too many active sessions login.toManySessions=Máte příliš mnoho aktivních sesií
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Automatické smazání
autoRedact.header=Auto Redact autoRedact.header=Automatické smazání
autoRedact.colorLabel=Colour autoRedact.colorLabel=Barva
autoRedact.textsToRedactLabel=Text to Redact (line-separated) autoRedact.textsToRedactLabel=Text k smazání (řádkově oddělený)
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret autoRedact.textsToRedactPlaceholder=např. \nKonfidenciální \nSkrytější
autoRedact.useRegexLabel=Use Regex autoRedact.useRegexLabel=Použít regulární výraz
autoRedact.wholeWordSearchLabel=Whole Word Search autoRedact.wholeWordSearchLabel=Hledání celých slov
autoRedact.customPaddingLabel=Custom Extra Padding autoRedact.customPaddingLabel=Vlastní doplňující vzdálenost
autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box) autoRedact.convertPDFToImageLabel=Převést PDF do PDF-Obrázku (Pro odstranění textu za obdélníkem)
autoRedact.submitButton=Submit autoRedact.submitButton=Odeslat
#showJS #showJS
showJS.title=Show Javascript showJS.title=Zobrazit JavaScript
showJS.header=Show Javascript showJS.header=Zobrazit JavaScript
showJS.downloadJS=Download Javascript showJS.downloadJS=Stáhnout JavaScript
showJS.submit=Show showJS.submit=Zobrazit
#pdfToSinglePage #pdfToSinglePage
@@ -729,7 +733,7 @@ pageLayout.submit=Odeslat
scalePages.title=Upravit měřítko stránky scalePages.title=Upravit měřítko stránky
scalePages.header=Upravit měřítko stránky scalePages.header=Upravit měřítko stránky
scalePages.pageSize=Velikost stránky dokumentu. scalePages.pageSize=Velikost stránky dokumentu.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Původní velikost
scalePages.scaleFactor=Úroveň přiblížení (oříznutí) stránky. scalePages.scaleFactor=Úroveň přiblížení (oříznutí) stránky.
scalePages.submit=Odeslat scalePages.submit=Odeslat
@@ -749,14 +753,15 @@ certSign.showSig=Ukázat podpis
certSign.reason=Důvod certSign.reason=Důvod
certSign.location=Umístění certSign.location=Umístění
certSign.name=Název certSign.name=Název
certSign.showLogo=Zobraz loga
certSign.submit=Podepsat PDF certSign.submit=Podepsat PDF
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Odstranit certifikátovou podpisu
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=Odstranění digitálního certifikátu z PDF
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=Vyberte soubor PDF:
removeCertSign.submit=Remove Signature removeCertSign.submit=Odstranit podpis
#removeBlanks #removeBlanks
@@ -778,11 +783,14 @@ removeAnnotations.submit=Odebrat
#compare #compare
compare.title=Porovnat compare.title=Porovnat
compare.header=Porovnat PDF compare.header=Porovnat PDF
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Podtržovací barva 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Podtržovací barva 2:
compare.document.1=Dokument 1 compare.document.1=Dokument 1
compare.document.2=Dokument 2 compare.document.2=Dokument 2
compare.submit=Porovnat compare.submit=Porovnat
compare.complex.message=Jedno nebo oba z předložených dokumentů jsou velké soubory, přesnost porovnání může být snižena
compare.large.file.message=Jeden nebo oba předložené dokumenty jsou příliš velké na zpracování
compare.no.text.message=Jedno nebo oba vybrané PDF soubory nemají textový obsah. Zvolte PDF soubory se textem pro porovnání.
#BookToPDF #BookToPDF
BookToPDF.title=Knihy a komiksy do PDF BookToPDF.title=Knihy a komiksy do PDF
@@ -805,6 +813,11 @@ sign.draw=Nakreslit podpis
sign.text=Vstup textu sign.text=Vstup textu
sign.clear=Vymazat sign.clear=Vymazat
sign.add=Přidat sign.add=Přidat
sign.saved=Uložené podpisy
sign.save=Uložit podpis
sign.personalSigs=Osobní podpisy
sign.sharedSigs=Sdílené podpisy
sign.noSavedSigs=Nenašly se žádné uložené podpisy
#repair #repair
@@ -823,7 +836,7 @@ flatten.submit=Zploštit
#ScannerImageSplit #ScannerImageSplit
ScannerImageSplit.selectText.1=Práh úhlu: ScannerImageSplit.selectText.1=Práh úhlu:
ScannerImageSplit.selectText.2=Nastaví minimální absolutní úhel, který je vyžadován k otočení obrázku (výchozí: 10). ScannerImageSplit.selectText.2=Nastaví minimální absolutní úhel, který je vyžadován k otočení obrázku (výchozí: 10).
ScannerImageSplit.selectText.3=Tolerance: ScannerImageSplit.selectText.3=Tolerancie:
ScannerImageSplit.selectText.4=Určuje rozsah barevné variace kolem odhadované barvy pozadí (výchozí: 30). ScannerImageSplit.selectText.4=Určuje rozsah barevné variace kolem odhadované barvy pozadí (výchozí: 30).
ScannerImageSplit.selectText.5=Minimální plocha: ScannerImageSplit.selectText.5=Minimální plocha:
ScannerImageSplit.selectText.6=Nastaví minimální plošný práh pro fotografii (výchozí: 10000). ScannerImageSplit.selectText.6=Nastaví minimální plošný práh pro fotografii (výchozí: 10000).
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=Minimální plocha kontury:
ScannerImageSplit.selectText.8=Nastaví minimální plošný práh kontury pro fotografii ScannerImageSplit.selectText.8=Nastaví minimální plošný práh kontury pro fotografii
ScannerImageSplit.selectText.9=Velikost okraje: ScannerImageSplit.selectText.9=Velikost okraje:
ScannerImageSplit.selectText.10=Nastaví velikost okraje přidaného a odebraného k zabránění bílých ohraničení ve výstupu (výchozí: 1). ScannerImageSplit.selectText.10=Nastaví velikost okraje přidaného a odebraného k zabránění bílých ohraničení ve výstupu (výchozí: 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Python není nainstalován. Je potřeba pro jeho spuštění.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=Zpracovat PDF s OCR
extractImages.title=Extrahovat obrázky extractImages.title=Extrahovat obrázky
extractImages.header=Extrahovat obrázky extractImages.header=Extrahovat obrázky
extractImages.selectText=Vyberte formát obrázku pro extrahované obrázky extractImages.selectText=Vyberte formát obrázku pro extrahované obrázky
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Uložit duplikátní obrázky
extractImages.submit=Extrahovat extractImages.submit=Extrahovat
@@ -896,7 +909,7 @@ merge.title=Sloučit
merge.header=Sloučit více PDF (2+) merge.header=Sloučit více PDF (2+)
merge.sortByName=Seřadit podle názvu merge.sortByName=Seřadit podle názvu
merge.sortByDate=Seřadit podle data merge.sortByDate=Seřadit podle data
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Odebrat digitální podpis v převedeném souboru?
merge.submit=Sloučit merge.submit=Sloučit
@@ -914,7 +927,7 @@ pdfOrganiser.mode.6=Liché-Sudé rozdělení
pdfOrganiser.mode.7=Odstranit první pdfOrganiser.mode.7=Odstranit první
pdfOrganiser.mode.8=Odstranit poslední pdfOrganiser.mode.8=Odstranit poslední
pdfOrganiser.mode.9=Odstranit první a poslední pdfOrganiser.mode.9=Odstranit první a poslední
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Lomeno spojení
pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1) pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1)
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(např. 1,3,2 nebo 4-8,2,10-12 nebo 2n-1)
multiTool.title=Vícefunkční nástroj pro PDF multiTool.title=Vícefunkční nástroj pro PDF
multiTool.header=Vícefunkční nástroj pro PDF multiTool.header=Vícefunkční nástroj pro PDF
multiTool.uploadPrompts=Název souboru multiTool.uploadPrompts=Název souboru
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Zobrazit PDF viewPdf.title=Zobrazit PDF
@@ -983,7 +1007,7 @@ pdfToImage.color=Barevný
pdfToImage.grey=Stupně šedi pdfToImage.grey=Stupně šedi
pdfToImage.blackwhite=Černobílý (Může dojít k ztrátě dat!) pdfToImage.blackwhite=Černobílý (Může dojít k ztrátě dat!)
pdfToImage.submit=Převést pdfToImage.submit=Převést
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Python není nainstalován. Potřebuje se pro konverzi do WebP.
#addPassword #addPassword
@@ -1020,7 +1044,7 @@ watermark.selectText.6=Výška mezery (Mezera mezi každým vodoznakem svisle):
watermark.selectText.7=Průhlednost (0% - 100%): watermark.selectText.7=Průhlednost (0% - 100%):
watermark.selectText.8=Typ vodoznaku: watermark.selectText.8=Typ vodoznaku:
watermark.selectText.9=Obrázek vodoznaku: watermark.selectText.9=Obrázek vodoznaku:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=Převést PDF na PDF-Obrázek
watermark.submit=Přidat vodoznak watermark.submit=Přidat vodoznak
watermark.type.1=Text watermark.type.1=Text
watermark.type.2=Obrázek watermark.type.2=Obrázek
@@ -1077,7 +1101,7 @@ pdfToPDFA.credit=Tato služba používá ghostscript pro konverzi do formátu PD
pdfToPDFA.submit=Převést pdfToPDFA.submit=Převést
pdfToPDFA.tip=V současné době nepracuje pro více vstupů najednou pdfToPDFA.tip=V současné době nepracuje pro více vstupů najednou
pdfToPDFA.outputFormat=Výstupní formát pdfToPDFA.outputFormat=Výstupní formát
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=PDF obsahuje digitální podpis, který bude odebrán v následujícím kroku.
#PDFToWord #PDFToWord
@@ -1179,15 +1203,15 @@ licenses.version=Verze
licenses.license=Licence licenses.license=Licence
#survey #survey
survey.nav=Survey survey.nav=Přehled
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Přehled
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF nemá sledování, proto chceme vaše názory k podnětom k lepšímu Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF se změnil od posledního příspěvku! Další informace najdete na našem blogu zde:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=S těmito změnami získáváme platné podpory a finanční podporu od business partnerů.
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Přehled bude v budoucnu zakázán, ale zůstane k dispozici na nástavbě)
survey.button=Take Survey survey.button=Udělat Příspěvek
survey.dontShowAgain=Don't show again survey.dontShowAgain=Neukazuj to znovu
#error #error
@@ -1205,21 +1229,19 @@ error.discordSubmit=Discord - Odeslat příspěvek podpory
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Odstranit obrázek
removeImage.header=Remove image removeImage.header=Odstranit obrázek
removeImage.removeImage=Remove image removeImage.removeImage=Odstranit obrázek
removeImage.submit=Remove image removeImage.submit=Odebrat obrázek
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=Podělit PDF podle kapitol
splitByChapters.header=Podělení PDF na kapitoly
splitByChapters.bookmarkLevel=Úroveň záhlaví
splitByChapters.includeMetadata=Zahrnout metadatů
splitByChapters.allowDuplicates=Povolit duplicitní záznamy
splitByChapters.desc.1=Tento nástroj podělí PDF soubor na více PDF soubory na základě struktury kapitol.
splitByChapters.desc.2=Úroveň záhlaví: Zvolte úroveň záhlaví pro použití při oddělování (0 pro hlavní, 1 pro druhou úroveň atd.).
splitByChapters.desc.3=Zahrnout metadatů: Pokud je zaškrtnuto, původní metadata PDF souboru budou zahrnuty do každého odděleného PDF souboru.
splitByChapters.desc.4=Povolit duplicitní záznamy: Pokud je zaškrtnuto, návštěvníci mohou vytvořit samostatné PDF soubory z více záhlaví na stejné straně.
splitByChapters.submit=Podělit se PDF

View File

@@ -74,17 +74,20 @@ seeDockerHub=Se Docker Hub
visitGithub=Besøg Github Repository visitGithub=Besøg Github Repository
donate=Donér donate=Donér
color=Farve color=Farve
sponsor=Sponsor sponsor=Sponsorer
info=Info info=Info
pro=Pro pro=Pro
page=Page page=Sidenummer
pages=Pages pages=Sideantal
loading=Laster...
addToDoc=Tilføj til Dokument
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Privacy Policy
legal.terms=Terms and Conditions legal.terms=Vilkår og betingelser
legal.accessibility=Accessibility legal.accessibility=Adgangsnævnteglen
legal.cookie=Cookie Policy legal.cookie=Cokiebelejring
legal.impressum=Impressum legal.impressum=Angivelse af ansvar
############### ###############
# Pipeline # # Pipeline #
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Validér
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Opgrader til Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Denne funktion er kun tilgængelig for Pro-brugere.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro understøtter YAML-konfigurationsfiler og andre SSO-funktioner.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=søger du flere funktioner til brugerstyring? Prøv Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Vil du gøre Stirling PDF bedre?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF har indsat analytics for at hjælpe os med at forbedre produktet. Vi følger ikke nogen personoplysninger eller filinhold.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Bevægelsesmæssigt aktiver du analytics for at hjælpe Stirling-PDF med at vokse og til atstå os bedre at forstå vores brugere.
analytics.enable=Enable analytics analytics.enable=Aktivér analytics
analytics.disable=Disable analytics analytics.disable=Deaktiver analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Du kan ændre analytics-indstillingerne i config/settings.yml-filen
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Sprog
navbar.settings=Indstillinger navbar.settings=Indstillinger
navbar.allTools=Værktøjer navbar.allTools=Værktøjer
navbar.multiTool=Multi Værktøjer navbar.multiTool=Multi Værktøjer
navbar.search=Search
navbar.sections.organize=Organisér navbar.sections.organize=Organisér
navbar.sections.convertTo=Konvertér til PDF navbar.sections.convertTo=Konvertér til PDF
navbar.sections.convertFrom=Konvertér fra PDF navbar.sections.convertFrom=Konvertér fra PDF
navbar.sections.security=Signér & Sikkerhed navbar.sections.security=Signér & Sikkerhed
navbar.sections.advance=Avanceret navbar.sections.advance=Avanceret
navbar.sections.edit=Vis & Redigér navbar.sections.edit=Vis & Redigér
navbar.sections.popular=Popular navbar.sections.popular=Populære
############# #############
# SETTINGS # # SETTINGS #
@@ -199,7 +203,7 @@ account.syncToAccount=Synkroniser Konto <- Browser
adminUserSettings.title=Brugerkontrolindstillinger adminUserSettings.title=Brugerkontrolindstillinger
adminUserSettings.header=Admin Brugerkontrolindstillinger adminUserSettings.header=Admin Brugerkontrolindstillinger
adminUserSettings.admin=Admin adminUserSettings.admin=Administrer
adminUserSettings.user=Bruger adminUserSettings.user=Bruger
adminUserSettings.addUser=Tilføj Ny Bruger adminUserSettings.addUser=Tilføj Ny Bruger
adminUserSettings.deleteUser=Slet Bruger adminUserSettings.deleteUser=Slet Bruger
@@ -243,7 +247,8 @@ database.fileNotFound=Fil ikke fundet
database.fileNullOrEmpty=Fil må ikke være null eller tom database.fileNullOrEmpty=Fil må ikke være null eller tom
database.failedImportFile=Kunne ikke importere fil database.failedImportFile=Kunne ikke importere fil
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Din sesions tid har udløbet. Genlad siden og prøv igen.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -503,28 +508,28 @@ home.removeImagePdf.desc=Fjern billede fra PDF for at reducere filstørrelse
removeImagePdf.tags=Fjern Billede,Sideoperationer,Back end,server side removeImagePdf.tags=Fjern Billede,Sideoperationer,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Partitioner PDF efter kapitler
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Partitioner en PDF i flere filer baseret på dens kapitelstruktur.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=partitionering,kapitler,merker,organisering
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Erstat-omgivende Farve PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Erstatt farve for tekst og baggrund i en PDF og omgivende farve til fuld farve af PDF for at redusere filstørrelsen.
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Erstat Farve,Side operationer,Behandling,server side
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Erstatt eller omgivende Farvemuligheder
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Standard (høj kontrastfarver)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Brugerdefineret (anpassede farver)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Inverter alle farver
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Høj kontrastfarveindstillinger
replace-color.selectText.6=white text on black background replace-color.selectText.6=Hvid tekst på sort baggrund
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Sort tekst på hvid baggrund
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Gul tekst på sort baggrund
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Grøn tekst på sort baggrund
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Vælg tekstfarve
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Vælg baggrundsfarve
replace-color.submit=Replace replace-color.submit=Erstat
@@ -551,10 +556,9 @@ login.oauth2AccessDenied=Adgang Nægtet
login.oauth2InvalidTokenResponse=Ugyldigt Token Svar login.oauth2InvalidTokenResponse=Ugyldigt Token Svar
login.oauth2InvalidIdToken=Ugyldigt Id Token login.oauth2InvalidIdToken=Ugyldigt Id Token
login.userIsDisabled=Bruger er deaktiveret, login er i øjeblikket blokeret med dette brugernavn. Kontakt venligst administratoren. login.userIsDisabled=Bruger er deaktiveret, login er i øjeblikket blokeret med dette brugernavn. Kontakt venligst administratoren.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Du er allerede logget ind på
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=enheder. Log ud af disse enheder og prøv igen.
login.toManySessions=You have too many active sessions login.toManySessions=Du har for mange aktive sessoner
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Rediger autoRedact.title=Auto Rediger
@@ -572,7 +576,7 @@ autoRedact.submitButton=Indsend
#showJS #showJS
showJS.title=Vis Javascript showJS.title=Vis Javascript
showJS.header=Vis Javascript showJS.header=Vis Javascript
showJS.downloadJS=Download Javascript showJS.downloadJS=Last ned Javascript
showJS.submit=Vis showJS.submit=Vis
@@ -629,7 +633,7 @@ HTMLToPDF.printBackground=Render baggrunden af hjemmesider.
HTMLToPDF.defaultHeader=Aktivér Standard Header (Navn og sidenummerAS HTMLToPDF.defaultHeader=Aktivér Standard Header (Navn og sidenummerAS
HTMLToPDF.cssMediaType=Ændre CSS-medietypen for siden. HTMLToPDF.cssMediaType=Ændre CSS-medietypen for siden.
HTMLToPDF.none=Ingen HTMLToPDF.none=Ingen
HTMLToPDF.print=Print HTMLToPDF.print=Skriv ud
HTMLToPDF.screen=Skærm HTMLToPDF.screen=Skærm
@@ -641,9 +645,9 @@ AddStampRequest.stampText=Stempeltekst
AddStampRequest.stampImage=Stempelbillede AddStampRequest.stampImage=Stempelbillede
AddStampRequest.alphabet=Alfabet AddStampRequest.alphabet=Alfabet
AddStampRequest.fontSize=Skrift/Billedstørrelse AddStampRequest.fontSize=Skrift/Billedstørrelse
AddStampRequest.rotation=Rotation AddStampRequest.rotation=Vendelse
AddStampRequest.opacity=Gennemsigtighed AddStampRequest.opacity=Gennemsigtighed
AddStampRequest.position=Position AddStampRequest.position=Plassering
AddStampRequest.overrideX=Tilsidesæt X-koordinat AddStampRequest.overrideX=Tilsidesæt X-koordinat
AddStampRequest.overrideY=Tilsidesæt Y-koordinat AddStampRequest.overrideY=Tilsidesæt Y-koordinat
AddStampRequest.customMargin=Brugerdefineret Margin AddStampRequest.customMargin=Brugerdefineret Margin
@@ -667,7 +671,7 @@ addPageNumbers.title=Tilføj Sidenumre
addPageNumbers.header=Tilføj Sidenumre addPageNumbers.header=Tilføj Sidenumre
addPageNumbers.selectText.1=Vælg PDF-fil: addPageNumbers.selectText.1=Vælg PDF-fil:
addPageNumbers.selectText.2=Marginstørrelse addPageNumbers.selectText.2=Marginstørrelse
addPageNumbers.selectText.3=Position addPageNumbers.selectText.3=Plassering
addPageNumbers.selectText.4=Startnummer addPageNumbers.selectText.4=Startnummer
addPageNumbers.selectText.5=Sider at nummerere addPageNumbers.selectText.5=Sider at nummerere
addPageNumbers.selectText.6=Brugerdefineret Tekst addPageNumbers.selectText.6=Brugerdefineret Tekst
@@ -749,6 +753,7 @@ certSign.showSig=Vis Underskrift
certSign.reason=Årsag certSign.reason=Årsag
certSign.location=Placering certSign.location=Placering
certSign.name=Navn certSign.name=Navn
certSign.showLogo=Vis Logo
certSign.submit=Underskriv PDF certSign.submit=Underskriv PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=Fremhævningsfarve 2:
compare.document.1=Dokument 1 compare.document.1=Dokument 1
compare.document.2=Dokument 2 compare.document.2=Dokument 2
compare.submit=Sammenlign compare.submit=Sammenlign
compare.complex.message=Et eller begge af de angivne dokumenter er store filer, præcisionen ved sammenligningen kan geminse.
compare.large.file.message=Et eller Begge af de Angivne Dokumenter Er For Store At Behandle
compare.no.text.message=Et eller Begge Af de Vælgede PDFs Har Ingen Tekstindhold. Vælg Vores PDFs Med Tekst for Sammenligning.
#BookToPDF #BookToPDF
BookToPDF.title=Bøger og Tegneserier til PDF BookToPDF.title=Bøger og Tegneserier til PDF
@@ -805,6 +813,11 @@ sign.draw=Tegn Underskrift
sign.text=Tekstinput sign.text=Tekstinput
sign.clear=Ryd sign.clear=Ryd
sign.add=Tilføj sign.add=Tilføj
sign.saved=Gemte Signaturer
sign.save=Gem Signatur
sign.personalSigs=Personlige Signaturer
sign.sharedSigs=Delte Signaturer
sign.noSavedSigs=Ingen Gemte Signaturer Fundet
#repair #repair
@@ -823,7 +836,7 @@ flatten.submit=Udjævn
#ScannerImageSplit #ScannerImageSplit
ScannerImageSplit.selectText.1=Vinkeltærskel: ScannerImageSplit.selectText.1=Vinkeltærskel:
ScannerImageSplit.selectText.2=Indstiller den minimale absolutte vinkel, der kræves for at billedet roteres (standard: 10). ScannerImageSplit.selectText.2=Indstiller den minimale absolutte vinkel, der kræves for at billedet roteres (standard: 10).
ScannerImageSplit.selectText.3=Tolerance: ScannerImageSplit.selectText.3=Tolerancen:
ScannerImageSplit.selectText.4=Bestemmer området for farvevariation omkring den estimerede baggrundsfarve (standard: 30). ScannerImageSplit.selectText.4=Bestemmer området for farvevariation omkring den estimerede baggrundsfarve (standard: 30).
ScannerImageSplit.selectText.5=Minimum Areal: ScannerImageSplit.selectText.5=Minimum Areal:
ScannerImageSplit.selectText.6=Indstiller den minimale arealtærskel for et foto (standard: 10000). ScannerImageSplit.selectText.6=Indstiller den minimale arealtærskel for et foto (standard: 10000).
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(f.eks. 1,3,2 eller 4-8,2,10-12 eller 2n-1)
multiTool.title=PDF Multi Værktøj multiTool.title=PDF Multi Værktøj
multiTool.header=PDF Multi Værktøj multiTool.header=PDF Multi Værktøj
multiTool.uploadPrompts=Filnavn multiTool.uploadPrompts=Filnavn
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Se PDF viewPdf.title=Se PDF
@@ -1014,7 +1038,7 @@ watermark.header=Tilføj Vandmærke
watermark.selectText.1=Vælg PDF til at tilføje vandmærke: watermark.selectText.1=Vælg PDF til at tilføje vandmærke:
watermark.selectText.2=Vandmærketekst: watermark.selectText.2=Vandmærketekst:
watermark.selectText.3=Skriftstørrelse: watermark.selectText.3=Skriftstørrelse:
watermark.selectText.4=Rotation (0-360): watermark.selectText.4=Vendt Side (0-360):
watermark.selectText.5=breddeAfstand (Afstand mellem hvert vandmærke vandret): watermark.selectText.5=breddeAfstand (Afstand mellem hvert vandmærke vandret):
watermark.selectText.6=højdeAfstand (Afstand mellem hvert vandmærke lodret): watermark.selectText.6=højdeAfstand (Afstand mellem hvert vandmærke lodret):
watermark.selectText.7=Gennemsigtighed (0% - 100%): watermark.selectText.7=Gennemsigtighed (0% - 100%):
@@ -1182,8 +1206,8 @@ licenses.license=License
survey.nav=Undersøgelse survey.nav=Undersøgelse
survey.title=Stirling-PDF Undersøgelse survey.title=Stirling-PDF Undersøgelse
survey.description=Stirling-PDF har ingen sporing, så vi vil gerne høre fra vores brugere for at forbedre Stirling-PDF! survey.description=Stirling-PDF har ingen sporing, så vi vil gerne høre fra vores brugere for at forbedre Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF Har Endtes Sidst Ganger du Foresatte En Kig! For At Lære Mere, Se Vores Blog Indlæg Her:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Med Disse Endringer Er Vi Kommet I Betalende Forretningsstøtte og Finansiering
survey.please=Overvej venligst at deltage i vores undersøgelse! survey.please=Overvej venligst at deltage i vores undersøgelse!
survey.disabled=(Undersøgelsespop-up vil blive deaktiveret i følgende opdateringer, men vil være tilgængelig i bunden af siden) survey.disabled=(Undersøgelsespop-up vil blive deaktiveret i følgende opdateringer, men vil være tilgængelig i bunden af siden)
survey.button=Tag Undersøgelsen survey.button=Tag Undersøgelsen
@@ -1211,15 +1235,13 @@ removeImage.removeImage=Fjern billede
removeImage.submit=Fjern removeImage.submit=Fjern
splitByChapters.title=Split PDF by Chapters splitByChapters.title=Del PDF ved Kapitler
splitByChapters.header=Split PDF by Chapters splitByChapters.header=Splitter PDF efter kapitel
splitByChapters.bookmarkLevel=Bookmark Level splitByChapters.bookmarkLevel=Bogmærke niveau
splitByChapters.includeMetadata=Include Metadata splitByChapters.includeMetadata=Inkluder metadata
splitByChapters.allowDuplicates=Allow Duplicates splitByChapters.allowDuplicates=Tillad duplikater
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure. splitByChapters.desc.1=Denne værktøj splitter en PDF-fil op i flere PDF'er baseret på dens kapitelstruktur.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.). splitByChapters.desc.2=Bogmærke niveau: Vælg nivået af bogmærker, der skal bruges til at splittere (0 for hovedniveau, 1 for anden niveau osv.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Inkluder metadata: Hvis markeret, vil den originale PDF's metadata inkluderes i hver splitterdels PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Tillad duplikater: Hvis markeret, tillader det flere bogmærker på samme side til at oprette separate PDF'er.
splitByChapters.submit=Split PDF splitByChapters.submit=Splitter PDF

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Schriftgröße
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Schriftart
pdfPrompt=PDF(s) auswählen pdfPrompt=PDF(s) auswählen
multiPdfPrompt=PDFs auswählen(2+) multiPdfPrompt=PDFs auswählen(2+)
multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin) multiPdfDropPrompt=Wählen Sie alle gewünschten PDFs aus (oder ziehen Sie sie per Drag & Drop hierhin)
@@ -77,8 +77,11 @@ color=Farbe
sponsor=Sponsor sponsor=Sponsor
info=Informationen info=Informationen
pro=Pro pro=Pro
page=Page page=Seite
pages=Pages pages=Seiten
loading=Laden...
addToDoc=In Dokument hinzufügen
reset=Reset
legal.privacy=Datenschutz legal.privacy=Datenschutz
legal.terms=AGB legal.terms=AGB
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Validieren
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Auf Pro-Version umsteigen
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Diese Funktion ist nur für Pro-Nutzer verfügbar.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling-PDF Pro unterstützt YAML Konfigurationsdateien, SSO und weitere Funktionen.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Suchen Sie weitere Funktionen in der Benutzerverwaltung? Steigen Sie auf die Pro-Version um
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Möchten Sie Stirling-PDF verbessern?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling-PDF verfügt über Opt-in-Analytics, die uns helfen, das Produkt zu verbessern. Wir zeichnen keine persönlichen Informationen oder Dateiinhalte auf.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Bitte erwägen Sie die Analytics zu aktivieren, um Stirling-PDF beim Wachsen zu helfen und um unsere User besser zu verstehen.
analytics.enable=Enable analytics analytics.enable=Analytics aktivieren
analytics.disable=Disable analytics analytics.disable=Analytics deaktivieren
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Sie können die Einstellungen für die Analytics in der config/settings.yml Datei bearbeiten
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Sprachen
navbar.settings=Einstellungen navbar.settings=Einstellungen
navbar.allTools=Werkzeuge navbar.allTools=Werkzeuge
navbar.multiTool=Multitools navbar.multiTool=Multitools
navbar.search=Suche
navbar.sections.organize=Organisieren navbar.sections.organize=Organisieren
navbar.sections.convertTo=In PDF konvertieren navbar.sections.convertTo=In PDF konvertieren
navbar.sections.convertFrom=Konvertieren von PDF navbar.sections.convertFrom=Konvertieren von PDF
navbar.sections.security=Zeichen und Sicherheit navbar.sections.security=Zeichen und Sicherheit
navbar.sections.advance=Fortschrittlich navbar.sections.advance=Fortschrittlich
navbar.sections.edit=Anzeigen und Bearbeiten navbar.sections.edit=Anzeigen und Bearbeiten
navbar.sections.popular=Popular navbar.sections.popular=Beliebt
############# #############
# SETTINGS # # SETTINGS #
@@ -243,7 +247,8 @@ database.fileNotFound=Datei nicht gefunden
database.fileNullOrEmpty=Datei darf nicht null oder leer sein database.fileNullOrEmpty=Datei darf nicht null oder leer sein
database.failedImportFile=Dateiimport fehlgeschlagen database.failedImportFile=Dateiimport fehlgeschlagen
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -392,7 +397,7 @@ certSign.tags=authentifizieren,pem,p12,offiziell,verschlüsseln
home.removeCertSign.title=Zertifikatsignatur entfernen home.removeCertSign.title=Zertifikatsignatur entfernen
home.removeCertSign.desc=Zertifikatsignatur aus PDF entfernen home.removeCertSign.desc=Zertifikatsignatur aus PDF entfernen
removeCertSign.tags=authentifizieren,PEM,P12,offiziell,entschlüsseln,decrypt removeCertSign.tags=authentifizieren,PEM,P12,offiziell,entschlüsseln
home.pageLayout.title=Mehrseitiges Layout home.pageLayout.title=Mehrseitiges Layout
home.pageLayout.desc=Mehrere Seiten eines PDF zu einer Seite zusammenführen home.pageLayout.desc=Mehrere Seiten eines PDF zu einer Seite zusammenführen
@@ -503,28 +508,28 @@ home.removeImagePdf.desc=Bild aus PDF entfernen, um die Dateigröße zu verringe
removeImagePdf.tags=bild entfernen,seitenoperationen,back end,server side removeImagePdf.tags=bild entfernen,seitenoperationen,back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=PDF-Datei nach Kapiteln aufteilen
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Aufteilung einer PDF-Datei in mehrere Dateien auf Basis der Kapitelstruktur.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=aufteilen,kapitel,lesezeichen,organisieren
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Farbe Ersetzen-Invertieren
replace-color.header=Replace-Invert Color PDF replace-color.header=Farb-PDF Ersetzen-Invertieren
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Farbe ersetzen und invertieren
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Ersetzen Sie die Farbe des Texts und Hintergrund der PDF-Datei und invertieren Sie die komplette Farbe der PDF-Datei, um die Dateigröße zu reduzieren
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Farbe ersetzen,Seiteneinstellungen,Backend,Serverseite
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Ersetzen oder Invertieren von Farboptionen
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Standard(Standardfarben mit hohem Kontrast)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Benutzerdefiniert(Benutzerdefinierte Farben)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Vollinvertierung(Invertierung aller Farben)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Farboptionen mit hohem Kontrast
replace-color.selectText.6=white text on black background replace-color.selectText.6=Weißer Text auf schwarzem Hintergrund
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Schwarzer Text auf weißem Hintergrund
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Gelber Text auf schwarzem Hintergrund
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Grüner Text auf schwarzem Hintergrund
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Textfarbe auswählen
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Hintergrundfarbe auswählen
replace-color.submit=Replace replace-color.submit=Ersetzen
@@ -551,10 +556,9 @@ login.oauth2AccessDenied=Zugriff abgelehnt
login.oauth2InvalidTokenResponse=Ungültige Token-Antwort login.oauth2InvalidTokenResponse=Ungültige Token-Antwort
login.oauth2InvalidIdToken=Ungültiges ID-Token login.oauth2InvalidIdToken=Ungültiges ID-Token
login.userIsDisabled=Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benutzernamen derzeit gesperrt. Bitte wenden Sie sich an den Administrator. login.userIsDisabled=Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benutzernamen derzeit gesperrt. Bitte wenden Sie sich an den Administrator.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Sie sind bereits an
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=Geräten angemeldet. Bitte melden Sie sich dort ab und versuchen es dann erneut.
login.toManySessions=You have too many active sessions login.toManySessions=Sie haben zu viele aktive Sitzungen
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatisch zensieren/schwärzen autoRedact.title=Automatisch zensieren/schwärzen
@@ -704,7 +708,7 @@ autoSplitPDF.header=PDF automatisch teilen
autoSplitPDF.description=Drucken Sie, fügen Sie ein, scannen Sie, laden Sie hoch und lassen Sie uns Ihre Dokumente automatisch trennen. Kein manuelles Sortieren erforderlich. autoSplitPDF.description=Drucken Sie, fügen Sie ein, scannen Sie, laden Sie hoch und lassen Sie uns Ihre Dokumente automatisch trennen. Kein manuelles Sortieren erforderlich.
autoSplitPDF.selectText.1=Drucken Sie einige Trennblätter aus (schwarz/weiß ist ausreichend). autoSplitPDF.selectText.1=Drucken Sie einige Trennblätter aus (schwarz/weiß ist ausreichend).
autoSplitPDF.selectText.2=Scannen Sie alle Dokumente auf einmal, indem Sie das Trennblatt zwischen die Dokumente einlegen. autoSplitPDF.selectText.2=Scannen Sie alle Dokumente auf einmal, indem Sie das Trennblatt zwischen die Dokumente einlegen.
autoSplitPDF.selectText.3=Laden Sie die einzelne große gescannte PDF-Datei hoch und überlassen Sie Stirling PDF den Rest. autoSplitPDF.selectText.3=Laden Sie die einzelne große gescannte PDF-Datei hoch und überlassen Sie Stirling-PDF den Rest.
autoSplitPDF.selectText.4=Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist. autoSplitPDF.selectText.4=Trennseiten werden automatisch erkannt und entfernt, so dass ein sauberes Enddokument garantiert ist.
autoSplitPDF.formPrompt=PDF mit Stirling-PDF Seitentrennern hochladen: autoSplitPDF.formPrompt=PDF mit Stirling-PDF Seitentrennern hochladen:
autoSplitPDF.duplexMode=Duplex-Modus (Scannen von Vorder- und Rückseite) autoSplitPDF.duplexMode=Duplex-Modus (Scannen von Vorder- und Rückseite)
@@ -729,7 +733,7 @@ pageLayout.submit=Abschicken
scalePages.title=Seitengröße anpassen scalePages.title=Seitengröße anpassen
scalePages.header=Seitengröße anpassen scalePages.header=Seitengröße anpassen
scalePages.pageSize=Format der Seiten des Dokuments scalePages.pageSize=Format der Seiten des Dokuments
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Originalgröße beibehalten
scalePages.scaleFactor=Zoomstufe (Ausschnitt) einer Seite scalePages.scaleFactor=Zoomstufe (Ausschnitt) einer Seite
scalePages.submit=Abschicken scalePages.submit=Abschicken
@@ -749,6 +753,7 @@ certSign.showSig=Signatur anzeigen
certSign.reason=Grund certSign.reason=Grund
certSign.location=Standort certSign.location=Standort
certSign.name=Name certSign.name=Name
certSign.showLogo=Logo anzeigen
certSign.submit=PDF signieren certSign.submit=PDF signieren
@@ -783,6 +788,9 @@ compare.highlightColor.2=Highlight-Farbe 2:
compare.document.1=Dokument 1 compare.document.1=Dokument 1
compare.document.2=Dokument 2 compare.document.2=Dokument 2
compare.submit=Vergleichen compare.submit=Vergleichen
compare.complex.message=Eines oder beide Dokumente sind sehr groß, dadurch kann die Genauigkeit des Vergleichs kann beeinträchtigt werden.
compare.large.file.message=Eines oder beide Dokumente sind zu groß, um verarbeitet zu werden
compare.no.text.message=Ein oder beide ausgewählten PDFs enthalten keine Textinhalt. Wählen Sie bitte PDFs mit Text für die Vergleichsanalyse.
#BookToPDF #BookToPDF
BookToPDF.title=Bücher und Comics zu PDF BookToPDF.title=Bücher und Comics zu PDF
@@ -805,6 +813,11 @@ sign.draw=Signatur zeichnen
sign.text=Texteingabe sign.text=Texteingabe
sign.clear=Leeren sign.clear=Leeren
sign.add=Signieren sign.add=Signieren
sign.saved=Gespeicherte Signaturen
sign.save=Signature speichern
sign.personalSigs=Persönliche Signaturen
sign.sharedSigs=Geteilte Signaturen
sign.noSavedSigs=Es wurden keine gespeicherten Signaturen gefunden
#repair #repair
@@ -858,7 +871,7 @@ ocr.submit=PDF mit OCR verarbeiten
extractImages.title=Bilder extrahieren extractImages.title=Bilder extrahieren
extractImages.header=Bilder extrahieren extractImages.header=Bilder extrahieren
extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen extractImages.selectText=Wählen Sie das Bildformat aus, in das extrahierte Bilder konvertiert werden sollen
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Doppelte Bilder speichern
extractImages.submit=Extrahieren extractImages.submit=Extrahieren
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(z.B. 1,3,2 oder 4-8,2,10-12 oder 2n-1)
multiTool.title=PDF-Multitool multiTool.title=PDF-Multitool
multiTool.header=PDF-Multitool multiTool.header=PDF-Multitool
multiTool.uploadPrompts=Dateiname multiTool.uploadPrompts=Dateiname
multiTool.selectAll=Alle auswählen
multiTool.deselectAll=Auswahl aufheben
multiTool.selectPages=Seiten auswählen
multiTool.selectedPages=Ausgewählte Seiten
multiTool.page=Seite
multiTool.deleteSelected=Auswahl löschen
multiTool.downloadAll=Downloaden
multiTool.downloadSelected=Auswahl downloaden
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=PDF anzeigen viewPdf.title=PDF anzeigen
@@ -1182,8 +1206,8 @@ licenses.license=Lizenz
survey.nav=Umfrage survey.nav=Umfrage
survey.title=Stirling-PDF-Umfrage survey.title=Stirling-PDF-Umfrage
survey.description=Stirling-PDF hat kein Tracking, daher möchten wir von unseren Benutzern hören, wie wir Stirling-PDF verbessern können! survey.description=Stirling-PDF hat kein Tracking, daher möchten wir von unseren Benutzern hören, wie wir Stirling-PDF verbessern können!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF hat sich seit der letzten Umfrage verändert! Mehr Informationen finden Sie bitte in unserem Blog-Beitrag hier:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Mit diesen Änderungen erhalten wir beauftragte Geschäftsunterstützung und Finanzierung
survey.please=Bitte nehmen Sie an unserer Umfrage teil! survey.please=Bitte nehmen Sie an unserer Umfrage teil!
survey.disabled=(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.) survey.disabled=(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.)
survey.button=Umfrage durchführen survey.button=Umfrage durchführen
@@ -1211,15 +1235,13 @@ removeImage.removeImage=Bild entfernen
removeImage.submit=Bild entfernen removeImage.submit=Bild entfernen
splitByChapters.title=Split PDF by Chapters splitByChapters.title=PDF nach Kapiteln aufteilen
splitByChapters.header=Split PDF by Chapters splitByChapters.header=PDF nach Kapiteln aufteilen
splitByChapters.bookmarkLevel=Bookmark Level splitByChapters.bookmarkLevel=Lesezeichenebene
splitByChapters.includeMetadata=Include Metadata splitByChapters.includeMetadata=Metadaten einschließen
splitByChapters.allowDuplicates=Allow Duplicates splitByChapters.allowDuplicates=Duplikate erlauben
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure. splitByChapters.desc.1=Dieses Werkzeug teilt eine PDF-Datei auf der Grundlage ihrer Kapitelstruktur in mehrere PDF-Dateien auf.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.). splitByChapters.desc.2=Lesezeichenebene: Wählen Sie die Ebene der Lesezeichen, die für die Aufteilung verwendet werden soll (0 für die erste Ebene, 1 für die zweite Ebene usw.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Metadaten einschließen: Wenn diese Option aktiviert ist, werden die Metadaten der ursprünglichen PDF-Datei in jede aufgeteilte PDF-Datei übernommen.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Duplikate erlauben: Wenn diese Option aktiviert ist, können mehrere Lesezeichen auf derselben Seite separate PDF Dateien erstellen.
splitByChapters.submit=Split PDF splitByChapters.submit=PDF teilen

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Μέγεθος Τύπου
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Όνομα Τύπου
pdfPrompt=Επιλογή PDF(s) pdfPrompt=Επιλογή PDF(s)
multiPdfPrompt=Επιλογή PDFs (2+) multiPdfPrompt=Επιλογή PDFs (2+)
multiPdfDropPrompt=Επιλογή (ή τράβηγμα αρχείου και απόθεση) όλων των PDF που χρειάζεστε multiPdfDropPrompt=Επιλογή (ή τράβηγμα αρχείου και απόθεση) όλων των PDF που χρειάζεστε
@@ -39,7 +39,7 @@ delete=Διαγραφή
username=Όνομα Χρήστη username=Όνομα Χρήστη
password=Κωδικός password=Κωδικός
welcome=Καλως Ήλθατε welcome=Καλως Ήλθατε
property=Property property=Χαρακτηριστικό
black=Μαύρο black=Μαύρο
white=Άσπρο white=Άσπρο
red=Κόκκινο red=Κόκκινο
@@ -56,15 +56,15 @@ userNotFoundMessage=Ο χρήστης δεν βρέθηκε.
incorrectPasswordMessage=Ο τρέχων κωδικός πρόσβασης είναι λανθασμένος. incorrectPasswordMessage=Ο τρέχων κωδικός πρόσβασης είναι λανθασμένος.
usernameExistsMessage=Το νέο όνομα χρήστη υπάρχει ήδη. usernameExistsMessage=Το νέο όνομα χρήστη υπάρχει ήδη.
invalidUsernameMessage=Μη έγκυρο όνομα χρήστη, όνομα χρήστη μπορεί να περιέχει μόνο γράμματα, αριθμούς και τους ακόλουθους ειδικούς χαρακτήρες @._+- ή πρέπει να είναι έγκυρη διεύθυνση email. invalidUsernameMessage=Μη έγκυρο όνομα χρήστη, όνομα χρήστη μπορεί να περιέχει μόνο γράμματα, αριθμούς και τους ακόλουθους ειδικούς χαρακτήρες @._+- ή πρέπει να είναι έγκυρη διεύθυνση email.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=Ο κωδικός πρόσβασης δεν μπορεί να είναι αδύναμος και δεν μπορεί να έχει χαμογελάτα στην αρχή ή το τέλος.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Ο Διαβεβαιωμένος Νέος Κωδικός Πρόσβασης πρέπει να συνάρτησε με το Νέο Κωδίκο Πρόσβασης.
deleteCurrentUserMessage=Δεν είναι δυνατή η διαγραφή του τρέχοντος συνδεδεμένου χρήστη. deleteCurrentUserMessage=Δεν είναι δυνατή η διαγραφή του τρέχοντος συνδεδεμένου χρήστη.
deleteUsernameExistsMessage=Το όνομα χρήστη δεν υπάρχει και δεν μπορεί να διαγραφεί. deleteUsernameExistsMessage=Το όνομα χρήστη δεν υπάρχει και δεν μπορεί να διαγραφεί.
downgradeCurrentUserMessage=Δεν είναι δυνατή η υποβάθμιση του ρόλου του τρέχοντος χρήστη downgradeCurrentUserMessage=Δεν είναι δυνατή η υποβάθμιση του ρόλου του τρέχοντος χρήστη
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=Ο σύγχρονος χρήστης δεν μπορεί να απενειλθείται
downgradeCurrentUserLongMessage=Δεν είναι δυνατή η υποβάθμιση του ρόλου του τρέχοντος χρήστη. Ως εκ τούτου, ο τρέχων χρήστης δεν θα εμφανίζεται. downgradeCurrentUserLongMessage=Δεν είναι δυνατή η υποβάθμιση του ρόλου του τρέχοντος χρήστη. Ως εκ τούτου, ο τρέχων χρήστης δεν θα εμφανίζεται.
userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user. userAlreadyExistsOAuthMessage=Το υχής ήδη υπάρχει ως OAuth2 χρήστης.
userAlreadyExistsWebMessage=The user already exists as an web user. userAlreadyExistsWebMessage=Ο χρήστης εξαρτάται ήδη ως πλήρωμα χρήστη.
error=Σφάλμα error=Σφάλμα
oops=Ωχ! oops=Ωχ!
help=Βοήθεια help=Βοήθεια
@@ -75,28 +75,31 @@ visitGithub=Επισκεφθείτε το Αποθετήριο του Github
donate=Δωρισε donate=Δωρισε
color=Χρώμα color=Χρώμα
sponsor=οστηρικτής sponsor=οστηρικτής
info=Info info=Πληροφορίες
pro=Pro pro=Προ
page=Page page=Σελίδα
pages=Pages pages=Σελίδες
loading=Φόρτωση...
addToDoc=Πρόσθεση στο Εκπομπώματο
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Πολιτική Προνομίους
legal.terms=Terms and Conditions legal.terms=Φράσεις Υποχρεωτικότητας
legal.accessibility=Accessibility legal.accessibility=Πρόσβαση
legal.cookie=Cookie Policy legal.cookie=Πολιτική Χώρου Συνθέσεων
legal.impressum=Impressum legal.impressum=Κατάσταση
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Μενού Pipeline (Beta) pipeline.header=Μενού Pipeline (Beta)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Αναβάθμιση Καλυτερού
pipeline.configureButton=Διαμόρφωσε pipeline.configureButton=Διαμόρφωσε
pipeline.defaultOption=Custom pipeline.defaultOption=Κατασκευή Μετρόπολης
pipeline.submitButton=Υποβολή pipeline.submitButton=Υποβολή
pipeline.help=Βοήθεια για το Pipeline pipeline.help=Βοήθεια για το Pipeline
pipeline.scanHelp=Βοήθεια για Σάρωση Φακέλων pipeline.scanHelp=Βοήθεια για Σάρωση Φακέλων
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Είστε σίγουροι ότι θέλετε να διαγράψετε το πρότυπο;
###################### ######################
# Pipeline Options # # Pipeline Options #
@@ -107,52 +110,53 @@ pipelineOptions.saveSettings=Αποθήκευση Ρυθμίσεων Λειτο
pipelineOptions.pipelineNamePrompt=Εισαγάγετε το όνομα του pipeline εδώ pipelineOptions.pipelineNamePrompt=Εισαγάγετε το όνομα του pipeline εδώ
pipelineOptions.selectOperation=Επιλέξτε Λειτουργία pipelineOptions.selectOperation=Επιλέξτε Λειτουργία
pipelineOptions.addOperationButton=Προσθήκη λειτουργίας pipelineOptions.addOperationButton=Προσθήκη λειτουργίας
pipelineOptions.pipelineHeader=Pipeline: pipelineOptions.pipelineHeader=Πρότυπο:
pipelineOptions.saveButton=Λήψη pipelineOptions.saveButton=Λήψη
pipelineOptions.validateButton=Επικυρώνω pipelineOptions.validateButton=Επικυρώνω
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Ενημερώστε σε Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Αυτή η λειτουργία είναι διαθέσιμη μόνο για τους χρήστες Pro.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro υποστηρίζει αρχεία συνασκήματος YAML και άλλες λειτουργίες SSO.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Σάξεις για περισσότερες λειτουργίες διαχείρισης χρηστών; Πроверьте Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Επιθυμείτε να βελτιώσετε το Stirling PDF;
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF έχει επιλεγμένα ανάλυμα για να με βοηθήσει στην βελτίωση του προϊόντος. Δεν ακολουθούμε καμία ιδιοχειρισμένη πληροφορία ή συγκέντρωση υπόλοιπου πλάνου.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Παρακαλώ ενεργοποιήστε τα ανάλυμα για να βοηθήσετε το Stirling-PDF να ξεφύγει και να μας βοηθήσετε στον καλύτερο δυνατό ανάλυμα χρηστών.
analytics.enable=Enable analytics analytics.enable=Ενεργοποίηση ανάλυμα
analytics.disable=Disable analytics analytics.disable=Διακόπτωση ανάλυμα
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Μπορείτε να αλλάξετε τις προπαραστάσεις των ανάλυμα σε υποθέσεις/settings.yml
############# #############
# NAVBAR # # NAVBAR #
############# #############
navbar.favorite=Favorites navbar.favorite=Πιρημός
navbar.darkmode=Μαύρο Θέμα navbar.darkmode=Μαύρο Θέμα
navbar.language=Languages navbar.language=Γλώσσες
navbar.settings=Ρυθμίσεις navbar.settings=Ρυθμίσεις
navbar.allTools=Tools navbar.allTools=Εργαλεία
navbar.multiTool=Multi Tools navbar.multiTool=Multi Tools
navbar.sections.organize=Organize navbar.search=Search
navbar.sections.convertTo=Convert to PDF navbar.sections.organize=Οργάνωση
navbar.sections.convertFrom=Convert from PDF navbar.sections.convertTo=Μετατροπή σε PDF
navbar.sections.security=Sign & Security navbar.sections.convertFrom=Μετατροπή από PDF
navbar.sections.advance=Advanced navbar.sections.security=Υπογραφή & Σέκυνση
navbar.sections.edit=View & Edit navbar.sections.advance=Διεξοδικό
navbar.sections.popular=Popular navbar.sections.edit=Σύντομος Προβολής & Διοίκηση
navbar.sections.popular=Επιφανειακά
############# #############
# SETTINGS # # SETTINGS #
############# #############
settings.title=Ρυθμίσεις settings.title=Ρυθμίσεις
settings.update=Υπάρχει διαθέσιμη ενημέρωση settings.update=Υπάρχει διαθέσιμη ενημέρωση
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available. settings.updateAvailable={0} είναι το πρόγραμμα εκτελεσιμωμένο σήμερα. Έχετε διαθέσιμη μια νέα έκδοση (σήμερα: {1}).
settings.appVersion=Έκδοση εφαρμογής: settings.appVersion=Έκδοση εφαρμογής:
settings.downloadOption.title=Επιλέξετε την επιλογή λήψης (Για λήψεις μεμονωμένων αρχείων χωρίς zip): settings.downloadOption.title=Επιλέξετε την επιλογή λήψης (Για λήψεις μεμονωμένων αρχείων χωρίς zip):
settings.downloadOption.1=Άνοιγμα στο ίδιο παράθυρο settings.downloadOption.1=Άνοιγμα στο ίδιο παράθυρο
@@ -161,9 +165,9 @@ settings.downloadOption.3=Λήψη αρχείου
settings.zipThreshold=Αρχεία Zip όταν ο αριθμός των ληφθέντων αρχείων είναι πολύ μεγάλος settings.zipThreshold=Αρχεία Zip όταν ο αριθμός των ληφθέντων αρχείων είναι πολύ μεγάλος
settings.signOut=Αποσύνδεση settings.signOut=Αποσύνδεση
settings.accountSettings=Ρυθμίσεις Λογαριασμού settings.accountSettings=Ρυθμίσεις Λογαριασμού
settings.bored.help=Enables easter egg game settings.bored.help=Ενεργοποίηση παιχνίδι ευφήμων
settings.cacheInputs.name=Save form inputs settings.cacheInputs.name=Αποθήκευση των εισαγωγών
settings.cacheInputs.help=Enable to store previously used inputs for future runs settings.cacheInputs.help=Ενεργοποίηση για να αποθηκεύσετε προηγουμένως χρησιμοποιημένες εισαγωγές για το μέλλον
changeCreds.title=Αλλαγή Διαπιστευτηρίων changeCreds.title=Αλλαγή Διαπιστευτηρίων
changeCreds.header=Ενημέρωση των λεπτομερειών του Λογαριασμού σας changeCreds.header=Ενημέρωση των λεπτομερειών του Λογαριασμού σας
@@ -191,7 +195,7 @@ account.signOut=Αποσύνδεση
account.yourApiKey=Το κλειδί σας για τη διεπαφή προγραμματισμού εφαρμογών (API key) account.yourApiKey=Το κλειδί σας για τη διεπαφή προγραμματισμού εφαρμογών (API key)
account.syncTitle=Συγχρονισμός των ρυθμίσεων του φυλλομετρητή (Web Browser) με τον λογαριασμό account.syncTitle=Συγχρονισμός των ρυθμίσεων του φυλλομετρητή (Web Browser) με τον λογαριασμό
account.settingsCompare=Σύγκριση Ρυθμίσεων: account.settingsCompare=Σύγκριση Ρυθμίσεων:
account.property=Property account.property=Υπεροχή
account.webBrowserSettings=Ρύθμιση φυλλομετρητή (Web Browser) account.webBrowserSettings=Ρύθμιση φυλλομετρητή (Web Browser)
account.syncToBrowser=Συγχρονισμός Λογαριασμού -> Φυλλομετρητή (Web Browser) account.syncToBrowser=Συγχρονισμός Λογαριασμού -> Φυλλομετρητή (Web Browser)
account.syncToAccount=Συγχρονισμός Λογαριασμού <- Φυλλομετρητή (Web Browser) account.syncToAccount=Συγχρονισμός Λογαριασμού <- Φυλλομετρητή (Web Browser)
@@ -202,10 +206,10 @@ adminUserSettings.header=Ρυθμίσεις ελέγχου Διαχειριστ
adminUserSettings.admin=Διαχειριστής adminUserSettings.admin=Διαχειριστής
adminUserSettings.user=Χρήστης adminUserSettings.user=Χρήστης
adminUserSettings.addUser=Προσθήκη νέου Χρήστη adminUserSettings.addUser=Προσθήκη νέου Χρήστη
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Διαγραφή Χρηστών
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=Είναι αποδεκτό να διαγράψετε τον χρήστη;
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Είναι αποδεκτό να αλλάξετε το σύμβαθρο του χρηστών;
adminUserSettings.usernameInfo=Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address. adminUserSettings.usernameInfo=Το όνομα χρήστη μπορεί να περιέχει μόνο γράμματα, αριθμούς και τα εξής διευρυμένα συμβολικά @._+- ή πρέπει να είναι έγκυρο e-mail.
adminUserSettings.roles=Ρόλοι adminUserSettings.roles=Ρόλοι
adminUserSettings.role=Ρόλος adminUserSettings.role=Ρόλος
adminUserSettings.actions=Ενέργειες adminUserSettings.actions=Ενέργειες
@@ -217,33 +221,34 @@ adminUserSettings.internalApiUser=Εσωτερικός API χρήστης
adminUserSettings.forceChange=Αναγκάστε τον χρήστη να αλλάξει το όνομα χρήστη/κωδικό πρόσβασης κατά τη σύνδεση adminUserSettings.forceChange=Αναγκάστε τον χρήστη να αλλάξει το όνομα χρήστη/κωδικό πρόσβασης κατά τη σύνδεση
adminUserSettings.submit=Αποθήκευση Χρήστη adminUserSettings.submit=Αποθήκευση Χρήστη
adminUserSettings.changeUserRole=Αλλαγή ρόλου χρήστη adminUserSettings.changeUserRole=Αλλαγή ρόλου χρήστη
adminUserSettings.authenticated=Authenticated adminUserSettings.authenticated=Εγγεγραφές
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Επεξεργασία Τοποθεσίας Δικότητας
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=Ενεργούς Χρήστης
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=Απενεργούς Χρήστης
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Ενεργοί Χρήστες:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Απενεργοί Χρήστες:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Συνολικός Αριθμός Χρηστών:
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Τελευταία Ερώτηση
database.title=Database Import/Export database.title=Εισάγωντας/Εξαγωγή Δεδομένων Βάσης Δεδομένων
database.header=Database Import/Export database.header=Εισάγωντας/Εξαγωγή Δεδομένων Βάσης Δεδομένων
database.fileName=File Name database.fileName=Όνομα αρχείου
database.creationDate=Creation Date database.creationDate=Ημερομηνία δημιουργίας
database.fileSize=File Size database.fileSize=Μέγεθος αρχείου
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Διαγραφή Προγράμματος Ανασυγκρότησης
database.importBackupFile=Import Backup File database.importBackupFile=Εισάγωντας Προγράμματος Ανασυγκρότησης
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Κατέβασμα Προγράμματος Ανασυγκρότησης
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=Όταν εισάγετε δεδομένα, είναι σημαντικό να εξασφαλίσετε τη σωστή μορφοποίηση. Αν δεν είστε σίγουροι για το ποια πράγματα κάνετε, αιτήστε υποβολή και υποστήριξη από ευελίκτω. Μια σφάλμα στη μορφοποίηση μπορεί να προκαλέσει καταστάσεις λάθους στην εφαρμογή, αν όχι ολόκληρη την αποχώρηση της εφαρμογής.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=Το ονόμα του αρχείου δεν έχει σημασία όταν ξεκινάτε μια επέμβαση. Αλλαγήται αργότερα για να ακολουθήσει το σχήμα backup_ωςώντας_YYYYMMDDHHmm.sql, επιτρέποντας μια συνεχές κατάληψη ονόματος.
database.submit=Import Backup database.submit=Εισάγωντας Προγράμματος Ανασυγκρότησης
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Τελείωση εισαγωγής στη βάση δεδομένων.
database.fileNotFound=File not Found database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Το αρχείο δεν μπορεί να είναι τυχόν ή κενό.
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Η σεζώνη σας υπάρξει παραγωγή. Πατήστε για να ανανεώσετε το πλήρωμα και δοκιμάστε ξανά.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -254,7 +259,7 @@ home.searchBar=Αναζήτηση για χαρακτηριστικά...
home.viewPdf.title=Εμφάνιση PDF home.viewPdf.title=Εμφάνιση PDF
home.viewPdf.desc=Εμφάνιση, προσθήκη σχεδίου, προσθήκη κειμένου ή εικόνων home.viewPdf.desc=Εμφάνιση, προσθήκη σχεδίου, προσθήκη κειμένου ή εικόνων
viewPdf.tags=view,read,annotate,text,image viewPdf.tags=ψηφιοποίηση,ανάγνωση,καταχώρηση,τεκτωνική,εικόνα
home.multiTool.title=PDF Πολυεργαλείο home.multiTool.title=PDF Πολυεργαλείο
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη και Κατάργηση σελίδων home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη και Κατάργηση σελίδων
@@ -262,11 +267,11 @@ multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,in
home.merge.title=Συγχώνευση home.merge.title=Συγχώνευση
home.merge.desc=Συγχώνευση πολλών PDF σε ένα με εύκολο τρόπο. home.merge.desc=Συγχώνευση πολλών PDF σε ένα με εύκολο τρόπο.
merge.tags=merge,Page operations,Back end,server side merge.tags=συνδυασμός,λεπτομέρειες σελίδας,μετάβαση από το μέχρι το κράτος,κρήτερο χρώμα
home.split.title=Διαχωρισμός home.split.title=Διαχωρισμός
home.split.desc=Διαχωρισμός των PDF σε πολλά έγγραφα. home.split.desc=Διαχωρισμός των PDF σε πολλά έγγραφα.
split.tags=Page operations,divide,Multi Page,cut,server side split.tags=λεπτομέρειες σελίδας,διαχωρισμός,πολυσελίδια,κοπή,κρήτερο χρώμα
home.rotate.title=Περιστροφή home.rotate.title=Περιστροφή
home.rotate.desc=Περιστροφή των PDF σας με εύκολο τρόπο. home.rotate.desc=Περιστροφή των PDF σας με εύκολο τρόπο.
@@ -275,45 +280,45 @@ rotate.tags=από την πλευρά του server
home.imageToPdf.title=Εικόνα σε PDF home.imageToPdf.title=Εικόνα σε PDF
home.imageToPdf.desc=Μετατροπή εικόνας (PNG, JPEG, GIF) σε PDF. home.imageToPdf.desc=Μετατροπή εικόνας (PNG, JPEG, GIF) σε PDF.
imageToPdf.tags=conversion,img,jpg,picture,photo imageToPdf.tags=διαδοχική ψηφιοποίηση,εικόνα,jpg,πληροφορίας,φωτογραφία
home.pdfToImage.title=PDF σε εικόνα home.pdfToImage.title=PDF σε εικόνα
home.pdfToImage.desc=Μετατροπή ενός PDF σε μία εικόνα. (PNG, JPEG, GIF) home.pdfToImage.desc=Μετατροπή ενός PDF σε μία εικόνα. (PNG, JPEG, GIF)
pdfToImage.tags=conversion,img,jpg,picture,photo pdfToImage.tags=διαδοχική ψηφιοποίηση,εικόνα,jpg,πληροφορίας,φωτογραφία
home.pdfOrganiser.title=Οργάνωση home.pdfOrganiser.title=Οργάνωση
home.pdfOrganiser.desc=Αφαίρεση/Αναδιάταξη σελίδων με οποιαδήποτε σειρά home.pdfOrganiser.desc=Αφαίρεση/Αναδιάταξη σελίδων με οποιαδήποτε σειρά
pdfOrganiser.tags=duplex,even,odd,sort,move pdfOrganiser.tags=διπλώματος,ήρωαι,ίσοδες,κατάταξη,μέταβαση
home.addImage.title=Προσθήκη Εικόνας home.addImage.title=Προσθήκη Εικόνας
home.addImage.desc=Προσθήκη μιας εικόνας σε μια καθορισμένη θέση στο PDF home.addImage.desc=Προσθήκη μιας εικόνας σε μια καθορισμένη θέση στο PDF
addImage.tags=img,jpg,picture,photo addImage.tags=εικόνα,γούστιο,φωτογραφία
home.watermark.title=Προσθήκη Υδατογραφήματος home.watermark.title=Προσθήκη Υδατογραφήματος
home.watermark.desc=Προσθήκη ενός προσαρμοσμένου υδατογράφηματος στο έγγραφό PDF. home.watermark.desc=Προσθήκη ενός προσαρμοσμένου υδατογράφηματος στο έγγραφό PDF.
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo watermark.tags=λέξη-πίνακας,τυπώμενο,ετικέτα,δικαιοχειρισμός,διόρθωση,εικόνα,γούστιο,φωτογραφία
home.permissions.title=Αλλαγή Δικαιωμάτων home.permissions.title=Αλλαγή Δικαιωμάτων
home.permissions.desc=Αλλαγή των Δικαιωμάτων στο έγγραφο PDF home.permissions.desc=Αλλαγή των Δικαιωμάτων στο έγγραφο PDF
permissions.tags=read,write,edit,print permissions.tags=αποκοπή,γραμμακτής,μετάβαση
home.removePages.title=Αφαίρεση home.removePages.title=Αφαίρεση
home.removePages.desc=Αφαίρεση μή επιθυμητών σελίδων απο το έγγραφο PDF. home.removePages.desc=Αφαίρεση μή επιθυμητών σελίδων απο το έγγραφο PDF.
removePages.tags=Remove pages,delete pages removePages.tags=απόθεση σελίδων,διαγραφή σελίδων
home.addPassword.title=Προσθήκη κωδικού home.addPassword.title=Προσθήκη κωδικού
home.addPassword.desc=Κρυπτογράφηση - κλείδωμα του PDF αρχείου με έναν κωδικό. home.addPassword.desc=Κρυπτογράφηση - κλείδωμα του PDF αρχείου με έναν κωδικό.
addPassword.tags=secure,security addPassword.tags=σφραγίστω,σφραγίζομαι
home.removePassword.title=Αφαίρεση Κωδικού home.removePassword.title=Αφαίρεση Κωδικού
home.removePassword.desc=Κατάργήση της προστασίας με κωδικό πρόσβασης από το έγγραφο PDF. home.removePassword.desc=Κατάργήση της προστασίας με κωδικό πρόσβασης από το έγγραφο PDF.
removePassword.tags=secure,Decrypt,security,unpassword,delete password removePassword.tags=σφραγίστω,παρακυμπνώ,σφραγική,διαγραφή σφραγίδας
home.compressPdfs.title=Συμπίεση home.compressPdfs.title=Συμπίεση
home.compressPdfs.desc=Συμπίεση των αρχείων PDF για την μείωση του μεγέθους τους. home.compressPdfs.desc=Συμπίεση των αρχείων PDF για την μείωση του μεγέθους τους.
compressPdfs.tags=squish,small,tiny compressPdfs.tags=ελαφρύνση,κοντά,τροχιές
home.changeMetadata.title=Αλλαγή Μεταδεδομένων home.changeMetadata.title=Αλλαγή Μεταδεδομένων
@@ -326,16 +331,16 @@ fileToPDF.tags=transformation,format,document,picture,slide,text,conversion,offi
home.ocr.title=οπτική αναγνώριση χαρακτήρων (OCR) / Σαρώσεις Cleanup home.ocr.title=οπτική αναγνώριση χαρακτήρων (OCR) / Σαρώσεις Cleanup
home.ocr.desc=Το Cleanup σαρώνει και ανιχνεύει κείμενο από εικόνες μέσα σε ένα PDF και το προσθέτει ξανά ως κείμενο home.ocr.desc=Το Cleanup σαρώνει και ανιχνεύει κείμενο από εικόνες μέσα σε ένα PDF και το προσθέτει ξανά ως κείμενο
ocr.tags=recognition,text,image,scan,read,identify,detection,editable ocr.tags=γνώση,λέξεις,εικόνα,ζήτημα,ανίδηση,δοχή,πρόγραμμα γνωστικής ανάγνωσης
home.extractImages.title=Εξαγωγή εικόνων home.extractImages.title=Εξαγωγή εικόνων
home.extractImages.desc=Εξαγωγή όλων των εικόνων απο ένα PDF και αποθήκευση αυτών σε zip home.extractImages.desc=Εξαγωγή όλων των εικόνων απο ένα PDF και αποθήκευση αυτών σε zip
extractImages.tags=picture,photo,save,archive,zip,capture,grab extractImages.tags=εικόνα,φωτογραφία,θυλώματος,αρχείο,γραφή,παράδειγμα
home.pdfToPDFA.title=PDF σε PDF/A home.pdfToPDFA.title=PDF σε PDF/A
home.pdfToPDFA.desc=Μετατροπή PDF σε PDF/A για μακροχρόνια αποθήκευση home.pdfToPDFA.desc=Μετατροπή PDF σε PDF/A για μακροχρόνια αποθήκευση
pdfToPDFA.tags=archive,long-term,standard,conversion,storage,preservation pdfToPDFA.tags=θυλώματος,σύνολο,κανόνες,παραστατικό,κράτηση
home.PDFToWord.title=PDF σε Word home.PDFToWord.title=PDF σε Word
home.PDFToWord.desc=Μετατροπή του PDF σε Word αρχείο (DOC, DOCX and ODT) home.PDFToWord.desc=Μετατροπή του PDF σε Word αρχείο (DOC, DOCX and ODT)
@@ -351,24 +356,24 @@ PDFToText.tags=richformat,richtextformat,rich text format
home.PDFToHTML.title=PDF σε HTML home.PDFToHTML.title=PDF σε HTML
home.PDFToHTML.desc=Μετατροπή του PDF σε μορφή HTML home.PDFToHTML.desc=Μετατροπή του PDF σε μορφή HTML
PDFToHTML.tags=web content,browser friendly PDFToHTML.tags=πρόσβαση σε πλαίσιο,περιεχόμενα για διαδικτυακά
home.PDFToXML.title=PDF σε XML home.PDFToXML.title=PDF σε XML
home.PDFToXML.desc=Μετατροπή του PDF σε μορφή XML home.PDFToXML.desc=Μετατροπή του PDF σε μορφή XML
PDFToXML.tags=data-extraction,structured-content,interop,transformation,convert PDFToXML.tags=ξυστώση-δεδομένων,σύνθεση στρογγυλών εξισώσεων,κοντινή κατάληψη,πρόσβαση
home.ScannerImageSplit.title=Ανίχνευση/Διαίρεση σαρωμένων φωτογραφιών home.ScannerImageSplit.title=Ανίχνευση/Διαίρεση σαρωμένων φωτογραφιών
home.ScannerImageSplit.desc=Διαχωρίσμός πολλών φωτογραφίών μέσα από μια φωτογραφία/PDF home.ScannerImageSplit.desc=Διαχωρίσμός πολλών φωτογραφίών μέσα από μια φωτογραφία/PDF
ScannerImageSplit.tags=separate,auto-detect,scans,multi-photo,organize ScannerImageSplit.tags=διχοτομία,δικτυακή-δοκιμασία,σκάνερις,θέση πλατύων,διαχώριση
home.sign.title=Υπογραφή home.sign.title=Υπογραφή
home.sign.desc=Προσθήκη υπογραφής στο PDF με σχέδιο, κείμενο ή εικόνα. home.sign.desc=Προσθήκη υπογραφής στο PDF με σχέδιο, κείμενο ή εικόνα.
sign.tags=authorize,initials,drawn-signature,text-sign,image-signature sign.tags=αποθωμάσια,κατογώρηση,φωνή,χαρακτεία-υπογραφής
home.flatten.title=Flatten home.flatten.title=Συνοπτικοποίηση
home.flatten.desc=Κατάργηση όλων των διαδραστικών στοιχείων και φορμών από ένα PDF home.flatten.desc=Κατάργηση όλων των διαδραστικών στοιχείων και φορμών από ένα PDF
flatten.tags=static,deactivate,non-interactive,streamline flatten.tags=εγχώριο,απενεργοποιήση,αδρανής-ενεργό,προσαρμογές
home.repair.title=Επιδιόρθωση home.repair.title=Επιδιόρθωση
home.repair.desc=Προσπάθεια επιδιόρθωσης ενός κατεστραμμένου PDF home.repair.desc=Προσπάθεια επιδιόρθωσης ενός κατεστραμμένου PDF
@@ -376,87 +381,87 @@ repair.tags=fix,restore,correction,recover
home.removeBlanks.title=Αφαίρεση κενών Σελίδων home.removeBlanks.title=Αφαίρεση κενών Σελίδων
home.removeBlanks.desc=Ανίχευση και αφαίρεση κενών σελίδων από ένα έγγραφο home.removeBlanks.desc=Ανίχευση και αφαίρεση κενών σελίδων από ένα έγγραφο
removeBlanks.tags=cleanup,streamline,non-content,organize removeBlanks.tags=καθαρισμός,προσαρμογές,εξωφύλακτες-δεδομένων,διοργάνωση
home.removeAnnotations.title=Remove Annotations home.removeAnnotations.title=Αποθήκευση Παρατηρήσεων
home.removeAnnotations.desc=Removes all comments/annotations from a PDF home.removeAnnotations.desc=Ελέγξτε και προστίθετε σχόλια/παρατηρήσεις από το PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove removeAnnotations.tags=σχόλια,κουμπί-ντεκτ,χαρτές,κάθετα-δεδομένα,αποβολή
home.compare.title=Σύγκριση home.compare.title=Σύγκριση
home.compare.desc=Σύγκριση και εμφάνιση των διαφορών μεταξύ δύο PDF αρχείων home.compare.desc=Σύγκριση και εμφάνιση των διαφορών μεταξύ δύο PDF αρχείων
compare.tags=differentiate,contrast,changes,analysis compare.tags=διακρίσεις,σύγκριση,αλλαγές,πληθυσμική-ανάλυση
home.certSign.title=Υπογραφή με Πιστοποιητικό home.certSign.title=Υπογραφή με Πιστοποιητικό
home.certSign.desc=Υπογραφή ενός PDF αρχείου με ένα Πιστοποιητικό/Κλειδί (PEM/P12) home.certSign.desc=Υπογραφή ενός PDF αρχείου με ένα Πιστοποιητικό/Κλειδί (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt certSign.tags=υπογραφή,PEM,P12,δημοσίες,δεκτικότητα,κρυπτογράφηση
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Αποθήκευση Υπογραφής Τέλους
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=Εμβέλειες σημάδισης από το PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=υπογραφή,PEM,P12,δημοσίες,κρυπτογράφηση-κλείσιμο
home.pageLayout.title=Διάταξη πολλών σελίδων home.pageLayout.title=Διάταξη πολλών σελίδων
home.pageLayout.desc=Συγχώνευση πολλαπλών σελίδων ενός εγγράφου PDF σε μία μόνο σελίδα home.pageLayout.desc=Συγχώνευση πολλαπλών σελίδων ενός εγγράφου PDF σε μία μόνο σελίδα
pageLayout.tags=merge,composite,single-view,organize pageLayout.tags=σύνθεση,ενωμένη,απλή-ροεπίσκαιρα,διοργάνωση
home.scalePages.title=Προσαρμογή του μεγέθους/κλίμακας σελίδας home.scalePages.title=Προσαρμογή του μεγέθους/κλίμακας σελίδας
home.scalePages.desc=Αλλαγή του μεγέθους/κλίμακας μίας σελίδας και/η του περιεχομένου της. home.scalePages.desc=Αλλαγή του μεγέθους/κλίμακας μίας σελίδας και/η του περιεχομένου της.
scalePages.tags=resize,modify,dimension,adapt scalePages.tags=μεταβάλλοντας τους διάστασες,ενδιαφέροντες πόροι,παρακμή,μετατύχηση
home.pipeline.title=Pipeline (Για προχωρημένους) home.pipeline.title=Pipeline (Για προχωρημένους)
home.pipeline.desc=Εκτέλεση πολλαπλών ενεργειών σε αρχεία PDF ορίζοντας pipeline scripts home.pipeline.desc=Εκτέλεση πολλαπλών ενεργειών σε αρχεία PDF ορίζοντας pipeline scripts
pipeline.tags=automate,sequence,scripted,batch-process pipeline.tags=αυτόματος κλωστήρας,σειρά,γραμμογραφική,αποδτομή-πακέτων
home.add-page-numbers.title=Προσθήκη αριθμών σε Σελίδες home.add-page-numbers.title=Προσθήκη αριθμών σε Σελίδες
home.add-page-numbers.desc=Προσθήκη αριθμών σελίδων σε ένα έγγραφο σε μια καθορισμένη θέση home.add-page-numbers.desc=Προσθήκη αριθμών σελίδων σε ένα έγγραφο σε μια καθορισμένη θέση
add-page-numbers.tags=paginate,label,organize,index add-page-numbers.tags=αυτόματη αρίθμηση σελίδων,κατάταξη,διοργάνωση,παραγγελία
home.auto-rename.title=Αυτόματη μετονομασία αρχείου PDF home.auto-rename.title=Αυτόματη μετονομασία αρχείου PDF
home.auto-rename.desc=Αυτόματη μετονομασία ενός αρχείου PDF με βάση την κεφαλίδα που έχει εντοπιστεί home.auto-rename.desc=Αυτόματη μετονομασία ενός αρχείου PDF με βάση την κεφαλίδα που έχει εντοπιστεί
auto-rename.tags=auto-detect,header-based,organize,relabel auto-rename.tags=αυτόματη αναδεικτική κατατάξη μέσω κεφαλαιών,διοργάνωση,καθαρισμός
home.adjust-contrast.title=Προσαρμογή χρωμάτων/Αντίθεση home.adjust-contrast.title=Προσαρμογή χρωμάτων/Αντίθεση
home.adjust-contrast.desc=Προσαρμογή της αντίθεσης, του κορεσμού και της φωτεινότητας ενός PDF home.adjust-contrast.desc=Προσαρμογή της αντίθεσης, του κορεσμού και της φωτεινότητας ενός PDF
adjust-contrast.tags=color-correction,tune,modify,enhance adjust-contrast.tags=καταπολέμηση του συγκρούσεων,ενδιαφέροντας ελέγχο,μεταβάλλοντας για είδη,εξέλιξη
home.crop.title=Περικοπή PDF home.crop.title=Περικοπή PDF
home.crop.desc=Περικοπή ενός PDF για να μειωθεί το μέγεθός του (διατηρεί το κείμενο!) home.crop.desc=Περικοπή ενός PDF για να μειωθεί το μέγεθός του (διατηρεί το κείμενο!)
crop.tags=trim,shrink,edit,shape crop.tags=καταγραφή-καύσης,περικόπτωση,επεξεργασία,forma
home.autoSplitPDF.title=Αυτόματος διαχωρισμός σελίδων home.autoSplitPDF.title=Αυτόματος διαχωρισμός σελίδων
home.autoSplitPDF.desc=Αυτόματος διαχωρισμός σαρωμένου PDF με φυσικό σαρωμένο διαχωριστή σελίδων QR Code home.autoSplitPDF.desc=Αυτόματος διαχωρισμός σαρωμένου PDF με φυσικό σαρωμένο διαχωριστή σελίδων QR Code
autoSplitPDF.tags=QR-based,separate,scan-segment,organize autoSplitPDF.tags=βάσει QR-code,διχοτομία,ελέγχο-διχοτομία,κλάδωση
home.sanitizePdf.title=Απολύμανση home.sanitizePdf.title=Απολύμανση
home.sanitizePdf.desc=Αφαίρεση σεναρίων και άλλων στοιχείων από αρχεία PDF home.sanitizePdf.desc=Αφαίρεση σεναρίων και άλλων στοιχείων από αρχεία PDF
sanitizePdf.tags=clean,secure,safe,remove-threats sanitizePdf.tags=καθαρισμός,διατηρητική,ασφάλεια,προσχώρηση-δυνατότητες
home.URLToPDF.title=URL/Ιστότοπος σε PDF home.URLToPDF.title=URL/Ιστότοπος σε PDF
home.URLToPDF.desc=Μετατροπή οποιαδήποτε διεύθυνσης URL http(s) σε PDF home.URLToPDF.desc=Μετατροπή οποιαδήποτε διεύθυνσης URL http(s) σε PDF
URLToPDF.tags=web-capture,save-page,web-to-doc,archive URLToPDF.tags=καταγραφή-Διαδικτύου,θηράω-σεγκένεια,Διαδικτυακό-σε-δοκίμιο,αποθήκευση
home.HTMLToPDF.title=HTML σε PDF home.HTMLToPDF.title=HTML σε PDF
home.HTMLToPDF.desc=Μετατροπή οποιουδήποτε αρχείου HTML ή zip σε PDF home.HTMLToPDF.desc=Μετατροπή οποιουδήποτε αρχείου HTML ή zip σε PDF
HTMLToPDF.tags=markup,web-content,transformation,convert HTMLToPDF.tags=μάρκαρι,χρηστήρια-Διαδικτύου,παρασταση,καλύτερο
home.MarkdownToPDF.title=Markdown σε PDF home.MarkdownToPDF.title=Markdown σε PDF
home.MarkdownToPDF.desc=Μετατροπή οποιουδήποτε αρχείου Markdown σε PDF home.MarkdownToPDF.desc=Μετατροπή οποιουδήποτε αρχείου Markdown σε PDF
MarkdownToPDF.tags=markup,web-content,transformation,convert MarkdownToPDF.tags=μάρκαρι,χρηστήρια-Διαδικτύου,παρασταση,καλύτερο
home.getPdfInfo.title=Λήψη όλων των πληροφοριών από το PDF home.getPdfInfo.title=Λήψη όλων των πληροφοριών από το PDF
home.getPdfInfo.desc=Λήψη όλων των πιθανών πληροφοριών από τα αρχεία PDF home.getPdfInfo.desc=Λήψη όλων των πιθανών πληροφοριών από τα αρχεία PDF
getPdfInfo.tags=infomation,data,stats,statistics getPdfInfo.tags=πληροφορίες,δεδομένα,στατιστικά,πληθυσμός
home.extractPage.title=Εξαγωγή σελίδων home.extractPage.title=Εξαγωγή σελίδων
home.extractPage.desc=Εξαγωγή των επιλεγμένων σελίδων από ένα PDF home.extractPage.desc=Εξαγωγή των επιλεγμένων σελίδων από ένα PDF
extractPage.tags=extract extractPage.tags=αποδιατύπωση
home.PdfToSinglePage.title=PDF σε μία μεγάλη σελίδα home.PdfToSinglePage.title=PDF σε μία μεγάλη σελίδα
home.PdfToSinglePage.desc=Συγχώνευση όλων των σελίδων PDF σε μια μεγάλη σελίδα home.PdfToSinglePage.desc=Συγχώνευση όλων των σελίδων PDF σε μια μεγάλη σελίδα
PdfToSinglePage.tags=single page PdfToSinglePage.tags=για-μία-σελίδα
home.showJS.title=Εμφάνιση Javascript home.showJS.title=Εμφάνιση Javascript
@@ -465,29 +470,29 @@ showJS.tags=JS
home.autoRedact.title=Αυτόματο Μαύρισμα Κειμένου home.autoRedact.title=Αυτόματο Μαύρισμα Κειμένου
home.autoRedact.desc=Αυτόματη επεξεργασία (Μαύρισμα) κείμενου σε PDF με βάση το κείμενο εισαγωγής home.autoRedact.desc=Αυτόματη επεξεργασία (Μαύρισμα) κείμενου σε PDF με βάση το κείμενο εισαγωγής
autoRedact.tags=Redact,Hide,black out,black,marker,hidden autoRedact.tags=ξεκράζω,φυλακίζω,εικόνο-κουπές,κρατήστε ασφαλείς,δημιουργήστε
home.tableExtraxt.title=PDF σε CSV home.tableExtraxt.title=PDF σε CSV
home.tableExtraxt.desc=Εξάγει πίνακες από PDF μετατρέποντάς το σε CSV home.tableExtraxt.desc=Εξάγει πίνακες από PDF μετατρέποντάς το σε CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert tableExtraxt.tags=CSV,καταθέσεις-τάβλες,αποδιατύπωση,μετατροπή
home.autoSizeSplitPDF.title=Αυτόματη διαίρεση κατά μέγεθος/πλήθος home.autoSizeSplitPDF.title=Αυτόματη διαίρεση κατά μέγεθος/πλήθος
home.autoSizeSplitPDF.desc=Διαχωρίστε ένα μόνο PDF σε πολλά έγγραφα με βάση το μέγεθος, τον αριθμό σελίδων ή τον αριθμό εγγράφων home.autoSizeSplitPDF.desc=Διαχωρίστε ένα μόνο PDF σε πολλά έγγραφα με βάση το μέγεθος, τον αριθμό σελίδων ή τον αριθμό εγγράφων
autoSizeSplitPDF.tags=pdf,split,document,organization autoSizeSplitPDF.tags=pdf,διαχωρισμός,γραμμακτής,διορθώσεις-κάντε
home.overlay-pdfs.title=Επικάλυψη PDFs home.overlay-pdfs.title=Επικάλυψη PDFs
home.overlay-pdfs.desc=Επικαλύπτει αρχεία PDF πάνω σε άλλο PDF home.overlay-pdfs.desc=Επικαλύπτει αρχεία PDF πάνω σε άλλο PDF
overlay-pdfs.tags=Overlay overlay-pdfs.tags=πλέξη-πDFs
home.split-by-sections.title=Διαχωρισμός PDF ανά ενότητες home.split-by-sections.title=Διαχωρισμός PDF ανά ενότητες
home.split-by-sections.desc=Διαχωρίστε κάθε σελίδα ενός PDF σε μικρότερες οριζόντιες και κάθετες ενότητες home.split-by-sections.desc=Διαχωρίστε κάθε σελίδα ενός PDF σε μικρότερες οριζόντιες και κάθετες ενότητες
split-by-sections.tags=Section Split, Divide, Customize split-by-sections.tags=διχοτομία-διεργασίες,διεργασίες,κρατήστε
home.AddStampRequest.title=Προσθήκη σφραγίδας σε PDF home.AddStampRequest.title=Προσθήκη σφραγίδας σε PDF
home.AddStampRequest.desc=Προσθέστε κείμενο ή προσθέστε σφραγίδες εικόνας σε καθορισμένες τοποθεσίες home.AddStampRequest.desc=Προσθέστε κείμενο ή προσθέστε σφραγίδες εικόνας σε καθορισμένες τοποθεσίες
AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize AddStampRequest.tags=κάντε-πίνακα,πρόσθεση-εικόνας,κέντρο-εικόνας,χαμυλόχατο,PDF,βάζω-δείγμα,κρατήστε
home.PDFToBook.title=PDF σε Book home.PDFToBook.title=PDF σε Book
@@ -498,33 +503,33 @@ home.BookToPDF.title=Book σε PDF
home.BookToPDF.desc=Μετατρέπει τις μορφές Books/Comics σε PDF χρησιμοποιώντας calibre home.BookToPDF.desc=Μετατρέπει τις μορφές Books/Comics σε PDF χρησιμοποιώντας calibre
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Αφαίρεση εικόνας
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Αφαίρεση εικόνας από το PDF για να μειώσετε το μέγεθος του αρχείου
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Αφαίρεση-Εικόνας,Πράξεις-Σελίδας,ύπαρξη-τμήματος,πλην-δυναμική
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Διχοτομία PDF ανά Περιγραφές
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=διχοτομία,περιγραφές,κεφάλαια,συνορία
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Αντικατάσταση-Αντίστροφη Παθωμένη Πίντσουρ
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Αντικατάσταση χρώματος για το πεδίο κειμένου και απόχρωμη έκθεση PDF για μείωση μεγέθους αρχείου
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Αντικατάσταση χρώματος, Διαδικασίες σελίδας, Μέσω πληροφόρησης, Από την εσωτερική
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Επιλογές αντικατάστασης-Αντίστροφης χρώματος
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Προεπιλογή (Χαράκτηρες υψηλής αντιδιαβάσιμότητας)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Εξαιρετικό (Προσωπικές επιλογές χρώματος)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Αντίστροφη Παθωμένη (Αντίστροφη αντικατάσταση όλων των πχώματος)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Επιλογές υψηλής αντιδιαβάσιμότητας
replace-color.selectText.6=white text on black background replace-color.selectText.6=Χρίστος το πεδίο κειμένου σε μαύρη οπτική
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Μαύρο το πεδίο κειμένου σε χλωρό οπτική
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Ευτυχισμένο το πεδίο κειμένου σε μαύρη οπτική
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Χλωροφαίνοντος το πεδίο κειμένου σε μαύρη οπτική
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Επιλογή χρώματος του κειμένου
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Επιλογή απόχρωμης οπτικής
replace-color.submit=Replace replace-color.submit=Αντικατάσταση
@@ -543,18 +548,17 @@ login.locked=Ο λογαριασμός σας έχει κλειδωθεί.
login.signinTitle=Παρακαλώ, συνδεθείτε login.signinTitle=Παρακαλώ, συνδεθείτε
login.ssoSignIn=Σύνδεση μέσω μοναδικής σύνδεσης login.ssoSignIn=Σύνδεση μέσω μοναδικής σύνδεσης
login.oauth2AutoCreateDisabled=Απενεργοποιήθηκε ο χρήστης αυτόματης δημιουργίας OAUTH2 login.oauth2AutoCreateDisabled=Απενεργοποιήθηκε ο χρήστης αυτόματης δημιουργίας OAUTH2
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=Η εγγραφή και το πληκτρολόγημα ανθρώπων με όχι εγγραμμένες λογισμικές αρχίζουν να είναι ορισμένες τοποθετήσεις. Παρακαλώ στείλτε μια ισχυρά παραίτηση στον διοικητή.
login.oauth2RequestNotFound=Authorization request not found login.oauth2RequestNotFound=Απαιτήσεις πληροφόρησης χρήστη ανακαλύψτηκαν μη έχουν βρεθεί
login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2InvalidUserInfoResponse=Απάντηση μεμονωμένων πληροφοριών χρήστη αποδείξτηκε άγνωστη
login.oauth2invalidRequest=Invalid Request login.oauth2invalidRequest=Αρχαίως απαιτήσεις πληροφοριών χρήστη
login.oauth2AccessDenied=Access Denied login.oauth2AccessDenied=Πρόσβαση ορισμένες τοποθετήσεις
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Απάντηση άρκετο ρόταμα
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Λιδός όρκου μη αρκετός
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=Ο χρήστης είναι δευτεροβαθμιακά διακωμένος, το σύστημα άλλαξε τον καθώς βρεθεί. Παρακαλείστε τους αρχηγούς να επιβεβαιώσουν τη συμπεριφορά χρήστη.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Είστε ήδη σύνδεδες σε
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=κατοχόι. Παρακαλώ δυσκέντρωση τους και προσπαθήστε ξανά.
login.toManySessions=You have too many active sessions login.toManySessions=Έχετε πολλές εγγραφές σε βίτιο μέση
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Αυτόματο Μαύρισμα Κειμένου autoRedact.title=Αυτόματο Μαύρισμα Κειμένου
@@ -564,7 +568,7 @@ autoRedact.textsToRedactLabel=Κείμενο για μαύρισμα (διαχω
autoRedact.textsToRedactPlaceholder=π.χ. \nΕμπιστευτικό \nΑκρώς απόρρητο autoRedact.textsToRedactPlaceholder=π.χ. \nΕμπιστευτικό \nΑκρώς απόρρητο
autoRedact.useRegexLabel=Χρήση Regex autoRedact.useRegexLabel=Χρήση Regex
autoRedact.wholeWordSearchLabel=Αναζήτηση ολόκληρης της λέξης autoRedact.wholeWordSearchLabel=Αναζήτηση ολόκληρης της λέξης
autoRedact.customPaddingLabel=Custom Extra Padding autoRedact.customPaddingLabel=Εμπνευσμένη Προσθήκη Ανάκρισης
autoRedact.convertPDFToImageLabel=Μετατροπή PDF σε PDF-Εικόνα (Χρησιμοποιείται για την αφαίρεση κειμένου πίσω από το πλαίσιο) autoRedact.convertPDFToImageLabel=Μετατροπή PDF σε PDF-Εικόνα (Χρησιμοποιείται για την αφαίρεση κειμένου πίσω από το πλαίσιο)
autoRedact.submitButton=Υποβολή autoRedact.submitButton=Υποβολή
@@ -630,7 +634,7 @@ HTMLToPDF.defaultHeader=Ενεργοποίηση προεπιλεγμένης κ
HTMLToPDF.cssMediaType=Αλλάξτε τον τύπο μέσων (media type )CSS της σελίδας. HTMLToPDF.cssMediaType=Αλλάξτε τον τύπο μέσων (media type )CSS της σελίδας.
HTMLToPDF.none=Κανένα HTMLToPDF.none=Κανένα
HTMLToPDF.print=Εκτύπωσε HTMLToPDF.print=Εκτύπωσε
HTMLToPDF.screen=Screen HTMLToPDF.screen=Ορόσκοπος
#AddStampRequest #AddStampRequest
@@ -729,7 +733,7 @@ pageLayout.submit=Υποβολή
scalePages.title=Προσαρμογή κλίμακας σελίδας scalePages.title=Προσαρμογή κλίμακας σελίδας
scalePages.header=Προσαρμογή κλίμακας σελίδας scalePages.header=Προσαρμογή κλίμακας σελίδας
scalePages.pageSize=Μέγεθος μιας σελίδας του εγγράφου. scalePages.pageSize=Μέγεθος μιας σελίδας του εγγράφου.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Τροποποίηση με ευθύγειες γραμμές
scalePages.scaleFactor=Επίπεδο ζουμ (περικοπή) σελίδας. scalePages.scaleFactor=Επίπεδο ζουμ (περικοπή) σελίδας.
scalePages.submit=Υποβολή scalePages.submit=Υποβολή
@@ -749,14 +753,15 @@ certSign.showSig=Εμφάνιση Υπογραφής
certSign.reason=Αιτία certSign.reason=Αιτία
certSign.location=Τοποθεσία certSign.location=Τοποθεσία
certSign.name=Όνομα certSign.name=Όνομα
certSign.showLogo=Προειδοποίηση Παρόχου
certSign.submit=Υπογραφή PDF certSign.submit=Υπογραφή PDF
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Αφαίρεση Αντικειμένων Τυπογραφίας Τομβής
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=Αφαίρεση της πληροφόρησης όρκου από το PDF
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=Επιλέξτε ένα αρχείο PDF:
removeCertSign.submit=Remove Signature removeCertSign.submit=Αφαιρέστε την ψήφιση
#removeBlanks #removeBlanks
@@ -778,11 +783,14 @@ removeAnnotations.submit=Κατάργηση
#compare #compare
compare.title=Σύγκριση compare.title=Σύγκριση
compare.header=Σύγκριση PDFs compare.header=Σύγκριση PDFs
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Μάσκα Εμφανισμού 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Μάσκα Εμφανισμού 2:
compare.document.1=Έγγραφο 1 compare.document.1=Έγγραφο 1
compare.document.2=Έγγραφο 2 compare.document.2=Έγγραφο 2
compare.submit=Σύγκριση compare.submit=Σύγκριση
compare.complex.message=Ένα ή τα δίπλα αποδεκτής χαρτογράφημα είναι μεγάλο, η πραγματικότητα αναζήτησης μπορεί να εξαβλύσει τη συγκρίση
compare.large.file.message=Ένα ή τα δίπλα αποδεκτής χαρτογράφημα είναι πολύ μεγάλο για να εξυπηρετήσει
compare.no.text.message=ένα ή τα δίπλα αποδεκτής χαρτογράφημα δεν περιέχουν κείμενο. Παρακαλώ επιλέξτε PDF με κείμενο για σύγκριση.
#BookToPDF #BookToPDF
BookToPDF.title=Books και Comics σε PDF BookToPDF.title=Books και Comics σε PDF
@@ -805,6 +813,11 @@ sign.draw=Σχεδίαση υπογραφής
sign.text=Εισαγωγή κειμένου sign.text=Εισαγωγή κειμένου
sign.clear=Καθάρισμα sign.clear=Καθάρισμα
sign.add=Προσθήκη sign.add=Προσθήκη
sign.saved=Αποθηκευμένες Αλιάσιδες
sign.save=Αποθήκευση Αλιάσης
sign.personalSigs=Προσωπικές Αλιάσεις
sign.sharedSigs=Μεταδότες Αλιάσεις
sign.noSavedSigs=Δεν βρέθηκαν αποθηκευμένες αλιάσεις
#repair #repair
@@ -814,10 +827,10 @@ repair.submit=Επιδιόρθωση
#flatten #flatten
flatten.title=Flatten flatten.title=Φιλοξένηση
flatten.header=Flatten PDFs flatten.header=Flatten PDFs
flatten.flattenOnlyForms=Flatten only forms flatten.flattenOnlyForms=Φιλοξενήστε μόνο τα φόρμαδα
flatten.submit=Flatten flatten.submit=Φιλοξένηση
#ScannerImageSplit #ScannerImageSplit
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=Ελάχιστη επιφάνεια περιγρ
ScannerImageSplit.selectText.8=Ρυθμίζει το ελάχιστο όριο περιγράμματος για μια φωτογραφία ScannerImageSplit.selectText.8=Ρυθμίζει το ελάχιστο όριο περιγράμματος για μια φωτογραφία
ScannerImageSplit.selectText.9=Μέγεθος περιγράμματος: ScannerImageSplit.selectText.9=Μέγεθος περιγράμματος:
ScannerImageSplit.selectText.10=Ορίζει το μέγεθος του περιγράμματος που προστίθεται και αφαιρείται για να αποτρέπονται λευκά περιγράμματα στην έξοδο (προεπιλογή: 1). ScannerImageSplit.selectText.10=Ορίζει το μέγεθος του περιγράμματος που προστίθεται και αφαιρείται για να αποτρέπονται λευκά περιγράμματα στην έξοδο (προεπιλογή: 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Δεν είναι ιστάμενος Python. Είναι απαιτήτων για τη λειτουργία.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=Επεξεργασία PDF με OCR
extractImages.title=Εξαγωγή Εικόνων extractImages.title=Εξαγωγή Εικόνων
extractImages.header=Εξαγωγή Εικόνων extractImages.header=Εξαγωγή Εικόνων
extractImages.selectText=Επιλέξτε μορφή εικόνας για να μετατρέψετε τις εξαγόμενες εικόνες extractImages.selectText=Επιλέξτε μορφή εικόνας για να μετατρέψετε τις εξαγόμενες εικόνες
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Αποθήκευση εικόνων που μπορούν να είναι ίδιες
extractImages.submit=Εξαγωγή extractImages.submit=Εξαγωγή
@@ -866,7 +879,7 @@ extractImages.submit=Εξαγωγή
fileToPDF.title=Αρχείο σε PDF fileToPDF.title=Αρχείο σε PDF
fileToPDF.header=Μετατροπή οποιουδήποτε αρχείου σε PDF fileToPDF.header=Μετατροπή οποιουδήποτε αρχείου σε PDF
fileToPDF.credit=Αυτή η υπηρεσία χρησιμοποιεί LibreOffice και Unoconv για την μετατροπή των αρχείων. fileToPDF.credit=Αυτή η υπηρεσία χρησιμοποιεί LibreOffice και Unoconv για την μετατροπή των αρχείων.
fileToPDF.supportedFileTypesInfo=Supported File types fileToPDF.supportedFileTypesInfo=Υποστηριζόμενα αρχεία
fileToPDF.supportedFileTypes=Οι υποστηριζόμενοι τύποι αρχείων θα πρέπει να περιλαμβάνουν τα παρακάτω, ωστόσο, για μια πλήρη ενημερωμένη λίστα με τις υποστηριζόμενες μορφές, ανατρέξτε στην τεκμηρίωση του LibreOffice fileToPDF.supportedFileTypes=Οι υποστηριζόμενοι τύποι αρχείων θα πρέπει να περιλαμβάνουν τα παρακάτω, ωστόσο, για μια πλήρη ενημερωμένη λίστα με τις υποστηριζόμενες μορφές, ανατρέξτε στην τεκμηρίωση του LibreOffice
fileToPDF.submit=Μετατροπή σε PDF fileToPDF.submit=Μετατροπή σε PDF
@@ -896,7 +909,7 @@ merge.title=Συγχώνευση
merge.header=Συγχώνευση πολλαπλών PDFs (2+) merge.header=Συγχώνευση πολλαπλών PDFs (2+)
merge.sortByName=Ταξινόμηση με βάση το Όνομα merge.sortByName=Ταξινόμηση με βάση το Όνομα
merge.sortByDate=Ταξινόμηση με βάση την Ημερομηνία merge.sortByDate=Ταξινόμηση με βάση την Ημερομηνία
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Επιλογή για τη μέριξη δικαιωμάτων σημείους σημάδους; Αφαίρεση ηλεκτρονικών πρόσβασης από το συγχέωνται αρχείο?
merge.submit=Συγχώνευση merge.submit=Συγχώνευση
@@ -904,24 +917,35 @@ merge.submit=Συγχώνευση
pdfOrganiser.title=Διοργανωτής σελίδας pdfOrganiser.title=Διοργανωτής σελίδας
pdfOrganiser.header=Διοργανωτής σελίδας PDF pdfOrganiser.header=Διοργανωτής σελίδας PDF
pdfOrganiser.submit=Αναδιάταξη σελίδων pdfOrganiser.submit=Αναδιάταξη σελίδων
pdfOrganiser.mode=Mode pdfOrganiser.mode=Τύπος
pdfOrganiser.mode.1=Προσαρμοσμένη Σειρά Σελίδας pdfOrganiser.mode.1=Προσαρμοσμένη Σειρά Σελίδας
pdfOrganiser.mode.2=Αντίστροφη Σειρά pdfOrganiser.mode.2=Αντίστροφη Σειρά
pdfOrganiser.mode.3=Ταξινόμηση Διπλής Όψης (Duplex Sort) pdfOrganiser.mode.3=Ταξινόμηση Διπλής Όψης (Duplex Sort)
pdfOrganiser.mode.4=Ταξινόμηση Φυλλαδίου (Booklet Sort) pdfOrganiser.mode.4=Ταξινόμηση Φυλλαδίου (Booklet Sort)
pdfOrganiser.mode.5=Side Stitch Booklet Sort pdfOrganiser.mode.5=Πλάσμα Σεπτιμερή Λεφτοδυοκόσμου
pdfOrganiser.mode.6=Διαίρεση Μονού-Ζυγού pdfOrganiser.mode.6=Διαίρεση Μονού-Ζυγού
pdfOrganiser.mode.7=Αφαίρεση Πρώτου pdfOrganiser.mode.7=Αφαίρεση Πρώτου
pdfOrganiser.mode.8=Αφαίρεση Τελευταίου pdfOrganiser.mode.8=Αφαίρεση Τελευταίου
pdfOrganiser.mode.9=Αφαίρεση Πρώτου και Τελευταίου pdfOrganiser.mode.9=Αφαίρεση Πρώτου και Τελευταίου
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Περίπτωση Τυχαίου Μέριξης
pdfOrganiser.placeholder=(π.χ. 1,3,2 ή 4-8,2,10-12 ή 2n-1) pdfOrganiser.placeholder=(π.χ. 1,3,2 ή 4-8,2,10-12 ή 2n-1)
#multiTool #multiTool
multiTool.title=PDF Πολυεργαλείο multiTool.title=PDF Πολυεργαλείο
multiTool.header=PDF Πολυεργαλείο multiTool.header=PDF Πολυεργαλείο
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=Όνομα αρχείου
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Προβολή PDF viewPdf.title=Προβολή PDF
@@ -983,7 +1007,7 @@ pdfToImage.color=Χρώμα
pdfToImage.grey=Κλίμακα του γκρι pdfToImage.grey=Κλίμακα του γκρι
pdfToImage.blackwhite=Ασπρόμαυρο (Μπορεί να χαθούν δεδομένα!) pdfToImage.blackwhite=Ασπρόμαυρο (Μπορεί να χαθούν δεδομένα!)
pdfToImage.submit=Μετατροπή pdfToImage.submit=Μετατροπή
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Δεν είναι ιστάμενος Python. Είναι απαιτήτων για τη μετατροπή σε WebP.
#addPassword #addPassword
@@ -1020,7 +1044,7 @@ watermark.selectText.6=heightSpacer (Κενό μεταξύ κάθε υδατογ
watermark.selectText.7=Αδιαφάνεια (Opacity) (0% - 100%): watermark.selectText.7=Αδιαφάνεια (Opacity) (0% - 100%):
watermark.selectText.8=Τύπος Υδατογραφήματος: watermark.selectText.8=Τύπος Υδατογραφήματος:
watermark.selectText.9=Εικόνα Υδατογραφήματος: watermark.selectText.9=Εικόνα Υδατογραφήματος:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=Μετατροπή PDF σε PDF-Image
watermark.submit=Προσθήκη Υδατογραφήματος watermark.submit=Προσθήκη Υδατογραφήματος
watermark.type.1=Κείμενο watermark.type.1=Κείμενο
watermark.type.2=Εικόνα watermark.type.2=Εικόνα
@@ -1064,7 +1088,7 @@ changeMetadata.keywords=Λέξεις-κλειδιά:
changeMetadata.modDate=Ημερομηνία Τροποποίησης (yyyy/MM/dd HH:mm:ss): changeMetadata.modDate=Ημερομηνία Τροποποίησης (yyyy/MM/dd HH:mm:ss):
changeMetadata.producer=Παραγωγός: changeMetadata.producer=Παραγωγός:
changeMetadata.subject=Θέμα: changeMetadata.subject=Θέμα:
changeMetadata.trapped=Trapped: changeMetadata.trapped=Τυχόν Περίκλειση:
changeMetadata.selectText.4=Άλλα μεταδεδομένα: changeMetadata.selectText.4=Άλλα μεταδεδομένα:
changeMetadata.selectText.5=Προσθήκη εγγραφής προσαρμοσμένων μεταδεδομένων changeMetadata.selectText.5=Προσθήκη εγγραφής προσαρμοσμένων μεταδεδομένων
changeMetadata.submit=Αλλαγή changeMetadata.submit=Αλλαγή
@@ -1076,8 +1100,8 @@ pdfToPDFA.header=PDF σε PDF/A
pdfToPDFA.credit=Αυτή η υπηρεσία χρησιμοποιεί ghostscript για PDF/A μετατροπή pdfToPDFA.credit=Αυτή η υπηρεσία χρησιμοποιεί ghostscript για PDF/A μετατροπή
pdfToPDFA.submit=Μετατροπή pdfToPDFA.submit=Μετατροπή
pdfToPDFA.tip=Προς το παρόν δεν λειτουργεί για πολλαπλές εισόδους ταυτόχρονα pdfToPDFA.tip=Προς το παρόν δεν λειτουργεί για πολλαπλές εισόδους ταυτόχρονα
pdfToPDFA.outputFormat=Output format pdfToPDFA.outputFormat=Εξόδος αναμορφώσεων
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=Το PDF περιέχει ηλεκτρονική ψηφιακή υπογραφή. Αυτό θα αφαιρεθεί στο επόμενο βήμα.
#PDFToWord #PDFToWord
@@ -1146,8 +1170,8 @@ overlay-pdfs.mode.fixedRepeat=Διορθώθηκε η Επικάλυψη Επα
overlay-pdfs.counts.label=Μετρήσεις επικάλυψης (για σταθερή λειτουργία επανάληψης) overlay-pdfs.counts.label=Μετρήσεις επικάλυψης (για σταθερή λειτουργία επανάληψης)
overlay-pdfs.counts.placeholder=Εισαγάγετε μετρήσεις διαχωρισμένες με κόμματα (π.χ. 2,3,1) overlay-pdfs.counts.placeholder=Εισαγάγετε μετρήσεις διαχωρισμένες με κόμματα (π.χ. 2,3,1)
overlay-pdfs.position.label=Επιλέξτε Θέση Επικάλυψης overlay-pdfs.position.label=Επιλέξτε Θέση Επικάλυψης
overlay-pdfs.position.foreground=Foreground overlay-pdfs.position.foreground=Προσκήνιο
overlay-pdfs.position.background=Background overlay-pdfs.position.background=фондо
overlay-pdfs.submit=Υποβολή overlay-pdfs.submit=Υποβολή
@@ -1163,31 +1187,31 @@ split-by-sections.merge=Συγχώνευση σε ένα PDF
#printFile #printFile
printFile.title=Print File printFile.title=Εκτύπωση Αρχείου
printFile.header=Print File to Printer printFile.header=Εκτύπωση Αρχείου σε Εκτυπωτή
printFile.selectText.1=Select File to Print printFile.selectText.1=Επιλογή Αρχείου για Εκτύπωση
printFile.selectText.2=Enter Printer Name printFile.selectText.2=Εισάγετε το όνομα του εκτυπωτή
printFile.submit=Print printFile.submit=Εκτύπωση
#licenses #licenses
licenses.nav=Άδειες licenses.nav=Άδειες
licenses.title=3rd Party Άδειες licenses.title=3rd Party Άδειες
licenses.header=3rd Party Άδειες licenses.header=3rd Party Άδειες
licenses.module=Module licenses.module=Μόδουλο
licenses.version=Εκδοχή licenses.version=Εκδοχή
licenses.license=Άδεια licenses.license=Άδεια
#survey #survey
survey.nav=Survey survey.nav=Έρευνα
survey.title=Stirling-PDF Survey survey.title=Περιεχόμενο Έρευνας Stirling-PDF
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Η Stirling-PDF δεν επηρεάζεται από τη μετακίνηση. Ελπίζουμε πως θα συμμεριζόμαστε για να βελτιώσουμε τη Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Αφού κάποιες αλλαγές στην Stirling-PDF, θα πρόκειται να εξετάσουμε με τρόπου πιο συγκεκριμένο αυτά. Αναχαίτιζε την ελέγχωσή τους!
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Με αυτές τις αλλαγές, συμπεριλαμβάνονται και οι δομοφόνια χρηματοδότησης και εκπομπής
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Το παράθυρο ερεύνησης θα απενεργοποιηθεί σε μελλοντικές ενημερώσεις, αλλά θα παρουσιάζεται στο τέλος της διαδικασίας)
survey.button=Take Survey survey.button=Παίρνω μερίδα στην ερεύνα
survey.dontShowAgain=Don't show again survey.dontShowAgain=Δεν απεικονίζεται ξανά
#error #error
@@ -1205,21 +1229,19 @@ error.discordSubmit=Discord - Υποβάλετε ένα Support post
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Αφαίρεση εικόνας
removeImage.header=Remove image removeImage.header=Αφαίρεση εικόνας
removeImage.removeImage=Remove image removeImage.removeImage=Αφαίρεση εικόνας
removeImage.submit=Remove image removeImage.submit=Αποθέτει την εικόνα
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=Χωρίστε το PDF με βάση τα κεφάλαια
splitByChapters.header=Χωρίστε το PDF με βάση τα κεφάλαια
splitByChapters.bookmarkLevel=Επίπεδο Σήμανσης Σκέψης
splitByChapters.includeMetadata=Πρόσθεση Metadata
splitByChapters.allowDuplicates=Διάλυση Παρόντων Τίτλων Επιπέδου
splitByChapters.desc.1=Αυτή η εργαλείο χωρίζει το PDF αρχείο σε πολλά PDF βάση της καθορισμένης δομής του κεφαλαιώδους.
splitByChapters.desc.2=Επίπεδο Σήμανσης Σκέψης: Επιλέξτε το επίπεδο σήμανσης σκέψης που να χρησιμοποιηθεί για τη διάλυση (0 για το κύριο επίπεδο, 1 για το δεύτερο επίπεδο κλπ.).
splitByChapters.desc.3=Πρόσθεση Metadata: Αν επεξεργαστείται, οι αρχικές metadata του PDF θα προστεθούν σε κάθε διαλυμένο PDF.
splitByChapters.desc.4=Διάλυση Παρόντων Τίτλων Επιπέδου: Αν επεξεργαστείται, επιτρέπει τη δημιουργία αποκοπών PDF με βάση πλήρως καθορισμένους σήμαντες έδρας.
splitByChapters.submit=Διαλύστε το PDF

View File

@@ -79,6 +79,9 @@ info=Info
pro=Pro pro=Pro
page=Page page=Page
pages=Pages pages=Pages
loading=Loading...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Privacy Policy
legal.terms=Terms and Conditions legal.terms=Terms and Conditions
@@ -139,6 +142,7 @@ navbar.language=Languages
navbar.settings=Settings navbar.settings=Settings
navbar.allTools=Tools navbar.allTools=Tools
navbar.multiTool=Multi Tool navbar.multiTool=Multi Tool
navbar.search=Search
navbar.sections.organize=Organize navbar.sections.organize=Organize
navbar.sections.convertTo=Convert to PDF navbar.sections.convertTo=Convert to PDF
navbar.sections.convertFrom=Convert from PDF navbar.sections.convertFrom=Convert from PDF
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed to import file database.failedImportFile=Failed to import file
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -554,7 +559,6 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@@ -749,6 +753,7 @@ certSign.showSig=Show Signature
certSign.reason=Reason certSign.reason=Reason
certSign.location=Location certSign.location=Location
certSign.name=Name certSign.name=Name
certSign.showLogo=Show Logo
certSign.submit=Sign PDF certSign.submit=Sign PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1 compare.document.1=Document 1
compare.document.2=Document 2 compare.document.2=Document 2
compare.submit=Compare compare.submit=Compare
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=Books and Comics to PDF
@@ -805,6 +813,11 @@ sign.draw=Draw Signature
sign.text=Text Input sign.text=Text Input
sign.clear=Clear sign.clear=Clear
sign.add=Add sign.add=Add
sign.saved=Saved Signatures
sign.save=Save Signature
sign.personalSigs=Personal Signatures
sign.sharedSigs=Shared Signatures
sign.noSavedSigs=No saved signatures found
#repair #repair
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
multiTool.title=PDF Multi Tool multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool multiTool.header=PDF Multi Tool
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=File Name
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=View PDF viewPdf.title=View PDF
@@ -1221,5 +1245,3 @@ splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF splitByChapters.submit=Split PDF

View File

@@ -79,6 +79,9 @@ info=Info
pro=Pro pro=Pro
page=Page page=Page
pages=Pages pages=Pages
loading=Loading...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Privacy Policy
legal.terms=Terms and Conditions legal.terms=Terms and Conditions
@@ -139,6 +142,7 @@ navbar.language=Languages
navbar.settings=Settings navbar.settings=Settings
navbar.allTools=Tools navbar.allTools=Tools
navbar.multiTool=Multi Tool navbar.multiTool=Multi Tool
navbar.search=Search
navbar.sections.organize=Organize navbar.sections.organize=Organize
navbar.sections.convertTo=Convert to PDF navbar.sections.convertTo=Convert to PDF
navbar.sections.convertFrom=Convert from PDF navbar.sections.convertFrom=Convert from PDF
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -554,7 +559,6 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@@ -749,6 +753,7 @@ certSign.showSig=Show Signature
certSign.reason=Reason certSign.reason=Reason
certSign.location=Location certSign.location=Location
certSign.name=Name certSign.name=Name
certSign.showLogo=Show Logo
certSign.submit=Sign PDF certSign.submit=Sign PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=Highlight Color 2:
compare.document.1=Document 1 compare.document.1=Document 1
compare.document.2=Document 2 compare.document.2=Document 2
compare.submit=Compare compare.submit=Compare
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=Books and Comics to PDF
@@ -805,6 +813,11 @@ sign.draw=Draw Signature
sign.text=Text Input sign.text=Text Input
sign.clear=Clear sign.clear=Clear
sign.add=Add sign.add=Add
sign.saved=Saved Signatures
sign.save=Save Signature
sign.personalSigs=Personal Signatures
sign.sharedSigs=Shared Signatures
sign.noSavedSigs=No saved signatures found
#repair #repair
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
multiTool.title=PDF Multi Tool multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool multiTool.header=PDF Multi Tool
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=File Name
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=View PDF viewPdf.title=View PDF
@@ -1221,5 +1245,3 @@ splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF splitByChapters.submit=Split PDF

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Tamaño de Letra
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Nombre de Letra
pdfPrompt=Seleccionar PDF(s) pdfPrompt=Seleccionar PDF(s)
multiPdfPrompt=Seleccionar PDFs (2+) multiPdfPrompt=Seleccionar PDFs (2+)
multiPdfDropPrompt=Seleccione (o arrastre y suelte) todos los PDFs que quiera multiPdfDropPrompt=Seleccione (o arrastre y suelte) todos los PDFs que quiera
@@ -50,7 +50,7 @@ WorkInProgess=Tarea en progreso, puede no funcionar o ralentizarse; ¡por favor,
poweredBy=Desarrollado por poweredBy=Desarrollado por
yes= yes=
no=No no=No
changedCredsMessage=Se cambiaron las credenciales! changedCredsMessage=¡Se cambiaron las credenciales!
notAuthenticatedMessage=Usuario no autentificado. notAuthenticatedMessage=Usuario no autentificado.
userNotFoundMessage=Usuario no encontrado. userNotFoundMessage=Usuario no encontrado.
incorrectPasswordMessage=La contraseña actual no es correcta. incorrectPasswordMessage=La contraseña actual no es correcta.
@@ -75,16 +75,19 @@ visitGithub=Visitar Repositorio de Github
donate=Donar donate=Donar
color=Color color=Color
sponsor=Patrocinador sponsor=Patrocinador
info=Info info=Información
pro=Pro pro=Pro
page=Page page=Página
pages=Pages pages=Páginas
loading=Cargando...
addToDoc=Agregar al Documento
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Política de Privacidad
legal.terms=Terms and Conditions legal.terms=Términos y Condiciones
legal.accessibility=Accessibility legal.accessibility=Accesibilidad
legal.cookie=Cookie Policy legal.cookie=Política de Cookies
legal.impressum=Impressum legal.impressum=Impresión
############### ###############
# Pipeline # # Pipeline #
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Validar
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Actualiza a Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Esta característica está únicamente disponible para usuarios Pro.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro soporta configuración de ficheros YAML y otras características SSO.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=¿Busca más funciones de administración de usuarios? Consulte Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=¿Quieres mejorar Stirling PDF?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF ha optado por analíticas para ayudarnos a mejorar el producto. No rastreamos ninguna información personal ni contenido de archivos.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Considere habilitar analíticas para ayudar a Stirling-PDF a crecer y permitirnos comprender mejor a nuestros usuarios.
analytics.enable=Enable analytics analytics.enable=Habilitar analíticas
analytics.disable=Disable analytics analytics.disable=Deshabilitar analíticas
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Puede cambiar la configuración de analíticas en el archivo config/settings.yml
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Idiomas
navbar.settings=Configuración navbar.settings=Configuración
navbar.allTools=Herramientas navbar.allTools=Herramientas
navbar.multiTool=Multi herramientas navbar.multiTool=Multi herramientas
navbar.search=Search
navbar.sections.organize=Organizar navbar.sections.organize=Organizar
navbar.sections.convertTo=Convertir a PDF navbar.sections.convertTo=Convertir a PDF
navbar.sections.convertFrom=Convertir desde PDF navbar.sections.convertFrom=Convertir desde PDF
navbar.sections.security=Señalización y seguridad navbar.sections.security=Señalización y seguridad
navbar.sections.advance=Avanzado navbar.sections.advance=Avanzado
navbar.sections.edit=Ver y Editar navbar.sections.edit=Ver y Editar
navbar.sections.popular=Popular navbar.sections.popular=Populares
############# #############
# SETTINGS # # SETTINGS #
@@ -243,7 +247,8 @@ database.fileNotFound=Archivo no encontrado
database.fileNullOrEmpty=El archivo no debe ser nulo o vacío. database.fileNullOrEmpty=El archivo no debe ser nulo o vacío.
database.failedImportFile=Archivo de importación fallido database.failedImportFile=Archivo de importación fallido
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Tu sesión ha caducado. Actualice la página e inténtelo de nuevo.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -392,7 +397,7 @@ certSign.tags=autentificar,PEM,P12,oficial,encriptar
home.removeCertSign.title=Quitar signo de certificado home.removeCertSign.title=Quitar signo de certificado
home.removeCertSign.desc=Eliminar firma de certificado de PDF home.removeCertSign.desc=Eliminar firma de certificado de PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=autenticar,PEM,P12,oficial,desencriptar
home.pageLayout.title=Diseño de varias páginas home.pageLayout.title=Diseño de varias páginas
home.pageLayout.desc=Unir varias páginas de un documento PDF en una sola página home.pageLayout.desc=Unir varias páginas de un documento PDF en una sola página
@@ -503,28 +508,28 @@ home.removeImagePdf.desc=Eliminar imagen del PDF> para reducir el tamaño de arc
removeImagePdf.tags=Eliminar imagen,Operaciones de página,Back end,lado del servidor removeImagePdf.tags=Eliminar imagen,Operaciones de página,Back end,lado del servidor
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Dividir PDF por capítulos
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Divida un PDF en varios archivos según su estructura de capítulos.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=dividir,capítulos,marcadores,organizar
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Reemplazar-Invertir-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Reemplazar-Invertir Color en PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Reemplazar e Invertir Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Reemplaza el color del texto y el fondo en el PDF e invierte el color completo del PDF para reducir el tamaño del archivo
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Reemplazar Color,Operaciones de Página,Back end,Lado del servidor
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Opciones para Reemplazar o Invertir color
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Predeterminado (Colores de alto contraste predeterminados)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Personalizado (Colores personalizados)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Invertir Completo (Invertir todos los colores)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Opciones de color de alto contraste
replace-color.selectText.6=white text on black background replace-color.selectText.6=Texto blanco sobre fondo negro
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Texto negro sobre fondo blanco
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Texto amarillo sobre fondo negro
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Texto verde sobre fondo negro
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Elegir Color de Texto
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Elegir Color de Fondo
replace-color.submit=Replace replace-color.submit=Reemplazar
@@ -543,7 +548,7 @@ login.locked=Su cuenta se ha bloqueado.
login.signinTitle=Por favor, inicie sesión login.signinTitle=Por favor, inicie sesión
login.ssoSignIn=Iniciar sesión a través del inicio de sesión único login.ssoSignIn=Iniciar sesión a través del inicio de sesión único
login.oauth2AutoCreateDisabled=Usuario de creación automática de OAUTH2 DESACTIVADO login.oauth2AutoCreateDisabled=Usuario de creación automática de OAUTH2 DESACTIVADO
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=El registro o inicio de sesión de usuarios no registrados está actualmente bloqueado. Por favor, contáctese con el administrador.
login.oauth2RequestNotFound=Solicitud de autorización no encontrada login.oauth2RequestNotFound=Solicitud de autorización no encontrada
login.oauth2InvalidUserInfoResponse=Respuesta de información de usuario no válida login.oauth2InvalidUserInfoResponse=Respuesta de información de usuario no válida
login.oauth2invalidRequest=Solicitud no válida login.oauth2invalidRequest=Solicitud no válida
@@ -551,10 +556,9 @@ login.oauth2AccessDenied=Acceso denegado
login.oauth2InvalidTokenResponse=Respuesta de token no válida login.oauth2InvalidTokenResponse=Respuesta de token no válida
login.oauth2InvalidIdToken=Token de identificación no válido login.oauth2InvalidIdToken=Token de identificación no válido
login.userIsDisabled=El usuario está desactivado, actualmente el acceso está bloqueado para ese nombre de usuario. Por favor, póngase en contacto con el administrador. login.userIsDisabled=El usuario está desactivado, actualmente el acceso está bloqueado para ese nombre de usuario. Por favor, póngase en contacto con el administrador.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Ya has iniciado sesión en
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=dispositivos. Cierra sesión en los dispositivos y vuelve a intentarlo.
login.toManySessions=You have too many active sessions login.toManySessions=Tienes demasiadas sesiones activas
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redactar autoRedact.title=Auto Redactar
@@ -749,6 +753,7 @@ certSign.showSig=Mostrar firma
certSign.reason=Razón certSign.reason=Razón
certSign.location=Ubicación certSign.location=Ubicación
certSign.name=Nombre certSign.name=Nombre
certSign.showLogo=Mostrar Logotipo
certSign.submit=Firmar PDF certSign.submit=Firmar PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=Color resaltado 2:
compare.document.1=Documento 1 compare.document.1=Documento 1
compare.document.2=Documento 2 compare.document.2=Documento 2
compare.submit=Comparar compare.submit=Comparar
compare.complex.message=Uno o ambos de los documentos proporcionados son archivos grandes; la precisión de la comparación puede disminuir.
compare.large.file.message=Uno o ambos de los documentos proporcionados son demasiado grandes para procesarse.
compare.no.text.message=Uno o ambos de los PDF seleccionados no contienen contenido de texto. Por favor, elija PDFs con texto para la comparación.
#BookToPDF #BookToPDF
BookToPDF.title=Libros y Cómics a PDF BookToPDF.title=Libros y Cómics a PDF
@@ -805,6 +813,11 @@ sign.draw=Dibujar firma
sign.text=Entrada de texto sign.text=Entrada de texto
sign.clear=Borrar sign.clear=Borrar
sign.add=Agregar sign.add=Agregar
sign.saved=firmas guardadas
sign.save=Guardar Firma
sign.personalSigs=Firmas Personales
sign.sharedSigs=Firmas compartidas
sign.noSavedSigs=No se encontraron firmas guardadas
#repair #repair
@@ -888,7 +901,7 @@ addImage.title=Añadir imagen
addImage.header=Añadir imagen de PDF addImage.header=Añadir imagen de PDF
addImage.everyPage=¿Todas las páginas? addImage.everyPage=¿Todas las páginas?
addImage.upload=Añadir imagen addImage.upload=Añadir imagen
addImage.submit=Añadir imagen addImage.submit=Enviar imagen
#merge #merge
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(por ej., 1,3,2 o 4-8,2,10-12 o 2n-1)
multiTool.title=Multi-herramienta PDF multiTool.title=Multi-herramienta PDF
multiTool.header=Multi-herramienta PDF multiTool.header=Multi-herramienta PDF
multiTool.uploadPrompts=Nombre del archivo multiTool.uploadPrompts=Nombre del archivo
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Ver PDF viewPdf.title=Ver PDF
@@ -1124,7 +1148,7 @@ PDFToCSV.prompt=Elija una página para extraer la tabla
PDFToCSV.submit=Extraer PDFToCSV.submit=Extraer
#split-by-size-or-count #split-by-size-or-count
split-by-size-or-count.title=Split PDF by Size or Count split-by-size-or-count.title=Dividir PDF por tamaño o cantidad
split-by-size-or-count.header=Dividir PDF por tamaño o número split-by-size-or-count.header=Dividir PDF por tamaño o número
split-by-size-or-count.type.label=Seleccionar tipo de división split-by-size-or-count.type.label=Seleccionar tipo de división
split-by-size-or-count.type.size=Por tamaño split-by-size-or-count.type.size=Por tamaño
@@ -1182,8 +1206,8 @@ licenses.license=Licencia
survey.nav=Encuesta survey.nav=Encuesta
survey.title=Encuesta Stirling-PDF survey.title=Encuesta Stirling-PDF
survey.description=Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF. survey.description=Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF.
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF ha cambiado desde la última encuesta! Para obtener más información, revise nuestro artículo de blog aquí:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Con estos cambios estamos obteniendo apoyo y financiamiento empresarial
survey.please=¡Considere realizar nuestra encuesta! survey.please=¡Considere realizar nuestra encuesta!
survey.disabled=(La ventana emergente de la encuesta se desactivará en las siguientes actualizaciones, pero estará disponible al pie de la página.) survey.disabled=(La ventana emergente de la encuesta se desactivará en las siguientes actualizaciones, pero estará disponible al pie de la página.)
survey.button=Realizar encuesta survey.button=Realizar encuesta
@@ -1211,15 +1235,13 @@ removeImage.removeImage=Eliminar imagen
removeImage.submit=Eliminar imagen removeImage.submit=Eliminar imagen
splitByChapters.title=Split PDF by Chapters splitByChapters.title=Dividir PDF por Capítulos
splitByChapters.header=Split PDF by Chapters splitByChapters.header=Dividir PDF por Capítulos
splitByChapters.bookmarkLevel=Bookmark Level splitByChapters.bookmarkLevel=Nivel de Marcador
splitByChapters.includeMetadata=Include Metadata splitByChapters.includeMetadata=Incluir Metadatos
splitByChapters.allowDuplicates=Allow Duplicates splitByChapters.allowDuplicates=Permitir Duplicados
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure. splitByChapters.desc.1=Esta herramienta divide un archivo PDF en múltiples archivos PDF según su estructura de capítulos.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.). splitByChapters.desc.2=Nivel de Marcador: Elige el nivel de marcadores para dividir (0 para el nivel superior, 1 para el segundo nivel, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Incluir Metadatos: Si está seleccionado, los metadatos del PDF original se incluirán en cada PDF dividido.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Permitir Duplicados: Si está seleccionado, permite que múltiples marcadores en la misma página creen archivos PDF separados.
splitByChapters.submit=Split PDF splitByChapters.submit=Dividir PDF

View File

@@ -79,6 +79,9 @@ info=Info
pro=Pro pro=Pro
page=Page page=Page
pages=Pages pages=Pages
loading=Loading...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Privacy Policy
legal.terms=Terms and Conditions legal.terms=Terms and Conditions
@@ -139,6 +142,7 @@ navbar.language=Languages
navbar.settings=Ezarpenak navbar.settings=Ezarpenak
navbar.allTools=Tools navbar.allTools=Tools
navbar.multiTool=Multi Tools navbar.multiTool=Multi Tools
navbar.search=Search
navbar.sections.organize=Organize navbar.sections.organize=Organize
navbar.sections.convertTo=Convert to PDF navbar.sections.convertTo=Convert to PDF
navbar.sections.convertFrom=Convert from PDF navbar.sections.convertFrom=Convert from PDF
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -554,7 +559,6 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Idatzi autoRedact.title=Auto Idatzi
@@ -749,6 +753,7 @@ certSign.showSig=Erakutsi sinadura
certSign.reason=Arrazoia certSign.reason=Arrazoia
certSign.location=Kokalekua certSign.location=Kokalekua
certSign.name=Izena certSign.name=Izena
certSign.showLogo=Show Logo
certSign.submit=Sinatu PDFa certSign.submit=Sinatu PDFa
@@ -783,6 +788,9 @@ compare.highlightColor.2=Highlight Color 2:
compare.document.1=1. dokumentua compare.document.1=1. dokumentua
compare.document.2=2. dokumentua compare.document.2=2. dokumentua
compare.submit=Konparatu compare.submit=Konparatu
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=Books and Comics to PDF
@@ -805,6 +813,11 @@ sign.draw=Marraztu sinadura
sign.text=Testua sartzea sign.text=Testua sartzea
sign.clear=Garbitu sign.clear=Garbitu
sign.add=Gehitu sign.add=Gehitu
sign.saved=Saved Signatures
sign.save=Save Signature
sign.personalSigs=Personal Signatures
sign.sharedSigs=Shared Signatures
sign.noSavedSigs=No saved signatures found
#repair #repair
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
multiTool.title=PDF erabilera anitzeko tresna multiTool.title=PDF erabilera anitzeko tresna
multiTool.header=PDF erabilera anitzeko tresna multiTool.header=PDF erabilera anitzeko tresna
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=File Name
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=View PDF viewPdf.title=View PDF
@@ -1221,5 +1245,3 @@ splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF splitByChapters.submit=Split PDF

View File

@@ -3,14 +3,14 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Taille de Police
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Nom de la Police
pdfPrompt=Sélectionnez le(s) PDF pdfPrompt=Sélectionnez le(s) PDF
multiPdfPrompt=Sélectionnez les PDF multiPdfPrompt=Sélectionnez les PDF
multiPdfDropPrompt=Sélectionnez (ou glissez-déposez) tous les PDF dont vous avez besoin multiPdfDropPrompt=Sélectionnez (ou glissez-déposez) tous les PDF dont vous avez besoin
imgPrompt=Choisir une image imgPrompt=Choisir une image
genericSubmit=Envoyer genericSubmit=Envoyer
processTimeWarning=Attention, ce processus peut prendre jusquà une minute en fonction de la taille du fichier. processTimeWarning=Attention, ce processus peut prendre jusqu'à une minute en fonction de la taille du fichier.
pageOrderPrompt=Ordre des pages (entrez une liste de numéros de page séparés par des virgules ou des fonctions telles que 2n+1) : pageOrderPrompt=Ordre des pages (entrez une liste de numéros de page séparés par des virgules ou des fonctions telles que 2n+1) :
pageSelectionPrompt=Sélection des pages (entrez une liste de numéros de page séparés par des virgules ou des fonctions telles que 2n+1) : pageSelectionPrompt=Sélection des pages (entrez une liste de numéros de page séparés par des virgules ou des fonctions telles que 2n+1) :
goToPage=Aller goToPage=Aller
@@ -23,7 +23,7 @@ close=Fermer
filesSelected=fichiers sélectionnés filesSelected=fichiers sélectionnés
noFavourites=Aucun favori ajouté noFavourites=Aucun favori ajouté
downloadComplete=Téléchargement terminé downloadComplete=Téléchargement terminé
bored=Marre dattendre ? bored=Marre d'attendre ?
alphabet=Alphabet alphabet=Alphabet
downloadPdf=Télécharger le PDF downloadPdf=Télécharger le PDF
text=Texte text=Texte
@@ -34,9 +34,9 @@ sizes.small=Petit
sizes.medium=Moyen sizes.medium=Moyen
sizes.large=Grand sizes.large=Grand
sizes.x-large=Très grand sizes.x-large=Très grand
error.pdfPassword=Le document PDF est protégé par un mot de passe qui na pas été fourni ou était incorrect error.pdfPassword=Le document PDF est protégé par un mot de passe qui n'a pas été fourni ou était incorrect
delete=Supprimer delete=Supprimer
username=Nom dutilisateur username=Nom d'utilisateur
password=Mot de passe password=Mot de passe
welcome=Bienvenue welcome=Bienvenue
property=Propriété property=Propriété
@@ -54,37 +54,40 @@ changedCredsMessage=Les identifiants ont été mis à jour !
notAuthenticatedMessage=Utilisateur non authentifié. notAuthenticatedMessage=Utilisateur non authentifié.
userNotFoundMessage=Utilisateur non trouvé. userNotFoundMessage=Utilisateur non trouvé.
incorrectPasswordMessage=Le mot de passe actuel est incorrect. incorrectPasswordMessage=Le mot de passe actuel est incorrect.
usernameExistsMessage=Le nouveau nom dutilisateur existe déjà. usernameExistsMessage=Le nouveau nom d'utilisateur existe déjà.
invalidUsernameMessage=Nom dutilisateur invalide, le nom dutilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide. invalidUsernameMessage=Nom d'utilisateur invalide, le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=Le mot de passe ne peut pas être vide et ne doit pas contenir d'espaces au début ou en fin.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Nouveau Mot de passe et Confirmer le Nouveau Mot de passe doivent correspondre.
deleteCurrentUserMessage=Impossible de supprimer lutilisateur actuellement connecté. deleteCurrentUserMessage=Impossible de supprimer l'utilisateur actuellement connecté.
deleteUsernameExistsMessage=Le nom dutilisateur nexiste pas et ne peut pas être supprimé. deleteUsernameExistsMessage=Le nom d'utilisateur n'existe pas et ne peut pas être supprimé.
downgradeCurrentUserMessage=Impossible de rétrograder le rôle de l'utilisateur actuel. downgradeCurrentUserMessage=Impossible de rétrograder le rôle de l'utilisateur actuel.
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=L'utilisateur actuel ne peut pas être désactivé
downgradeCurrentUserLongMessage=Impossible de rétrograder le rôle de l'utilisateur actuel. Par conséquent, l'utilisateur actuel ne sera pas affiché. downgradeCurrentUserLongMessage=Impossible de rétrograder le rôle de l'utilisateur actuel. Par conséquent, l'utilisateur actuel ne sera pas affiché.
userAlreadyExistsOAuthMessage=L'utilisateur existe déjà en tant qu'utilisateur OAuth2. userAlreadyExistsOAuthMessage=L'utilisateur existe déjà en tant qu'utilisateur OAuth2.
userAlreadyExistsWebMessage=L'utilisateur existe déjà en tant qu'utilisateur Web. userAlreadyExistsWebMessage=L'utilisateur existe déjà en tant qu'utilisateur Web.
error=Erreur error=Erreur
oops=Oups ! oops=Oups !
help=Aide help=Aide
goHomepage=Aller à la page daccueil goHomepage=Aller à la page d'accueil
joinDiscord=Rejoignez notre serveur Discord joinDiscord=Rejoignez notre serveur Discord
seeDockerHub=Consulter le Docker Hub seeDockerHub=Consulter le Docker Hub
visitGithub=Visiter le dépôt Github visitGithub=Visiter le dépôt Github
donate=Faire un don donate=Faire un don
color=Couleur color=Couleur
sponsor=Sponsor sponsor=Sponsoriser
info=Info info=Informations
pro=Pro pro=Pro
page=Page page=Page
pages=Pages pages=Pages
loading=Chargement...
addToDoc=Ajouter au Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Politique de Confidentialité
legal.terms=Terms and Conditions legal.terms=Conditions Générales
legal.accessibility=Accessibility legal.accessibility=Accessibilité
legal.cookie=Cookie Policy legal.cookie=Politique des Cookies
legal.impressum=Impressum legal.impressum=Mentions Légales
############### ###############
# Pipeline # # Pipeline #
@@ -96,7 +99,7 @@ pipeline.defaultOption=Personnaliser
pipeline.submitButton=Soumettre pipeline.submitButton=Soumettre
pipeline.help=Aide Pipeline pipeline.help=Aide Pipeline
pipeline.scanHelp=Aide analyse de dossier pipeline.scanHelp=Aide analyse de dossier
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Êtes-vous sûr de vouloir supprimer le pipeline ?
###################### ######################
# Pipeline Options # # Pipeline Options #
@@ -107,28 +110,28 @@ pipelineOptions.saveSettings=Sauvegarder la configuration
pipelineOptions.pipelineNamePrompt=Entrez ici le nom du pipeline pipelineOptions.pipelineNamePrompt=Entrez ici le nom du pipeline
pipelineOptions.selectOperation=Sélectionner une opération pipelineOptions.selectOperation=Sélectionner une opération
pipelineOptions.addOperationButton=Ajouter une opération pipelineOptions.addOperationButton=Ajouter une opération
pipelineOptions.pipelineHeader=Pipeline: pipelineOptions.pipelineHeader=Pipeline :
pipelineOptions.saveButton=Télécharger pipelineOptions.saveButton=Télécharger
pipelineOptions.validateButton=Valider pipelineOptions.validateButton=Valider
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Passer à Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Cette fonctionnalité est uniquement disponible pour les utilisateurs Pro.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro prend en charge les fichiers de configuration YAML et d'autres fonctionnalités SSO.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Vous cherchez plus de fonctionnalités de gestion des utilisateurs ? Découvrez Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Souhaitez-vous améliorer Stirling PDF ?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF utilise des analyses volontaires pour nous aider à améliorer le produit. Nous ne suivons aucune information personnelle ni le contenu des fichiers.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Veuillez envisager d'activer les analyses pour aider Stirling-PDF à se développer et pour nous permettre de mieux comprendre nos utilisateurs.
analytics.enable=Enable analytics analytics.enable=Activer les analyses
analytics.disable=Disable analytics analytics.disable=Désactiver les analyses
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Vous pouvez modifier les paramètres des analyses dans le fichier config/settings.yml
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Langues
navbar.settings=Paramètres navbar.settings=Paramètres
navbar.allTools=Outils navbar.allTools=Outils
navbar.multiTool=Outils Multiples navbar.multiTool=Outils Multiples
navbar.search=Search
navbar.sections.organize=Organisation navbar.sections.organize=Organisation
navbar.sections.convertTo=Convertir en PDF navbar.sections.convertTo=Convertir en PDF
navbar.sections.convertFrom=Convertir depuis PDF navbar.sections.convertFrom=Convertir depuis PDF
navbar.sections.security=Signature et sécurité navbar.sections.security=Signature et sécurité
navbar.sections.advance=Mode avancé navbar.sections.advance=Mode avancé
navbar.sections.edit=Voir et modifier navbar.sections.edit=Voir et modifier
navbar.sections.popular=Popular navbar.sections.popular=Populaire
############# #############
# SETTINGS # # SETTINGS #
@@ -153,8 +157,8 @@ navbar.sections.popular=Popular
settings.title=Paramètres settings.title=Paramètres
settings.update=Mise à jour disponible settings.update=Mise à jour disponible
settings.updateAvailable={0} est la version actuellement installée. Une nouvelle version ({1}) est disponible. settings.updateAvailable={0} est la version actuellement installée. Une nouvelle version ({1}) est disponible.
settings.appVersion=Version de lapplication : settings.appVersion=Version de l'application :
settings.downloadOption.title=Choisissez loption de téléchargement (pour les téléchargements à fichier unique non ZIP) : settings.downloadOption.title=Choisissez l'option de téléchargement (pour les téléchargements à fichier unique non ZIP) :
settings.downloadOption.1=Ouvrir dans la même fenêtre settings.downloadOption.1=Ouvrir dans la même fenêtre
settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre settings.downloadOption.2=Ouvrir dans une nouvelle fenêtre
settings.downloadOption.3=Télécharger le fichier settings.downloadOption.3=Télécharger le fichier
@@ -168,7 +172,7 @@ settings.cacheInputs.help=Permet de stocker les entrées précédemment utilisé
changeCreds.title=Modifiez vos identifiants changeCreds.title=Modifiez vos identifiants
changeCreds.header=Mettez à jour vos identifiants de connexion changeCreds.header=Mettez à jour vos identifiants de connexion
changeCreds.changePassword=Vous utilisez les identifiants de connexion par défaut. Veuillez saisir un nouveau mot de passe changeCreds.changePassword=Vous utilisez les identifiants de connexion par défaut. Veuillez saisir un nouveau mot de passe
changeCreds.newUsername=Nouveau nom dutilisateur changeCreds.newUsername=Nouveau nom d'utilisateur
changeCreds.oldPassword=Mot de passe actuel changeCreds.oldPassword=Mot de passe actuel
changeCreds.newPassword=Nouveau mot de passe changeCreds.newPassword=Nouveau mot de passe
changeCreds.confirmNewPassword=Confirmer le nouveau mot de passe changeCreds.confirmNewPassword=Confirmer le nouveau mot de passe
@@ -178,10 +182,10 @@ changeCreds.submit=Soumettre les modifications
account.title=Paramètres du compte account.title=Paramètres du compte
account.accountSettings=Paramètres du compte account.accountSettings=Paramètres du compte
account.adminSettings=Paramètres dadministration Voir et ajouter des utilisateurs account.adminSettings=Paramètres d'administration Voir et ajouter des utilisateurs
account.userControlSettings=Contrôle des paramètres des utilisateurs account.userControlSettings=Contrôle des paramètres des utilisateurs
account.changeUsername=Modifier le nom dutilisateur account.changeUsername=Modifier le nom d'utilisateur
account.newUsername=Nouveau nom dutilisateur account.newUsername=Nouveau nom d'utilisateur
account.password=Mot de passe de confirmation account.password=Mot de passe de confirmation
account.oldPassword=Ancien mot de passe account.oldPassword=Ancien mot de passe
account.newPassword=Nouveau mot de passe account.newPassword=Nouveau mot de passe
@@ -202,48 +206,49 @@ adminUserSettings.header=Administration des paramètres des utilisateurs
adminUserSettings.admin=Administateur adminUserSettings.admin=Administateur
adminUserSettings.user=Utilisateur adminUserSettings.user=Utilisateur
adminUserSettings.addUser=Ajouter un utilisateur adminUserSettings.addUser=Ajouter un utilisateur
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Supprimer l'utilisateur
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=Voulez vous vraiment supprimer l'utilisateur ?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Voulez vous vraiment déactiver/réactiver l'utilisateur ?
adminUserSettings.usernameInfo=Le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide. adminUserSettings.usernameInfo=Le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide.
adminUserSettings.roles=Rôles adminUserSettings.roles=Rôles
adminUserSettings.role=Rôle adminUserSettings.role=Rôle
adminUserSettings.actions=Actions adminUserSettings.actions=Actions
adminUserSettings.apiUser=Utilisateur API limité adminUserSettings.apiUser=Utilisateur API limité
adminUserSettings.extraApiUser=Utilisateur limité supplémentaire de lAPI adminUserSettings.extraApiUser=Utilisateur limité supplémentaire de l'API
adminUserSettings.webOnlyUser=Utilisateur Web uniquement adminUserSettings.webOnlyUser=Utilisateur Web uniquement
adminUserSettings.demoUser=Demo User (Paramètres par défaut) adminUserSettings.demoUser=Demo User (Paramètres par défaut)
adminUserSettings.internalApiUser=Utilisateur de l'API interne adminUserSettings.internalApiUser=Utilisateur de l'API interne
adminUserSettings.forceChange=Forcer lutilisateur à changer son nom dutilisateur/mot de passe lors de la connexion adminUserSettings.forceChange=Forcer l'utilisateur à changer son nom d'utilisateur/mot de passe lors de la connexion
adminUserSettings.submit=Ajouter adminUserSettings.submit=Ajouter
adminUserSettings.changeUserRole=Changer le rôle de l'utilisateur adminUserSettings.changeUserRole=Changer le rôle de l'utilisateur
adminUserSettings.authenticated=Authentifié adminUserSettings.authenticated=Authentifié
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Éditer son propre profil
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=Utilisateur activé
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=Utilisateur désactivé
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Utilisateurs actifs :
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Utilisateurs désactivés :
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Utilisateurs au total :
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Dernière requête
database.title=Database Import/Export database.title=Import/Export de la Base de Données
database.header=Database Import/Export database.header=Import/Export de la Base de Données
database.fileName=File Name database.fileName=Nom du Fichier
database.creationDate=Creation Date database.creationDate=Date de Création
database.fileSize=File Size database.fileSize=Taille du Fichier
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Supprimer le fichier de sauvegarde
database.importBackupFile=Import Backup File database.importBackupFile=Importer le fichier de sauvegarde
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Télécharger le fichier de sauvegarde
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=Lors de l'importation des données, il est crucial de garantir la structure correcte. Si vous n'êtes pas sûr de ce que vous faites, sollicitez un avis et un soutien d'un professionnel. Une erreur dans la structure peut entraîner des dysfonctionnements de l'application, allant jusqu'à l'incapacité totale d'exécuter l'application.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=Le nom du fichier ne fait pas de différence lors de l'upload. Il sera renommé ultérieurement selon le format backup_user_yyyyMMddHHmm.sql, assurant ainsi une convention de nommage cohérente.
database.submit=Import Backup database.submit=Importer la sauvegarde
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Importation dans la base de données réussie
database.fileNotFound=File not Found database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Fichier ne peut pas être null ou vide
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Votre session a expiré. Veuillez recharger la page et réessayer.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -282,7 +287,7 @@ home.pdfToImage.desc=Convertissez un PDF en image (PNG, JPEG, GIF).
pdfToImage.tags=conversion,img,jpg,image,photo pdfToImage.tags=conversion,img,jpg,image,photo
home.pdfOrganiser.title=Organiser home.pdfOrganiser.title=Organiser
home.pdfOrganiser.desc=Supprimez ou réorganisez les pages dans nimporte quel ordre. home.pdfOrganiser.desc=Supprimez ou réorganisez les pages dans n'importe quel ordre.
pdfOrganiser.tags=organiser,recto-verso,duplex,even,odd,sort,move pdfOrganiser.tags=organiser,recto-verso,duplex,even,odd,sort,move
@@ -292,7 +297,7 @@ addImage.tags=img,jpg,image,photo
home.watermark.title=Ajouter un filigrane home.watermark.title=Ajouter un filigrane
home.watermark.desc=Ajoutez un filigrane personnalisé à votre PDF. home.watermark.desc=Ajoutez un filigrane personnalisé à votre PDF.
watermark.tags=texte,filigrane,label,propriété,droit dauteur,marque déposée,img,jpg,image,photo,copyright,trademark watermark.tags=texte,filigrane,label,propriété,droit d'auteur,marque déposée,img,jpg,image,photo,copyright,trademark
home.permissions.title=Modifier les permissions home.permissions.title=Modifier les permissions
home.permissions.desc=Modifiez les permissions de votre PDF. home.permissions.desc=Modifiez les permissions de votre PDF.
@@ -321,16 +326,16 @@ home.changeMetadata.desc=Modifiez, supprimez ou ajoutez des métadonnées à un
changeMetadata.tags=métadonnées,titre,auteur,date,création,heure,éditeur,statistiques,title,author,date,creation,time,publisher,producer,stats,metadata changeMetadata.tags=métadonnées,titre,auteur,date,création,heure,éditeur,statistiques,title,author,date,creation,time,publisher,producer,stats,metadata
home.fileToPDF.title=Fichier en PDF home.fileToPDF.title=Fichier en PDF
home.fileToPDF.desc=Convertissez presque nimporte quel fichiers en PDF (DOCX, PNG, XLS, PPT, TXT et plus). home.fileToPDF.desc=Convertissez presque n'importe quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT, etc.).
fileToPDF.tags=convertion,transformation,format,document,image,slide,texte,conversion,office,docs,word,excel,powerpoint fileToPDF.tags=convertion,transformation,format,document,image,slide,texte,conversion,office,docs,word,excel,powerpoint
home.ocr.title=OCR / Nettoyage des numérisations home.ocr.title=OCR / Nettoyage des numérisations
home.ocr.desc=Utilisez lOCR pour analyser et détecter le texte des images dun PDF et le rajouter en tant que tel. home.ocr.desc=Utilisez l'OCR pour analyser et détecter le texte des images d'un PDF et le rajouter en tant que tel.
ocr.tags=ocr,reconnaissance,texte,image,numérisation,scan,read,identify,detection,editable ocr.tags=ocr,reconnaissance,texte,image,numérisation,scan,read,identify,detection,editable
home.extractImages.title=Extraire les images home.extractImages.title=Extraire les images
home.extractImages.desc=Extrayez toutes les images dun PDF et enregistrez-les dans un ZIP. home.extractImages.desc=Extrayez toutes les images d'un PDF et enregistrez-les dans un ZIP.
extractImages.tags=image,photo,save,archive,zip,capture,grab extractImages.tags=image,photo,save,archive,zip,capture,grab
home.pdfToPDFA.title=PDF en PDF/A home.pdfToPDFA.title=PDF en PDF/A
@@ -339,7 +344,7 @@ pdfToPDFA.tags=convertion,archive,long-term,standard,conversion,storage,préserv
home.PDFToWord.title=PDF en Word home.PDFToWord.title=PDF en Word
home.PDFToWord.desc=Convertissez un PDF en Word (DOC, DOCX et ODT). home.PDFToWord.desc=Convertissez un PDF en Word (DOC, DOCX et ODT).
PDFToWord.tags=doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile PDFToWord.tags=doc, docx, odt, word, transformation, format, conversion, office, microsoft, docfile
home.PDFToPresentation.title=PDF en formats de présentation home.PDFToPresentation.title=PDF en formats de présentation
home.PDFToPresentation.desc=Convertissez un PDF en format de présentation (PPT, PPTX et ODP). home.PDFToPresentation.desc=Convertissez un PDF en format de présentation (PPT, PPTX et ODP).
@@ -347,7 +352,7 @@ PDFToPresentation.tags=présentation,slides,show,office,microsoft
home.PDFToText.title=PDF en RTF (texte) home.PDFToText.title=PDF en RTF (texte)
home.PDFToText.desc=Convertissez un PDF au format RTF (texte). home.PDFToText.desc=Convertissez un PDF au format RTF (texte).
PDFToText.tags=richformat,richtextformat,rich text format PDFToText.tags=format riche, format de texte riche, format de texte enrichi
home.PDFToHTML.title=PDF en HTML home.PDFToHTML.title=PDF en HTML
home.PDFToHTML.desc=Convertissez un PDF au format HTML. home.PDFToHTML.desc=Convertissez un PDF au format HTML.
@@ -359,7 +364,7 @@ home.PDFToXML.desc=Convertissez un PDF au format XML.
PDFToXML.tags=xml,extraction de données,contenu structuré,interopérabilité,data-extraction,structured-content,interop,transformation,convert PDFToXML.tags=xml,extraction de données,contenu structuré,interopérabilité,data-extraction,structured-content,interop,transformation,convert
home.ScannerImageSplit.title=Diviser les photos numérisées home.ScannerImageSplit.title=Diviser les photos numérisées
home.ScannerImageSplit.desc=Divisez plusieurs photos à partir dune photo ou dun PDF. home.ScannerImageSplit.desc=Divisez plusieurs photos à partir d'une photo ou d'un PDF.
ScannerImageSplit.tags=diviser,détecter automatiquement,numériser,separate,auto-detect,scans,multi-photo,organize ScannerImageSplit.tags=diviser,détecter automatiquement,numériser,separate,auto-detect,scans,multi-photo,organize
home.sign.title=Signer home.sign.title=Signer
@@ -367,7 +372,7 @@ home.sign.desc=Ajoutez une signature au PDF avec un dessin, du texte ou une imag
sign.tags=signer,authorize,initials,drawn-signature,text-sign,image-signature sign.tags=signer,authorize,initials,drawn-signature,text-sign,image-signature
home.flatten.title=Rendre inerte home.flatten.title=Rendre inerte
home.flatten.desc=Supprimez tous les éléments et formulaires interactifs dun PDF. home.flatten.desc=Supprimez tous les éléments et formulaires interactifs d'un PDF.
flatten.tags=inerte,static,deactivate,non-interactive,streamline flatten.tags=inerte,static,deactivate,non-interactive,streamline
home.repair.title=Réparer home.repair.title=Réparer
@@ -375,11 +380,11 @@ home.repair.desc=Essayez de réparer un PDF corrompu ou cassé.
repair.tags=réparer,restaurer,corriger,récupérer,fix,restore,correction,recover repair.tags=réparer,restaurer,corriger,récupérer,fix,restore,correction,recover
home.removeBlanks.title=Supprimer les pages vierges home.removeBlanks.title=Supprimer les pages vierges
home.removeBlanks.desc=Détectez et supprimez les pages vierges dun PDF. home.removeBlanks.desc=Détectez et supprimez les pages vierges d'un PDF.
removeBlanks.tags=pages vierges,supprimer,nettoyer,cleanup,streamline,non-content,organize removeBlanks.tags=pages vierges,supprimer,nettoyer,cleanup,streamline,non-content,organize
home.removeAnnotations.title=Supprimer les annotations home.removeAnnotations.title=Supprimer les annotations
home.removeAnnotations.desc=Supprimer tous les commentaires/annotations dun PDF. home.removeAnnotations.desc=Supprimer tous les commentaires/annotations d'un PDF.
removeAnnotations.tags=commentaires,supprimer,annotations,highlight,notes,markup,remove removeAnnotations.tags=commentaires,supprimer,annotations,highlight,notes,markup,remove
home.compare.title=Comparer home.compare.title=Comparer
@@ -390,16 +395,16 @@ home.certSign.title=Signer avec un certificat
home.certSign.desc=Signez un PDF avec un certificat ou une clé (PEM/P12). home.certSign.desc=Signez un PDF avec un certificat ou une clé (PEM/P12).
certSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,encrypt certSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Supprimer la signature par certificat
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=Supprimez la signature par certificat d'un PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Fusionner des pages home.pageLayout.title=Fusionner des pages
home.pageLayout.desc=Fusionnez plusieurs pages dun PDF en une seule. home.pageLayout.desc=Fusionnez plusieurs pages d'un PDF en une seule.
pageLayout.tags=fusionner,merge,composite,single-view,organize pageLayout.tags=fusionner,merge,composite,single-view,organize
home.scalePages.title=Ajuster léchelle ou la taille home.scalePages.title=Ajuster l'échelle ou la taille
home.scalePages.desc=Modifiez la taille ou léchelle dune page et/ou de son contenu. home.scalePages.desc=Modifiez la taille ou l'échelle d'une page et/ou de son contenu.
scalePages.tags=ajuster,redimensionner,resize,modify,dimension,adapt scalePages.tags=ajuster,redimensionner,resize,modify,dimension,adapt
home.pipeline.title=Pipeline home.pipeline.title=Pipeline
@@ -415,7 +420,7 @@ home.auto-rename.desc=Renommez automatiquement un fichier PDF en fonction de son
auto-rename.tags=renommer,détection automatique,réétiqueter,auto-detect,header-based,organize,relabel auto-rename.tags=renommer,détection automatique,réétiqueter,auto-detect,header-based,organize,relabel
home.adjust-contrast.title=Ajuster les couleurs home.adjust-contrast.title=Ajuster les couleurs
home.adjust-contrast.desc=Ajustez le contraste, la saturation et la luminosité dun PDF. home.adjust-contrast.desc=Ajustez le contraste, la saturation et la luminosité d'un PDF.
adjust-contrast.tags=ajuster,couleurs,amélioration,color-correction,tune,modify,enhance adjust-contrast.tags=ajuster,couleurs,amélioration,color-correction,tune,modify,enhance
home.crop.title=Redimensionner home.crop.title=Redimensionner
@@ -431,16 +436,16 @@ home.sanitizePdf.desc=Supprimez les scripts et autres éléments des PDF.
sanitizePdf.tags=assainir,sécurisé,clean,secure,safe,remove-threats sanitizePdf.tags=assainir,sécurisé,clean,secure,safe,remove-threats
home.URLToPDF.title=URL en PDF home.URLToPDF.title=URL en PDF
home.URLToPDF.desc=Convertissez nimporte quelle URL http(s) en PDF. home.URLToPDF.desc=Convertissez n'importe quelle URL http(s) en PDF.
URLToPDF.tags=pdf,contenu Web,save-page,web-to-doc,archive URLToPDF.tags=pdf,contenu Web,save-page,web-to-doc,archive
home.HTMLToPDF.title=HTML en PDF home.HTMLToPDF.title=HTML en PDF
home.HTMLToPDF.desc=Convertissez nimporte quel fichier HTML ou ZIP en PDF. home.HTMLToPDF.desc=Convertissez n'importe quel fichier HTML ou ZIP en PDF.
HTMLToPDF.tags=html,markup,contenu Web,transformation,convert HTMLToPDF.tags=html,markup,contenu Web,transformation,convert
home.MarkdownToPDF.title=Markdown en PDF home.MarkdownToPDF.title=Markdown en PDF
home.MarkdownToPDF.desc=Convertissez nimporte quel fichier Markdown en PDF. home.MarkdownToPDF.desc=Convertissez n'importe quel fichier Markdown en PDF.
MarkdownToPDF.tags=markdown,markup,contenu Web,transformation,convert MarkdownToPDF.tags=markdown,markup,contenu Web,transformation,convert
@@ -464,29 +469,29 @@ home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
showJS.tags=JS showJS.tags=JS
home.autoRedact.title=Caviarder automatiquement home.autoRedact.title=Caviarder automatiquement
home.autoRedact.desc=Caviardez automatiquement les informations sensibles dun PDF. home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
autoRedact.tags=caviarder,redact,auto autoRedact.tags=caviarder,redact,auto
home.tableExtraxt.title=PDF en CSV home.tableExtraxt.title=PDF en CSV
home.tableExtraxt.desc=Extrait les tableaux dun PDF et les transforme en CSV. home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
tableExtraxt.tags=CSV,Table Extraction,extract,convert tableExtraxt.tags=CSV, Extraction de table, extraction, conversion
home.autoSizeSplitPDF.title=Séparer automatiquement par taille/nombre home.autoSizeSplitPDF.title=Séparer automatiquement par taille/nombre
home.autoSizeSplitPDF.desc=Séparer un PDF unique en plusieurs documents en fonction de la taille, du nombre de pages ou du nombre de documents. home.autoSizeSplitPDF.desc=Séparer un PDF unique en plusieurs documents en fonction de la taille, du nombre de pages ou du nombre de documents.
autoSizeSplitPDF.tags=pdf,split,document,organization autoSizeSplitPDF.tags=pdf, découpage, document, organisation
home.overlay-pdfs.title=Incrustation de PDF home.overlay-pdfs.title=Incrustation de PDF
home.overlay-pdfs.desc=Incrustation dun PDF sur un autre PDF. home.overlay-pdfs.desc=Incrustation d'un PDF sur un autre PDF.
overlay-pdfs.tags=Overlay,incrustation overlay-pdfs.tags=Overlay,incrustation
home.split-by-sections.title=Séparer un PDF en sections home.split-by-sections.title=Séparer un PDF en sections
home.split-by-sections.desc=Diviser chaque page dun PDF en sections horizontales/verticales plus petites. home.split-by-sections.desc=Diviser chaque page d'un PDF en sections horizontales/verticales plus petites.
split-by-sections.tags=Sections,Diviser,Section Split, Divide, Customize split-by-sections.tags=Sections,Diviser,Section Split, Divide, Customize
home.AddStampRequest.title=Ajouter un tampon sur un PDF home.AddStampRequest.title=Ajouter un tampon sur un PDF
home.AddStampRequest.desc=Ajouter un texte ou limage dun tampon à un emplacement défini. home.AddStampRequest.desc=Ajouter un texte ou l'image d'un tampon à un emplacement défini.
AddStampRequest.tags=Tampon,Ajouter,Stamp,Add image,center image,Watermark,PDF,Embed,Customize AddStampRequest.tags=Tampon,Ajouter,Stamp,Add image,center image,Watermark,PDF,Embed,Customize
@@ -498,33 +503,33 @@ home.BookToPDF.title=eBook vers PDF
home.BookToPDF.desc=Convertit les formats de livres/bandes dessinées en PDF à l'aide de calibre home.BookToPDF.desc=Convertit les formats de livres/bandes dessinées en PDF à l'aide de calibre
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Supprimer les images
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Supprimez les images d'un PDF pour réduire sa taille
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Images,Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Séparer un PDF par chapitres
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Séparez un PDF en fichiers multiples en fonction de sa structure par chapitres.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=séparer,chapitres,split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Remplacer-Inverser-Couleur
replace-color.header=Replace-Invert Color PDF replace-color.header=Remplacer-Inverser Couleur PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Remplacer et Inverser Couleur
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Remplacer la couleur pour le texte et l'arrière-plan dans le PDF et inverser la couleur complète du PDF pour réduire la taille du fichier
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Remplacer Couleur,Opérations de Page,Back-end,Côté serveur
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Options de Remplacement ou d'Inversion de Couleur
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Par défaut (Couleurs à fort contraste par défaut)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Personnalisé (Couleurs personnalisées)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Inversion complète (Inverser toutes les couleurs)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Options de couleur à fort contraste
replace-color.selectText.6=white text on black background replace-color.selectText.6=Texte blanc sur fond noir
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Texte noir sur fond blanc
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Texte jaune sur fond noir
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Texte vert sur fond noir
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Choisir la couleur du texte
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Choisir la couleur de l'arrière-plan
replace-color.submit=Replace replace-color.submit=Remplacer
@@ -538,23 +543,22 @@ login.title=Connexion
login.header=Connexion login.header=Connexion
login.signin=Connexion login.signin=Connexion
login.rememberme=Se souvenir de moi login.rememberme=Se souvenir de moi
login.invalid=Nom dutilisateur ou mot de passe invalide. login.invalid=Nom d'utilisateur ou mot de passe invalide.
login.locked=Votre compte a été verrouillé. login.locked=Votre compte a été verrouillé.
login.signinTitle=Veuillez vous connecter login.signinTitle=Veuillez vous connecter
login.ssoSignIn=Se connecter via l'authentification unique login.ssoSignIn=Se connecter via l'authentification unique
login.oauth2AutoCreateDisabled=OAUTH2 Création automatique d'utilisateur désactivée login.oauth2AutoCreateDisabled=OAUTH2 Création automatique d'utilisateur désactivée
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=La création ou l'authentification d'utilisateurs non enregistrés est actuellement bloquée. Veuillez contacter l'administrateur.
login.oauth2RequestNotFound=Demande d'autorisation introuvable login.oauth2RequestNotFound=Demande d'autorisation introuvable
login.oauth2InvalidUserInfoResponse=Réponse contenant les informations de l'utilisateur est invalide login.oauth2InvalidUserInfoResponse=Réponse contenant les informations de l'utilisateur est invalide
login.oauth2invalidRequest=Requête invalide login.oauth2invalidRequest=Requête invalide
login.oauth2AccessDenied=Accès refusé login.oauth2AccessDenied=Accès refusé
login.oauth2InvalidTokenResponse=Réponse contenant le jeton est invalide login.oauth2InvalidTokenResponse=Réponse contenant le jeton est invalide
login.oauth2InvalidIdToken=Jeton d'identification invalide login.oauth2InvalidIdToken=Jeton d'identification invalide
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=L'utilisateur est désactivé, la connexion est actuellement bloquée avec ce nom d'utilisateur. Veuillez contacter l'administrateur.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Vous êtes déjà connecté sur
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=appareils. Veuillez vous déconnecter des appareils et réessayer.
login.toManySessions=You have too many active sessions login.toManySessions=Vous avez trop de sessions actives.
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Caviarder automatiquement autoRedact.title=Caviarder automatiquement
@@ -586,7 +590,7 @@ pdfToSinglePage.submit=Convertir en une seule page
pageExtracter.title=Extraire des pages pageExtracter.title=Extraire des pages
pageExtracter.header=Extraire des pages pageExtracter.header=Extraire des pages
pageExtracter.submit=Extraire pageExtracter.submit=Extraire
pageExtracter.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1) pageExtracter.placeholder=(par exemple : 1,2,8 ou 4,7,12-16 ou 2n-1)
#getPdfInfo #getPdfInfo
@@ -618,15 +622,15 @@ HTMLToPDF.header=HTML en PDF
HTMLToPDF.help=Accepte les fichiers HTML et les ZIP contenant du HTML, du CSS, des images, etc. (requis). HTMLToPDF.help=Accepte les fichiers HTML et les ZIP contenant du HTML, du CSS, des images, etc. (requis).
HTMLToPDF.submit=Convertir HTMLToPDF.submit=Convertir
HTMLToPDF.credit=Utilise WeasyPrint. HTMLToPDF.credit=Utilise WeasyPrint.
HTMLToPDF.zoom=Niveau de zoom pour laffichage du site web. HTMLToPDF.zoom=Niveau de zoom pour l'affichage du site web.
HTMLToPDF.pageWidth=Largeur de la page en centimètres. (Vide par défaut) HTMLToPDF.pageWidth=Largeur de la page en centimètres. (Vide par défaut)
HTMLToPDF.pageHeight=Hauteur de la page en centimètres. (Vide par défaut) HTMLToPDF.pageHeight=Hauteur de la page en centimètres. (Vide par défaut)
HTMLToPDF.marginTop=Marge supérieure de la page en millimètres. (Vide par défaut) HTMLToPDF.marginTop=Marge supérieure de la page en millimètres. (Vide par défaut)
HTMLToPDF.marginBottom=Marge inférieure de la page en millimètres. (Vide par défaut) HTMLToPDF.marginBottom=Marge inférieure de la page en millimètres. (Vide par défaut)
HTMLToPDF.marginLeft=Marge gauche de la page en millimètres. (Vide par défaut) HTMLToPDF.marginLeft=Marge gauche de la page en millimètres. (Vide par défaut)
HTMLToPDF.marginRight=Marge droite de la page en millimètres. (Vide par défaut) HTMLToPDF.marginRight=Marge droite de la page en millimètres. (Vide par défaut)
HTMLToPDF.printBackground=Restituer limage de fond des sites web. HTMLToPDF.printBackground=Restituer l'image de fond des sites web.
HTMLToPDF.defaultHeader=Activer lentête par défaut (Nom et numéro de page) HTMLToPDF.defaultHeader=Activer l'entête par défaut (Nom et numéro de page)
HTMLToPDF.cssMediaType=Modifier le type de média CSS de la page. HTMLToPDF.cssMediaType=Modifier le type de média CSS de la page.
HTMLToPDF.none=Aucun HTMLToPDF.none=Aucun
HTMLToPDF.print=Imprimer HTMLToPDF.print=Imprimer
@@ -704,7 +708,7 @@ autoSplitPDF.header=Séparer automatiquement les pages
autoSplitPDF.description=Imprimez, insérez, numérisez, téléchargez et laissez-nous séparer automatiquement vos documents. Aucun travail de tri manuel nécessaire. autoSplitPDF.description=Imprimez, insérez, numérisez, téléchargez et laissez-nous séparer automatiquement vos documents. Aucun travail de tri manuel nécessaire.
autoSplitPDF.selectText.1=Imprimez des feuilles de séparation ci-dessous (le mode noir et blanc convient). autoSplitPDF.selectText.1=Imprimez des feuilles de séparation ci-dessous (le mode noir et blanc convient).
autoSplitPDF.selectText.2=Numérisez tous vos documents en une seule fois en insérant les feuilles intercalaires entre eux. autoSplitPDF.selectText.2=Numérisez tous vos documents en une seule fois en insérant les feuilles intercalaires entre eux.
autoSplitPDF.selectText.3=Téléchargez le fichier PDF numérisé et laissez Stirling PDF soccuper du reste. autoSplitPDF.selectText.3=Téléchargez le fichier PDF numérisé et laissez Stirling PDF s'occuper du reste.
autoSplitPDF.selectText.4=Les feuilles de séparation sont automatiquement détectées et supprimées, garantissant un document final soigné. autoSplitPDF.selectText.4=Les feuilles de séparation sont automatiquement détectées et supprimées, garantissant un document final soigné.
autoSplitPDF.formPrompt=PDF contenant des feuilles de séparation de Stirling PDF : autoSplitPDF.formPrompt=PDF contenant des feuilles de séparation de Stirling PDF :
autoSplitPDF.duplexMode=Mode recto-verso autoSplitPDF.duplexMode=Mode recto-verso
@@ -726,11 +730,11 @@ pageLayout.submit=Fusionner
#scalePages #scalePages
scalePages.title=Ajuster la taille ou léchelle scalePages.title=Ajuster la taille ou l'échelle
scalePages.header=Ajuster la taille ou léchelle scalePages.header=Ajuster la taille ou l'échelle
scalePages.pageSize=Taille dune page du document scalePages.pageSize=Taille d'une page du document
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Taille d'origine
scalePages.scaleFactor=Niveau de zoom (recadrage) dune page scalePages.scaleFactor=Niveau de zoom (recadrage) d'une page
scalePages.submit=Ajuster scalePages.submit=Ajuster
@@ -738,10 +742,10 @@ scalePages.submit=Ajuster
certSign.title=Signer avec un certificat certSign.title=Signer avec un certificat
certSign.header=Signer avec un certificat (Travail en cours) certSign.header=Signer avec un certificat (Travail en cours)
certSign.selectPDF=PDF à signer certSign.selectPDF=PDF à signer
certSign.jksNote=Note: Si votre type de certificat nest pas listé ci-dessous, merci de le convertir en fichier Java Keystore (.jks) en utilisant loutil en ligne de commande keytool. Puis choisissez loption Fichier .jks ci-dessous. certSign.jksNote=Note: Si votre type de certificat n'est pas listé ci-dessous, merci de le convertir en fichier Java Keystore (.jks) en utilisant l'outil en ligne de commande keytool. Puis choisissez l'option Fichier .jks ci-dessous.
certSign.selectKey=Fichier de clé privée (format PKCS#8, peut être .pem ou .der) certSign.selectKey=Fichier de clé privée (format PKCS#8, peut être .pem ou .der)
certSign.selectCert=Fichier de certificat (format X.509, peut être .pem ou .der) certSign.selectCert=Fichier de certificat (format X.509, peut être .pem ou .der)
certSign.selectP12=Fichier keystore de clés PKCS#12 (.p12 ou .pfx) (facultatif, sil nest fourni, il doit contenir votre clé privée et votre certificat) certSign.selectP12=Fichier keystore de clés PKCS#12 (.p12 ou .pfx) (facultatif, s'il n'est fourni, il doit contenir votre clé privée et votre certificat)
certSign.selectJKS=Sélectionner votre fichier Java Keystore File (.jks or .keystore): certSign.selectJKS=Sélectionner votre fichier Java Keystore File (.jks or .keystore):
certSign.certType=Type de certificat certSign.certType=Type de certificat
certSign.password=Mot de passe keystore ou clé privée le cas échéant certSign.password=Mot de passe keystore ou clé privée le cas échéant
@@ -749,14 +753,15 @@ certSign.showSig=Afficher la signature
certSign.reason=Raison certSign.reason=Raison
certSign.location=Emplacement certSign.location=Emplacement
certSign.name=Nom certSign.name=Nom
certSign.showLogo=Afficher le logo
certSign.submit=Signer certSign.submit=Signer
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Supprimer la Signature de Certificat
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=Supprimer le certificat numérique du PDF
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=Sélectionnez un fichier PDF :
removeCertSign.submit=Remove Signature removeCertSign.submit=Supprimer la Signature
#removeBlanks #removeBlanks
@@ -778,23 +783,26 @@ removeAnnotations.submit=Supprimer
#compare #compare
compare.title=Comparer compare.title=Comparer
compare.header=Comparer compare.header=Comparer
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Couleur de mise en évidence 1 :
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Couleur de mise en évidence 2 :
compare.document.1=Document 1 compare.document.1=Document 1
compare.document.2=Document 2 compare.document.2=Document 2
compare.submit=Comparer compare.submit=Comparer
compare.complex.message=Un ou les deux documents fournis sont des fichiers volumineux, l'exactitude de la comparaison peut être réduite
compare.large.file.message=Un ou les deux documents fournis sont trop volumineux pour être traités
compare.no.text.message=L'un ou les deux documents PDF sélectionnés ne contiennent aucun contenu textuel. Veuillez choisir des documents PDF avec du texte pour la comparaison.
#BookToPDF #BookToPDF
BookToPDF.title=Livres et BD vers PDF BookToPDF.title=Livres et BD vers PDF
BookToPDF.header=Livre vers PDF BookToPDF.header=Livre vers PDF
BookToPDF.credit=Utiliser Calibre BookToPDF.credit=Utilise Calibre
BookToPDF.submit=Convertir BookToPDF.submit=Convertir
#PDFToBook #PDFToBook
PDFToBook.title=PDF vers Livre PDFToBook.title=PDF vers Livre
PDFToBook.header=PDF vers Livre PDFToBook.header=PDF vers Livre
PDFToBook.selectText.1=Format PDFToBook.selectText.1=Format
PDFToBook.credit=Utiliser Calibre PDFToBook.credit=Utilise Calibre
PDFToBook.submit=Convertir PDFToBook.submit=Convertir
#sign #sign
@@ -805,6 +813,11 @@ sign.draw=Dessiner une signature
sign.text=Saisir de texte sign.text=Saisir de texte
sign.clear=Effacer sign.clear=Effacer
sign.add=Ajouter sign.add=Ajouter
sign.saved=Saved Signatures
sign.save=Enregistrer le sceau
sign.personalSigs=Sceaux personnels
sign.sharedSigs=Sceaux partagés
sign.noSavedSigs=Aucun sceau enregistré trouvé
#repair #repair
@@ -822,16 +835,16 @@ flatten.submit=Rendre inerte
#ScannerImageSplit #ScannerImageSplit
ScannerImageSplit.selectText.1=Seuil de rotation ScannerImageSplit.selectText.1=Seuil de rotation
ScannerImageSplit.selectText.2=Définit langle absolu minimum requis pour la rotation de limage (par défaut : 10). ScannerImageSplit.selectText.2=Définit l'angle absolu minimum requis pour la rotation de l'image (par défaut : 10).
ScannerImageSplit.selectText.3=Tolérance ScannerImageSplit.selectText.3=Tolérance
ScannerImageSplit.selectText.4=Détermine la plage de variation de couleur autour de la couleur darrière-plan estimée (par défaut : 20). ScannerImageSplit.selectText.4=Détermine la plage de variation de couleur autour de la couleur d'arrière-plan estimée (par défaut : 20).
ScannerImageSplit.selectText.5=Surface minimale ScannerImageSplit.selectText.5=Surface minimale
ScannerImageSplit.selectText.6=Définit la surface minimale pour une photo (par défaut : 8000). ScannerImageSplit.selectText.6=Définit la surface minimale pour une photo (par défaut : 8000).
ScannerImageSplit.selectText.7=Surface de contour minimale ScannerImageSplit.selectText.7=Surface de contour minimale
ScannerImageSplit.selectText.8=Définit la surface de contour minimale pour une photo (par défaut : 500). ScannerImageSplit.selectText.8=Définit la surface de contour minimale pour une photo (par défaut : 500).
ScannerImageSplit.selectText.9=Taille de la bordure ScannerImageSplit.selectText.9=Taille de la bordure
ScannerImageSplit.selectText.10=Définit la taille de la bordure ajoutée et supprimée pour éviter les bordures blanches dans la sortie (par défaut : 1). ScannerImageSplit.selectText.10=Définit la taille de la bordure ajoutée et supprimée pour éviter les bordures blanches dans la sortie (par défaut : 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Python n'est pas installé. Il est nécessaire pour le fonctionnement.
#OCR #OCR
@@ -840,25 +853,25 @@ ocr.header=OCR (Reconnaissance optique de caractères) / Nettoyage des numérisa
ocr.selectText.1=Langues à détecter dans le PDF (celles listées sont celles actuellement détectées) ocr.selectText.1=Langues à détecter dans le PDF (celles listées sont celles actuellement détectées)
ocr.selectText.2=Produire un fichier texte contenant le texte détecté à côté du PDF ocr.selectText.2=Produire un fichier texte contenant le texte détecté à côté du PDF
ocr.selectText.3=Corriger les pages qui ont été numérisées à un angle oblique en les remettant en place ocr.selectText.3=Corriger les pages qui ont été numérisées à un angle oblique en les remettant en place
ocr.selectText.4=Nettoyer la page afin quil soit moins probable que lOCR trouve du texte dans le bruit de fond, sans modifier la sortie ocr.selectText.4=Nettoyer la page afin qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond, sans modifier la sortie
ocr.selectText.5=Nettoyer la page afin quil soit moins probable que lOCR trouve du texte dans le bruit de fond, en modifiant la sortie ocr.selectText.5=Nettoyer la page afin qu'il soit moins probable que l'OCR trouve du texte dans le bruit de fond, en modifiant la sortie
ocr.selectText.6=Ignorer les pages contenant du texte interactif, nanalyser que les pages qui sont des images ocr.selectText.6=Ignorer les pages contenant du texte interactif, n'analyser que les pages qui sont des images
ocr.selectText.7=Forcer lOCR, analyser chaque page et supprimer tous les éléments de texte dorigine ocr.selectText.7=Forcer l'OCR, analyser chaque page et supprimer tous les éléments de texte d'origine
ocr.selectText.8=Normal (génère une erreur si le PDF contient du texte) ocr.selectText.8=Normal (génère une erreur si le PDF contient du texte)
ocr.selectText.9=Paramètres additionnels ocr.selectText.9=Paramètres additionnels
ocr.selectText.10=Mode OCR ocr.selectText.10=Mode OCR
ocr.selectText.11=Supprimer les images après lOCR (Supprime TOUTES les images, utile uniquement si elles font partie de létape de conversion) ocr.selectText.11=Supprimer les images après l'OCR (Supprime TOUTES les images, utile uniquement si elles font partie de l'étape de conversion)
ocr.selectText.12=Type de rendu (avancé) ocr.selectText.12=Type de rendu (avancé)
ocr.help=Veuillez lire cette documentation pour savoir comment utiliser lOCR pour dautres langues ou une utilisation hors Docker : ocr.help=Veuillez lire cette documentation pour savoir comment utiliser l'OCR pour d'autres langues ou une utilisation hors Docker :
ocr.credit=Ce service utilise OCRmyPDF et Tesseract pour lOCR. ocr.credit=Ce service utilise OCRmyPDF et Tesseract pour l'OCR.
ocr.submit=Traiter ocr.submit=Traiter
#extractImages #extractImages
extractImages.title=Extraire les images extractImages.title=Extraire les images
extractImages.header=Extraire les images extractImages.header=Extraire les images
extractImages.selectText=Format dimage dans lequel convertir les images extraites extractImages.selectText=Format d'image dans lequel convertir les images extraites
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Enregistrer les images dupliquées
extractImages.submit=Extraire extractImages.submit=Extraire
@@ -873,10 +886,10 @@ fileToPDF.submit=Convertir
#compress #compress
compress.title=Compresser un PDF compress.title=Compresser un PDF
compress.header=Compresser un PDF (lorsque cest possible!) compress.header=Compresser un PDF (lorsque c'est possible!)
compress.credit=Ce service utilise Ghostscript pour la compression et loptimisation des PDF. compress.credit=Ce service utilise Ghostscript pour la compression et l'optimisation des PDF.
compress.selectText.1=Mode manuel de 1 à 4 compress.selectText.1=Mode manuel de 1 à 4
compress.selectText.2=Niveau doptimisation compress.selectText.2=Niveau d'optimisation
compress.selectText.3=4 (terrible pour les images textuelles) compress.selectText.3=4 (terrible pour les images textuelles)
compress.selectText.4=Mode automatique ajuste automatiquement la qualité pour obtenir le PDF à la taille exacte compress.selectText.4=Mode automatique ajuste automatiquement la qualité pour obtenir le PDF à la taille exacte
compress.selectText.5=Taille PDF attendue (par exemple, 25MB, 10,8MB, 25KB) compress.selectText.5=Taille PDF attendue (par exemple, 25MB, 10,8MB, 25KB)
@@ -896,7 +909,7 @@ merge.title=Fusionner
merge.header=Fusionner plusieurs PDF merge.header=Fusionner plusieurs PDF
merge.sortByName=Trier par nom merge.sortByName=Trier par nom
merge.sortByDate=Trier par date merge.sortByDate=Trier par date
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Supprimer la signature numérique dans le fichier fusionné ?
merge.submit=Fusionner merge.submit=Fusionner
@@ -914,14 +927,25 @@ pdfOrganiser.mode.6=Partage impair-pair
pdfOrganiser.mode.7=Supprimer le premier pdfOrganiser.mode.7=Supprimer le premier
pdfOrganiser.mode.8=Supprimer le dernier pdfOrganiser.mode.8=Supprimer le dernier
pdfOrganiser.mode.9=Supprimer le premier et le dernier pdfOrganiser.mode.9=Supprimer le premier et le dernier
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Méger Impair-Pair
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1) pdfOrganiser.placeholder=(par exemple 1,3,2 ou 4-8,2,10-12 ou 2n-1)
#multiTool #multiTool
multiTool.title=Outil multifonction PDF multiTool.title=Outil multifonction PDF
multiTool.header=Outil multifonction PDF multiTool.header=Outil multifonction PDF
multiTool.uploadPrompts=Nom du fichier multiTool.uploadPrompts=Nom du fichier
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Visualiser un PDF viewPdf.title=Visualiser un PDF
@@ -932,7 +956,7 @@ pageRemover.title=Supprimer des pages
pageRemover.header=Supprimer des pages pageRemover.header=Supprimer des pages
pageRemover.pagesToDelete=Pages à supprimer (entrez une liste de numéros de pages séparés par des virgules) : pageRemover.pagesToDelete=Pages à supprimer (entrez une liste de numéros de pages séparés par des virgules) :
pageRemover.submit=Supprimer les pages pageRemover.submit=Supprimer les pages
pageRemover.placeholder=(e.g. 1,2,6 or 1-10,15-30) pageRemover.placeholder=(par exemple 1,2,6 ou 1-10,15-30)
#rotate #rotate
@@ -961,9 +985,9 @@ split.submit=Diviser
imageToPDF.title=Image en PDF imageToPDF.title=Image en PDF
imageToPDF.header=Image en PDF imageToPDF.header=Image en PDF
imageToPDF.submit=Convertir imageToPDF.submit=Convertir
imageToPDF.selectLabel=Options dajustement de limage imageToPDF.selectLabel=Options d'ajustement de l'image
imageToPDF.fillPage=Remplir la page imageToPDF.fillPage=Remplir la page
imageToPDF.fitDocumentToImage=Ajuster la page à limage imageToPDF.fitDocumentToImage=Ajuster la page à l'image
imageToPDF.maintainAspectRatio=Maintenir les proportions imageToPDF.maintainAspectRatio=Maintenir les proportions
imageToPDF.selectText.2=Rotation automatique du PDF imageToPDF.selectText.2=Rotation automatique du PDF
imageToPDF.selectText.3=Logique multi-fichiers (uniquement activée si vous travaillez avec plusieurs images) imageToPDF.selectText.3=Logique multi-fichiers (uniquement activée si vous travaillez avec plusieurs images)
@@ -974,37 +998,37 @@ imageToPDF.selectText.5=Convertir en PDF séparés
#pdfToImage #pdfToImage
pdfToImage.title=Image en PDF pdfToImage.title=Image en PDF
pdfToImage.header=Image en PDF pdfToImage.header=Image en PDF
pdfToImage.selectText=Format dimage pdfToImage.selectText=Format d'image
pdfToImage.singleOrMultiple=Type de résultat pdfToImage.singleOrMultiple=Type de résultat
pdfToImage.single=Une seule grande image pdfToImage.single=Une seule grande image
pdfToImage.multi=Plusieurs images pdfToImage.multi=Plusieurs images
pdfToImage.colorType=Type dimpression pdfToImage.colorType=Type d'impression
pdfToImage.color=Couleur pdfToImage.color=Couleur
pdfToImage.grey=Niveaux de gris pdfToImage.grey=Niveaux de gris
pdfToImage.blackwhite=Noir et blanc (peut engendrer une perte de données !) pdfToImage.blackwhite=Noir et blanc (peut engendrer une perte de données !)
pdfToImage.submit=Convertir pdfToImage.submit=Convertir
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Python nest pas installé. Nécessaire pour la conversion WebP.
#addPassword #addPassword
addPassword.title=Ajouter un mot de passe addPassword.title=Ajouter un mot de passe
addPassword.header=Ajouter un mot de passe addPassword.header=Ajouter un mot de passe
addPassword.selectText.1=PDF à chiffrer addPassword.selectText.1=PDF à chiffrer
addPassword.selectText.2=Mot de passe de lutilisateur addPassword.selectText.2=Mot de passe de l'utilisateur
addPassword.selectText.3=Longueur de la clé de chiffrement addPassword.selectText.3=Longueur de la clé de chiffrement
addPassword.selectText.4=Les valeurs plus élevées sont plus fortes, mais les valeurs plus faibles ont une meilleure compatibilité. addPassword.selectText.4=Les valeurs plus élevées sont plus fortes, mais les valeurs plus faibles ont une meilleure compatibilité.
addPassword.selectText.5=Autorisations à définir (utilisation recommandée avec le mot de passe du propriétaire) addPassword.selectText.5=Autorisations à définir (utilisation recommandée avec le mot de passe du propriétaire)
addPassword.selectText.6=Empêcher lassemblage du document addPassword.selectText.6=Empêcher l'assemblage du document
addPassword.selectText.7=Empêcher lextraction de contenu addPassword.selectText.7=Empêcher l'extraction de contenu
addPassword.selectText.8=Empêcher lextraction pour laccessibilité addPassword.selectText.8=Empêcher l'extraction pour l'accessibilité
addPassword.selectText.9=Empêcher de remplir les formulaires addPassword.selectText.9=Empêcher de remplir les formulaires
addPassword.selectText.10=Empêcher la modification addPassword.selectText.10=Empêcher la modification
addPassword.selectText.11=Empêcher la modification des annotations addPassword.selectText.11=Empêcher la modification des annotations
addPassword.selectText.12=Empêcher limpression addPassword.selectText.12=Empêcher l'impression
addPassword.selectText.13=Empêcher limpression des différents formats addPassword.selectText.13=Empêcher l'impression des différents formats
addPassword.selectText.14=Mot de passe du propriétaire addPassword.selectText.14=Mot de passe du propriétaire
addPassword.selectText.15=Restreint ce qui peut être fait avec le document une fois quil est ouvert (non pris en charge par tous les lecteurs). addPassword.selectText.15=Restreint ce qui peut être fait avec le document une fois qu'il est ouvert (non pris en charge par tous les lecteurs).
addPassword.selectText.16=Restreint louverture du document lui-même. addPassword.selectText.16=Restreint l'ouverture du document lui-même.
addPassword.submit=Chiffrer addPassword.submit=Chiffrer
@@ -1020,9 +1044,9 @@ watermark.selectText.6=heightSpacer (espace entre chaque filigrane verticalement
watermark.selectText.7=Opacité (de 0% à 100%) watermark.selectText.7=Opacité (de 0% à 100%)
watermark.selectText.8=Type de filigrane watermark.selectText.8=Type de filigrane
watermark.selectText.9=Image du filigrane watermark.selectText.9=Image du filigrane
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=Convertir le PDF en PDF-Image
watermark.submit=Ajouter un filigrane watermark.submit=Ajouter un filigrane
watermark.type.1=Text watermark.type.1=Texte
watermark.type.2=Image watermark.type.2=Image
@@ -1032,14 +1056,14 @@ permissions.header=Modifier les permissions
permissions.warning=Attention, pour que ces permissions soient immuables il est recommandé de les paramétrer avec un mot de passe via la page Ajouter un mot de passe. permissions.warning=Attention, pour que ces permissions soient immuables il est recommandé de les paramétrer avec un mot de passe via la page Ajouter un mot de passe.
permissions.selectText.1=Sélectionnez le PDF permissions.selectText.1=Sélectionnez le PDF
permissions.selectText.2=Permissions à définir permissions.selectText.2=Permissions à définir
permissions.selectText.3=Empêcher lassemblage du document permissions.selectText.3=Empêcher l'assemblage du document
permissions.selectText.4=Empêcher lextraction de contenu permissions.selectText.4=Empêcher l'extraction de contenu
permissions.selectText.5=Empêcher lextraction pour laccessibilité permissions.selectText.5=Empêcher l'extraction pour l'accessibilité
permissions.selectText.6=Empêcher de remplir les formulaires permissions.selectText.6=Empêcher de remplir les formulaires
permissions.selectText.7=Empêcher la modification permissions.selectText.7=Empêcher la modification
permissions.selectText.8=Empêcher la modification des annotations permissions.selectText.8=Empêcher la modification des annotations
permissions.selectText.9=Empêcher limpression permissions.selectText.9=Empêcher l'impression
permissions.selectText.10=Empêcher limpression des différents formats permissions.selectText.10=Empêcher l'impression des différents formats
permissions.submit=Modifier permissions.submit=Modifier
@@ -1064,7 +1088,7 @@ changeMetadata.keywords=Mots clés
changeMetadata.modDate=Date de modification (yyyy/MM/dd HH:mm:ss) changeMetadata.modDate=Date de modification (yyyy/MM/dd HH:mm:ss)
changeMetadata.producer=Producteur changeMetadata.producer=Producteur
changeMetadata.subject=Sujet changeMetadata.subject=Sujet
changeMetadata.trapped=Recouvrement (technique dimpression) changeMetadata.trapped=Recouvrement (technique d'impression)
changeMetadata.selectText.4=Autres métadonnées changeMetadata.selectText.4=Autres métadonnées
changeMetadata.selectText.5=Ajouter une entrée de métadonnées personnalisée changeMetadata.selectText.5=Ajouter une entrée de métadonnées personnalisée
changeMetadata.submit=Modifier changeMetadata.submit=Modifier
@@ -1077,7 +1101,7 @@ pdfToPDFA.credit=Ce service utilise ghostscript pour la conversion en PDF/A.
pdfToPDFA.submit=Convertir pdfToPDFA.submit=Convertir
pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois
pdfToPDFA.outputFormat=Format de sortie pdfToPDFA.outputFormat=Format de sortie
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=Le PDF contient une signature numérique. Elle sera supprimée dans l'étape suivante.
#PDFToWord #PDFToWord
@@ -1139,13 +1163,13 @@ split-by-size-or-count.submit=Séparer
overlay-pdfs.header=Incrustation de PDF overlay-pdfs.header=Incrustation de PDF
overlay-pdfs.baseFile.label=Sélectionner le fichier PDF de base overlay-pdfs.baseFile.label=Sélectionner le fichier PDF de base
overlay-pdfs.overlayFiles.label=Sélectionner les fichiers PDF à superposer overlay-pdfs.overlayFiles.label=Sélectionner les fichiers PDF à superposer
overlay-pdfs.mode.label=Sélectionner le mode dincrustation overlay-pdfs.mode.label=Sélectionner le mode d'incrustation
overlay-pdfs.mode.sequential=Superposition séquentielle overlay-pdfs.mode.sequential=Superposition séquentielle
overlay-pdfs.mode.interleaved=Superposition entrelacée overlay-pdfs.mode.interleaved=Superposition entrelacée
overlay-pdfs.mode.fixedRepeat=Superposition à répétition fixe overlay-pdfs.mode.fixedRepeat=Superposition à répétition fixe
overlay-pdfs.counts.label=Nombre de superpositions (pour le mode de répétition fixe) overlay-pdfs.counts.label=Nombre de superpositions (pour le mode de répétition fixe)
overlay-pdfs.counts.placeholder=Compteurs (séparés par des virgules, exemple : 2,3,1) overlay-pdfs.counts.placeholder=Compteurs (séparés par des virgules, exemple : 2,3,1)
overlay-pdfs.position.label=Définir la position de lincrustation overlay-pdfs.position.label=Définir la position de l'incrustation
overlay-pdfs.position.foreground=Premier plan overlay-pdfs.position.foreground=Premier plan
overlay-pdfs.position.background=Arrière-plan overlay-pdfs.position.background=Arrière-plan
overlay-pdfs.submit=Soumettre overlay-pdfs.submit=Soumettre
@@ -1179,47 +1203,45 @@ licenses.version=Version
licenses.license=Licence licenses.license=Licence
#survey #survey
survey.nav=Survey survey.nav=Enquête
survey.title=Stirling-PDF Survey survey.title=Enquête Stirling-PDF
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF n'a pas de suivi, donc nous voulons entendre nos utilisateurs pour améliorer Stirling-PDF !
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF a changé depuis la dernière enquête ! Pour en savoir plus, veuillez consulter notre article de blog ici :
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Avec ces changements, nous obtenons un soutien commercial rémunéré et un financement
survey.please=Please consider taking our survey! survey.please=Veuillez envisager de répondre à notre enquête !
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(La fenêtre contextuelle de l'enquête sera désactivée dans les mises à jour suivantes mais sera disponible en bas de page)
survey.button=Take Survey survey.button=Répondre à l'enquête
survey.dontShowAgain=Don't show again survey.dontShowAgain=Ne plus afficher
#error #error
error.sorry=Désolé pour ce problème ! error.sorry=Désolé pour ce problème !
error.needHelp=Besoin daide / Vous avez trouvé un problème ? error.needHelp=Besoin d'aide / Vous avez trouvé un problème ?
error.contactTip=Si vous avez encore des problèmes, nhésitez pas à nous contacter pour obtenir de laide. Vous pouvez soumettre un ticket sur notre page GitHub ou nous contacter via Discord : error.contactTip=Si vous avez encore des problèmes, n'hésitez pas à nous contacter pour obtenir de l'aide. Vous pouvez soumettre un ticket sur notre page GitHub ou nous contacter via Discord :
error.404.head=404 - Page non trouvée | oups on sest foiré ! error.404.head=404 - Page non trouvée | oups on s'est foiré !
error.404.1=Nous ne parvenons pas à trouver la page que vous recherchez. error.404.1=Nous ne parvenons pas à trouver la page que vous recherchez.
error.404.2=Quelque chose na pas fonctionné error.404.2=Quelque chose n'a pas fonctionné
error.github=Créer un ticket sur GitHub error.github=Créer un ticket sur GitHub
error.showStack=Afficher la Stack Trace error.showStack=Afficher la Stack Trace
error.copyStack=Copier la Stack Trace error.copyStack=Copier la Stack Trace
error.githubSubmit=GitHub - Créer un ticket error.githubSubmit=GitHub - Créer un ticket
error.discordSubmit=Discord - Poster un message de demande dassistance error.discordSubmit=Discord - Poster un message de demande d'assistance
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Supprimer l'image
removeImage.header=Remove image removeImage.header=Supprimer l'image
removeImage.removeImage=Remove image removeImage.removeImage=Supprimer l'image
removeImage.submit=Remove image removeImage.submit=Supprimer l'image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=Diviser un PDF par Chapitres
splitByChapters.header=Diviser un PDF par Chapitres
splitByChapters.bookmarkLevel=Niveau de Signet
splitByChapters.includeMetadata=Inclure les Métadonnées
splitByChapters.allowDuplicates=Autoriser les Doublons
splitByChapters.desc.1=Cet outil divise un fichier PDF en plusieurs PDF en fonction de sa structure de chapitres.
splitByChapters.desc.2=Niveau de Signet : Choisissez le niveau de signets à utiliser pour la division (0 pour le niveau supérieur, 1 pour le deuxième niveau, etc...).
splitByChapters.desc.3=Inclure les Métadonnées : Si coché, les métadonnées du PDF original seront incluses dans chaque PDF divisé.
splitByChapters.desc.4=Autoriser les Doublons : Si coché, permet à plusieurs signets sur la même page de créer des PDF séparés.
splitByChapters.submit=Diviser le PDF

View File

@@ -79,6 +79,9 @@ info=Eolas
pro=Pro pro=Pro
page=Page page=Page
pages=Pages pages=Pages
loading=Loading...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Privacy Policy
legal.terms=Terms and Conditions legal.terms=Terms and Conditions
@@ -139,6 +142,7 @@ navbar.language=Teangacha
navbar.settings=Socruithe navbar.settings=Socruithe
navbar.allTools=Uirlisí navbar.allTools=Uirlisí
navbar.multiTool=Uirlisí Il navbar.multiTool=Uirlisí Il
navbar.search=Search
navbar.sections.organize=Eagraigh navbar.sections.organize=Eagraigh
navbar.sections.convertTo=Tiontaigh go PDF navbar.sections.convertTo=Tiontaigh go PDF
navbar.sections.convertFrom=Tiontaigh ó PDF navbar.sections.convertFrom=Tiontaigh ó PDF
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
database.failedImportFile=Theip ar iompórtáil an chomhaid database.failedImportFile=Theip ar iompórtáil an chomhaid
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -554,7 +559,6 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@@ -749,6 +753,7 @@ certSign.showSig=Taispeáin Síniú
certSign.reason=Cúis certSign.reason=Cúis
certSign.location=Suíomh certSign.location=Suíomh
certSign.name=Ainm certSign.name=Ainm
certSign.showLogo=Show Logo
certSign.submit=Sínigh PDF certSign.submit=Sínigh PDF
@@ -783,6 +788,9 @@ compare.highlightColor.2=Dath Aibhsithe 2:
compare.document.1=Doiciméad 1 compare.document.1=Doiciméad 1
compare.document.2=Doiciméad 2 compare.document.2=Doiciméad 2
compare.submit=Déan comparáid idir compare.submit=Déan comparáid idir
compare.complex.message=One or both of the provided documents are large files, accuracy of comparison may be reduced
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=One or both of the selected PDFs have no text content. Please choose PDFs with text for comparison.
#BookToPDF #BookToPDF
BookToPDF.title=Leabhair agus comics a PDF BookToPDF.title=Leabhair agus comics a PDF
@@ -805,6 +813,11 @@ sign.draw=Tarraing Síniú
sign.text=Ionchur Téacs sign.text=Ionchur Téacs
sign.clear=Glan sign.clear=Glan
sign.add=Cuir sign.add=Cuir
sign.saved=Saved Signatures
sign.save=Save Signature
sign.personalSigs=Personal Signatures
sign.sharedSigs=Shared Signatures
sign.noSavedSigs=No saved signatures found
#repair #repair
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(m.sh. 1,3,2 nó 4-8,2,10-12 nó 2n-1)
multiTool.title=Il-uirlis PDF multiTool.title=Il-uirlis PDF
multiTool.header=Il-uirlis PDF multiTool.header=Il-uirlis PDF
multiTool.uploadPrompts=Ainm comhaid multiTool.uploadPrompts=Ainm comhaid
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Féach PDF viewPdf.title=Féach PDF
@@ -1221,5 +1245,3 @@ splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF splitByChapters.submit=Split PDF

View File

@@ -12,17 +12,17 @@ imgPrompt=छवियों का चयन करें
genericSubmit=प्रस्तुत करें genericSubmit=प्रस्तुत करें
processTimeWarning=चेतावनी: यह प्रक्रिया फ़ाइल के आकार पर निर्भर करती है और यह से एक मिनट तक लग सकती है processTimeWarning=चेतावनी: यह प्रक्रिया फ़ाइल के आकार पर निर्भर करती है और यह से एक मिनट तक लग सकती है
pageOrderPrompt=कस्टम पेज क्रम (पेज नंबरों या 2n+1 जैसे कार्यों की एक कॉमा से अलग-अलग सूची दर्ज करें): pageOrderPrompt=कस्टम पेज क्रम (पेज नंबरों या 2n+1 जैसे कार्यों की एक कॉमा से अलग-अलग सूची दर्ज करें):
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) : pageSelectionPrompt=कस्तम पेज चयन (पेज संख्याओं 1,5,6 या फंक्शन 2n+1 को अलग-अलग बैरीज़ में लिखिए) :
goToPage=जाएँ goToPage=जाएँ
true=सही true=सही
false=गलत false=गलत
unknown=अज्ञात unknown=अज्ञात
save=सहेजें save=सहेजें
saveToBrowser=Save to Browser saveToBrowser=ब्राउझर में सहमत करें
close=बंद करें close=बंद करें
filesSelected=फ़ाइलें चयनित हैं filesSelected=फ़ाइलें चयनित हैं
noFavourites=कोई पसंदीदा जोड़ा नहीं गया है noFavourites=कोई पसंदीदा जोड़ा नहीं गया है
downloadComplete=Download Complete downloadComplete=डाउनलोड पूरा हुआ
bored=बोर हो रहे हैं? bored=बोर हो रहे हैं?
alphabet=वर्णमाला alphabet=वर्णमाला
downloadPdf=पीडीएफ़ डाउनलोड करें downloadPdf=पीडीएफ़ डाउनलोड करें
@@ -46,89 +46,92 @@ red=लाल
green=हरा green=हरा
blue=नीला blue=नीला
custom=कस्टम... custom=कस्टम...
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems! WorkInProgess=कार्य चल रहा है, ये लगभग कार्य कर सकते हैं या फ़ौल बिजी में हो सकते हैं, किसी समस्या का पता लगाने के लिए कृपया रिपोर्ट करें!
poweredBy=Powered by poweredBy=बलिदान की स्वामित्व
yes=Yes yes=हा
no=No no=नहीं
changedCredsMessage=क्रेडेंशियल्स बदल दी गईं! changedCredsMessage=क्रेडेंशियल्स बदल दी गईं!
notAuthenticatedMessage=उपयोगकर्ता प्रमाणित नहीं है। notAuthenticatedMessage=उपयोगकर्ता प्रमाणित नहीं है।
userNotFoundMessage=उपयोगकर्ता नहीं मिला। userNotFoundMessage=उपयोगकर्ता नहीं मिला।
incorrectPasswordMessage=वर्तमान पासवर्ड गलत है। incorrectPasswordMessage=वर्तमान पासवर्ड गलत है।
usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है। usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है।
invalidUsernameMessage=Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address. invalidUsernameMessage=अवैध उपयोगकर्ता नाम, उपयोगकर्ता नाम केवल अक्षर, संख्या और इन प्रतिकरणों @._+- में ही शामिल हो सकते हैं या एक बिल्ड-आउट वैध ईमेल एड्रेस के रूप में होना चाहिए।
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=पासवर्ड खाली नहीं हो सकता है और इसमें शुरुआत या अंत में अज्ञात अंदाज के विच्छेदन नहीं हो सकते।
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=नया पासवर्ड और पुष्टि नया पासवर्ड मेल खाते हैं।
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=प्रसिद्धिगत उपयोगकर्ता को नहीं हटा सकते हैं।
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=उपयोगकर्ता नाम मौजूद नहीं है और नहीं हटा सकता है।
downgradeCurrentUserMessage=मौजूदा यूज़र की भूमिका को डाउनग्रेड नहीं किया जा सकता downgradeCurrentUserMessage=मौजूदा यूज़र की भूमिका को डाउनग्रेड नहीं किया जा सकता
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=वर्तमान उपयोगकर्ता निषेध किया गया है।
downgradeCurrentUserLongMessage=मौजूदा यूज़र की भूमिका को डाउनग्रेड नहीं किया जा सकता। इसलिए, वर्तमान उपयोगकर्ता को नहीं दिखाया जाएगा। downgradeCurrentUserLongMessage=मौजूदा यूज़र की भूमिका को डाउनग्रेड नहीं किया जा सकता। इसलिए, वर्तमान उपयोगकर्ता को नहीं दिखाया जाएगा।
userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user. userAlreadyExistsOAuthMessage=उपयोगकर्ता ऑटहॉराइजेशन 2 से वास्तविक में मौजूद है।
userAlreadyExistsWebMessage=The user already exists as an web user. userAlreadyExistsWebMessage=उपयोगकर्ता वेब से राजीव में मौजूद है।
error=Error error=मुश्किल
oops=Oops! oops=ओह!
help=Help help=सहायता
goHomepage=Go to Homepage goHomepage=主页前往
joinDiscord=Join our Discord server joinDiscord=हमारे Discord सर्वर में शामिल होना
seeDockerHub=See Docker Hub seeDockerHub=Docker Hub पर देखें
visitGithub=Visit Github Repository visitGithub=गिटहब को दृश्यकरण करें
donate=Donate donate=दान करें
color=Color color=रंग
sponsor=Sponsor sponsor=पatreon से पोर्टन
info=Info info=सूचना
pro=Pro pro=कॉलेजीय
page=पृष्ठ page=पृष्ठ
pages=पृष्ठों pages=पृष्ठों
loading=डालिंग...
addToDoc=Add to Document
reset=Reset
legal.privacy=Privacy Policy legal.privacy=गुप्तता सूचना
legal.terms=Terms and Conditions legal.terms=शर्तें और प्रवाह
legal.accessibility=Accessibility legal.accessibility=कारणीबिलिटी
legal.cookie=Cookie Policy legal.cookie=कुकीज़ नीति
legal.impressum=Impressum legal.impressum=प्रेरणा
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Beta) pipeline.header=पाइपलाइन सूची (बेटा)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=व्यक्तिगत अपलोड
pipeline.configureButton=Configure pipeline.configureButton=संरचना करें
pipeline.defaultOption=Custom pipeline.defaultOption=कसरत की शुल्क
pipeline.submitButton=Submit pipeline.submitButton=प्रविष्टि
pipeline.help=Pipeline Help pipeline.help=पाइपलाइन मदद
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=फोल्डर स्फॅं जस्त्र मदद
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=कि आपकी है पाइपलाइन का हटाना करना चाहते हैं?
###################### ######################
# Pipeline Options # # Pipeline Options #
###################### ######################
pipelineOptions.header=Pipeline Configuration pipelineOptions.header=पाइपलाइन संरचना
pipelineOptions.pipelineNameLabel=Pipeline Name pipelineOptions.pipelineNameLabel=पाइपलाइन का नाम
pipelineOptions.saveSettings=Save Operation Settings pipelineOptions.saveSettings=कार्यक्रम सेटिंग्स संरक्षण
pipelineOptions.pipelineNamePrompt=Enter pipeline name here pipelineOptions.pipelineNamePrompt=यहाँ पाइपलाइन का नाम दर्ज करें
pipelineOptions.selectOperation=Select Operation pipelineOptions.selectOperation=कार्य चुनें
pipelineOptions.addOperationButton=Add operation pipelineOptions.addOperationButton=कार्य जोड़ें
pipelineOptions.pipelineHeader=Pipeline: pipelineOptions.pipelineHeader=पाइपलाइन:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=डाउनलोड
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=सुविधा परीक्षण
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=प्रो के लिए अदायगी में तहत तुलना करें
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=यह संभावना केवल प्रो उपयोगकर्ताओं के लिए उपलब्ध है।
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=स्टीरिंग पीडीऍफ़ प्रो यॅमल संरचना फाइलें और अन्य SSO सुविधाओं का समर्थन करता है।
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=सामान्य प्रबंधन विशेषताएं खोजने के लिए स्टीरिंग पीडीऍफ़ प्रो का परीक्षण करें
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=स्टीरिंग पीडीऍफ़ को बेहतर करने में मदद करना चाहते हैं?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=स्टीरिंग पीडीऍफ़ मध्यम सुनिश्चित है जो हमें उपलब्ध कराता है और उत्पाद को बेहतर करने में मदद करता है। हम किसी प्रकार का व्यक्तिगत जानकारी या फ़ाइल सामग्रियों का ट्रॅक नहीं करते हैं।
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=मांगित गर्न मा, कैनलीस-पडफको सुधार बढाउने मदत गर्न माफि गर्ने प्रयोगकर्ताको समजलाई समज्दा परिवर्तनले मदत गर्न सकिँदू।
analytics.enable=Enable analytics analytics.enable=कैनलीस खुलाउँछु
analytics.disable=Disable analytics analytics.disable=कैनलीस बुझाउँछु
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=परिष्कार संपर्कमा कैनलीस सेटिङहरू परिवर्तन गर्न सकिँदू
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=भाषा
navbar.settings=सेटिंग्स navbar.settings=सेटिंग्स
navbar.allTools=साधन navbar.allTools=साधन
navbar.multiTool=विभिन्न साधन navbar.multiTool=विभिन्न साधन
navbar.search=Search
navbar.sections.organize=संगठित करें navbar.sections.organize=संगठित करें
navbar.sections.convertTo=पीडीएफ में कनवर्ट करें navbar.sections.convertTo=पीडीएफ में कनवर्ट करें
navbar.sections.convertFrom=पीडीएफ से कनवर्ट करें navbar.sections.convertFrom=पीडीएफ से कनवर्ट करें
navbar.sections.security=संकेत और सुरक्षा navbar.sections.security=संकेत और सुरक्षा
navbar.sections.advance=उन्नत navbar.sections.advance=उन्नत
navbar.sections.edit=देखें और संपादित करें navbar.sections.edit=देखें और संपादित करें
navbar.sections.popular=Popular navbar.sections.popular=यादृच्छिको
############# #############
# SETTINGS # # SETTINGS #
@@ -161,13 +165,13 @@ settings.downloadOption.3=फ़ाइल डाउनलोड करें
settings.zipThreshold=जब डाउनलोड की गई फ़ाइलों की संख्या सीमा से अधिक हो settings.zipThreshold=जब डाउनलोड की गई फ़ाइलों की संख्या सीमा से अधिक हो
settings.signOut=साइन आउट settings.signOut=साइन आउट
settings.accountSettings=खाता सेटिंग्स settings.accountSettings=खाता सेटिंग्स
settings.bored.help=Enables easter egg game settings.bored.help=बालाची खुशाखुशी गेम सक्रिय गर्ने आवकता
settings.cacheInputs.name=Save form inputs settings.cacheInputs.name=पहिलो इनपुटहरू बंदरगाहमा राख्न
settings.cacheInputs.help=Enable to store previously used inputs for future runs settings.cacheInputs.help=क्रियाकलापको पारित कर्मचारी भेट्दा पूर्ववार उपयोग मा लगाएको इनपुटहरू बंदरगाहमा संग्रहित गर्ने आवकता
changeCreds.title=क्रेडेंशियल बदलें changeCreds.title=क्रेडेंशियल बदलें
changeCreds.header=अपना खाता विवरण अपडेट करें changeCreds.header=अपना खाता विवरण अपडेट करें
changeCreds.changePassword=You are using default login credentials. Please enter a new password changeCreds.changePassword=सुरक्षित पासワर्ड वापर्ने बदल्नु हो
changeCreds.newUsername=नया उपयोगकर्ता नाम changeCreds.newUsername=नया उपयोगकर्ता नाम
changeCreds.oldPassword=वर्तमान पासवर्ड changeCreds.oldPassword=वर्तमान पासवर्ड
changeCreds.newPassword=नया पासवर्ड changeCreds.newPassword=नया पासवर्ड
@@ -202,25 +206,25 @@ adminUserSettings.header=व्यवस्थापक उपयोगकर्
adminUserSettings.admin=व्यवस्थापक adminUserSettings.admin=व्यवस्थापक
adminUserSettings.user=उपयोगकर्ता adminUserSettings.user=उपयोगकर्ता
adminUserSettings.addUser=नया उपयोगकर्ता जोड़ें adminUserSettings.addUser=नया उपयोगकर्ता जोड़ें
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=उपयोगकर्ता छुट्टी देनु
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=उपयोगकर्ताको छुट्टी दिइने सँचार हुनुपछै अनुमति दिन्‍दै लागि पुष्टि गर्नुहोस्
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=उपयोगकर्ताको स्थिरपद्धति परिवर्तनले पुष्टि गर्नुहोस्‍
adminUserSettings.usernameInfo=Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address. adminUserSettings.usernameInfo=उपयोगकर्ता नाममा केही संख्या, क्रतिका र अगले पूर्णाङ्क @._+- मा जस्ता विशेष चिह्नहरू छुन्न सकिँदू उपयोगकर्ता नामले एक संधारणीय पत्रक्याले बनाइएच।
adminUserSettings.roles=रोल्स adminUserSettings.roles=रोल्स
adminUserSettings.role=रोल adminUserSettings.role=रोल
adminUserSettings.actions=क्रियाएँ adminUserSettings.actions=क्रियाएँ
adminUserSettings.apiUser=सीमित API उपयोगकर्ता adminUserSettings.apiUser=सीमित API उपयोगकर्ता
adminUserSettings.extraApiUser=Additional Limited API User adminUserSettings.extraApiUser=अतिरिक्त सीमित API उपयोगकर्ता
adminUserSettings.webOnlyUser=केवल वेब उपयोगकर्ता adminUserSettings.webOnlyUser=केवल वेब उपयोगकर्ता
adminUserSettings.demoUser=Demo User (No custom settings) adminUserSettings.demoUser=विनंति उपयोगकर्ता (स्वामित्व अनुकूली)
adminUserSettings.internalApiUser=Internal API User adminUserSettings.internalApiUser=अन्तराल API उपयोगकर्ता
adminUserSettings.forceChange=उपयोगकर्ता को लॉगिन पर उपयोगकर्ता नाम/पासवर्ड बदलने के लिए मजबूर करें adminUserSettings.forceChange=उपयोगकर्ता को लॉगिन पर उपयोगकर्ता नाम/पासवर्ड बदलने के लिए मजबूर करें
adminUserSettings.submit=उपयोगकर्ता को सहेजें adminUserSettings.submit=उपयोगकर्ता को सहेजें
adminUserSettings.changeUserRole=यूज़र की भूमिका बदलें adminUserSettings.changeUserRole=यूज़र की भूमिका बदलें
adminUserSettings.authenticated=Authenticated adminUserSettings.authenticated=मान्यताप्राप्त
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=आफु प्रोफाइल संपादन गर्नुहोस्
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=कार्यक्षम उपयोगकर्ता
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=अकार्यक्षम उपयोगकर्ता
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Active Users:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Disabled Users:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Total Users:
@@ -244,6 +248,7 @@ database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Your session has expired. Please refresh the page and try again.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -485,46 +490,46 @@ home.split-by-sections.title=खंडों से पीडीएफ़ वि
home.split-by-sections.desc=पीडीएफ़ के प्रत्येक पृष्ठ को छोटे से छोटे क्षैतिज और ऊर्ध्वाधर खंडों में विभाजित करें home.split-by-sections.desc=पीडीएफ़ के प्रत्येक पृष्ठ को छोटे से छोटे क्षैतिज और ऊर्ध्वाधर खंडों में विभाजित करें
split-by-sections.tags=खंड विभाजन, विभाजित करें, अनुकूलित split-by-sections.tags=खंड विभाजन, विभाजित करें, अनुकूलित
home.AddStampRequest.title=Add Stamp to PDF home.AddStampRequest.title=PDF में स्पष्ट रंग जोड़ें
home.AddStampRequest.desc=Add text or add image stamps at set locations home.AddStampRequest.desc=साहित्य पुनर्व्यवस्थित करें या निर्धारित स्थानों पर चित्र लक्षण जोड़ें
AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize
home.PDFToBook.title=PDF to Book home.PDFToBook.title=PDF से बुक
home.PDFToBook.desc=Converts PDF to Book/Comic formats using calibre home.PDFToBook.desc=Calibre का उपयोग करके PDF को बुक/कमिक्स फॉर्मेट में परिवर्तित करें
PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.BookToPDF.title=Book to PDF home.BookToPDF.title=बुक से PDF
home.BookToPDF.desc=Converts Books/Comics formats to PDF using calibre home.BookToPDF.desc=Calibre का उपयोग करके Books/Comics फॉर्मेट को PDF में परिवर्तित करें
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=चित्र हटाएं
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=PDF से चित्र हटा कर फाइल आकार को कम करें
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=चित्र हटाएं,पृष्ठ ऑपरेशन्स,बाकी सिड,सर्वर साइड
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=अध्यायों पर अलग-करें
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=पुस्तक के अध्याय की संरचना पर आधारित एक PDF को बहिन-भागों में विभाजित करें
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=विभाजन,अध्याय,पसंदीदा,रजैत
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=चित्र रंग परिवर्तन/उलटकर परिवर्तन PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=PDF में टेक्स्ट और पैरासेमा के लिए रंग परिवर्तन करें और पूरी फोटो उलटकर परिवर्तन करें जो कि फाइल आकार को कम करें
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=रंग परिवर्तन,पृष्ठ ऑपरेशन्स,बाकी सिड,सर्वर साइड
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=रंग परिवर्तन/उलटकर परिवर्तन विकल्प
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=वैश्विक(वैश्विक उच्च अंतराल रंग)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=स्वतन्त्र(आम रंग)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=सार्वभौमिक-क्रमांतरण(सभी रंगों को आलवा करें)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=कुछ तृvigya रंग विकल्प
replace-color.selectText.6=white text on black background replace-color.selectText.6=गायन उपरि पीक मैदान पर काला अवलोकन
replace-color.selectText.7=Black text on white background replace-color.selectText.7=काले उपरि काला रेखा
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=काले उपरि काला मैदान पर सफ़ेद अवलोकन
replace-color.selectText.9=Green text on black background replace-color.selectText.9=काले उपरि काला मैदान पर हियंग अवलोकन
replace-color.selectText.10=Choose text Color replace-color.selectText.10=याद की जाने वाली रेखा चुनें
replace-color.selectText.11=Choose background Color replace-color.selectText.11=पौधा उपरि पीक मैदान चुनें
replace-color.submit=Replace replace-color.submit=बदलें
@@ -543,18 +548,17 @@ login.locked=आपका खाता लॉक कर दिया गया
login.signinTitle=कृपया साइन इन करें login.signinTitle=कृपया साइन इन करें
login.ssoSignIn=सिंगल साइन - ऑन के ज़रिए लॉग इन करें login.ssoSignIn=सिंगल साइन - ऑन के ज़रिए लॉग इन करें
login.oauth2AutoCreateDisabled=OAUTH2 ऑटो - क्रिएट यूज़र अक्षम किया गया login.oauth2AutoCreateDisabled=OAUTH2 ऑटो - क्रिएट यूज़र अक्षम किया गया
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=व्यक्तिगत नहीं की रजिस्टर या लॉग-इन वर्षा माह प्रतिबंधित है। कृपया संबवादक से संपर्क करें.
login.oauth2RequestNotFound=Authorization request not found login.oauth2RequestNotFound=स्वीकारोचा याचना मिल नहीं रही
login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2InvalidUserInfoResponse=अमान्तरित प्रकाशीय जानकारी संदेश कैसे है
login.oauth2invalidRequest=Invalid Request login.oauth2invalidRequest=गलत याचना
login.oauth2AccessDenied=Access Denied login.oauth2AccessDenied=इनपुट उम्मीदवार डिसकार
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=अमान्तरित सिक्वेंस जवाब कैसे है
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=गलत इड टोकन
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=उपयोगकर्ता डिसबाल, यह वर्षा सभी उपयोगकर्ता जूझे वर्षाकरण बारा मिल गई है। कृपया संबवादक से संपर्क करें.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=आप पहले से ही
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=सुनिश्चित करने वाले डिवाइस्स पर लॉग-इन हैं। कृपया इन डिवाइस से लॉगआउट करें और पुनः प्रयास करें
login.toManySessions=You have too many active sessions login.toManySessions=आपके अधिक संख्या में विदीश हो रहे हैं
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=स्वत: गोपनीयकरण autoRedact.title=स्वत: गोपनीयकरण
@@ -586,7 +590,7 @@ pdfToSinglePage.submit=एकल पृष्ठ में परिवर्त
pageExtracter.title=पृष्ठों को निकालें pageExtracter.title=पृष्ठों को निकालें
pageExtracter.header=पृष्ठों को निकालें pageExtracter.header=पृष्ठों को निकालें
pageExtracter.submit=निकालें pageExtracter.submit=निकालें
pageExtracter.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1) pageExtracter.placeholder=(उदाहरण के लिए 1,2,8 या 4,7,12-16 या 2n-1)
#getPdfInfo #getPdfInfo
@@ -618,37 +622,37 @@ HTMLToPDF.header=HTML से पीडीएफ़
HTMLToPDF.help=HTML फ़ाइलों और html/css/images आदि को आत्मसात करने वाले ZIPs को स्वीकार करता है HTMLToPDF.help=HTML फ़ाइलों और html/css/images आदि को आत्मसात करने वाले ZIPs को स्वीकार करता है
HTMLToPDF.submit=रूपांतरित करें HTMLToPDF.submit=रूपांतरित करें
HTMLToPDF.credit=WeasyPrint का प्रयोग होता है HTMLToPDF.credit=WeasyPrint का प्रयोग होता है
HTMLToPDF.zoom=Zoom level for displaying the website. HTMLToPDF.zoom=संप्रेषण वेबसाइट के लिए डॉलर स्तर।
HTMLToPDF.pageWidth=Width of the page in centimeters. (Blank to default) HTMLToPDF.pageWidth=पृष्ठ की चौड़ाई मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.pageHeight=Height of the page in centimeters. (Blank to default) HTMLToPDF.pageHeight=पृष्ठ की ऊँचाई मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.marginTop=Top margin of the page in millimeters. (Blank to default) HTMLToPDF.marginTop=पृष्ठ का शीर्ष बन्दरगाह मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.marginBottom=Bottom margin of the page in millimeters. (Blank to default) HTMLToPDF.marginBottom=पृष्ठ का तल बन्दरगाह मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.marginLeft=Left margin of the page in millimeters. (Blank to default) HTMLToPDF.marginLeft=पृष्ठ का बाएँ बन्दरगाह मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.marginRight=Right margin of the page in millimeters. (Blank to default) HTMLToPDF.marginRight=पृष्ठ का डाई बन्दरगाह मिलीमिटर में। (व्यंकत अधिकतर मान)
HTMLToPDF.printBackground=Render the background of websites. HTMLToPDF.printBackground=वेबसाइट के पैनल को छद्म रूप से दिखाएं।
HTMLToPDF.defaultHeader=Enable Default Header (Name and page number) HTMLToPDF.defaultHeader=उचित उपनाम (नाम और पृष्ठ संख्या) इनकार करें।
HTMLToPDF.cssMediaType=Change the CSS media type of the page. HTMLToPDF.cssMediaType=पृष्ठ के लिए CSS मीडिया टाइप परिवर्तित करें।
HTMLToPDF.none=None HTMLToPDF.none=कोई नहीं
HTMLToPDF.print=Print HTMLToPDF.print=दबाओ और बन्दोच्स हार्डवेयर पर आउटपुट करें।
HTMLToPDF.screen=Screen HTMLToPDF.screen=दिखाएँ जैसा कि अपने ट्रिपल पर।
#AddStampRequest #AddStampRequest
AddStampRequest.header=Stamp PDF AddStampRequest.header=बिन्दुक बन्दोच्स हेडर
AddStampRequest.title=Stamp PDF AddStampRequest.title=बिन्दुक बन्दोच्स
AddStampRequest.stampType=Stamp Type AddStampRequest.stampType=बिन्दुक प्रकार
AddStampRequest.stampText=Stamp Text AddStampRequest.stampText=बिन्दुक टेक्स्ट
AddStampRequest.stampImage=Stamp Image AddStampRequest.stampImage=बिन्दुक आइमेज
AddStampRequest.alphabet=Alphabet AddStampRequest.alphabet=अक्षर
AddStampRequest.fontSize=Font/Image Size AddStampRequest.fontSize=फोन्ट/चित्र का आकार
AddStampRequest.rotation=Rotation AddStampRequest.rotation=वृद्धि
AddStampRequest.opacity=Opacity AddStampRequest.opacity=परिस्थिति
AddStampRequest.position=Position AddStampRequest.position=स्थिति
AddStampRequest.overrideX=Override X Coordinate AddStampRequest.overrideX=X निर्देशांक परिबद्ध करें
AddStampRequest.overrideY=Override Y Coordinate AddStampRequest.overrideY=Y निर्देशांक परिबद्ध करें
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=संवैधित मैरज
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=संवैधित टेक्स्ट रंग
AddStampRequest.submit=Submit AddStampRequest.submit=प्रदान करें
#sanitizePDF #sanitizePDF
@@ -729,7 +733,7 @@ pageLayout.submit=प्रस्तुत क
scalePages.title=पृष्ठ-स्केल समायोजित करें scalePages.title=पृष्ठ-स्केल समायोजित करें
scalePages.header=पृष्ठ-स्केल समायोजित करें scalePages.header=पृष्ठ-स्केल समायोजित करें
scalePages.pageSize=दस्तावेज़ के पृष्ठ का आकार। scalePages.pageSize=दस्तावेज़ के पृष्ठ का आकार।
scalePages.keepPageSize=Original Size scalePages.keepPageSize=मूल आकार
scalePages.scaleFactor=पृष्ठ का ज़ूम स्तर (क्रॉप)। scalePages.scaleFactor=पृष्ठ का ज़ूम स्तर (क्रॉप)।
scalePages.submit=प्रस्तुत करें scalePages.submit=प्रस्तुत करें
@@ -738,25 +742,26 @@ scalePages.submit=प्रस्तुत करें
certSign.title=प्रमाणपत्र साइनिंग certSign.title=प्रमाणपत्र साइनिंग
certSign.header=अपने प्रमाणपत्र के साथ एक पीडीएफ़ पर हस्ताक्षर करें (काम जारी है) certSign.header=अपने प्रमाणपत्र के साथ एक पीडीएफ़ पर हस्ताक्षर करें (काम जारी है)
certSign.selectPDF=साइन करने के लिए एक पीडीएफ़ फ़ाइल का चयन करें: certSign.selectPDF=साइन करने के लिए एक पीडीएफ़ फ़ाइल का चयन करें:
certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below. certSign.jksNote=नोट: यदि आपके संदेश प्रकार नीचे सूचीबद्ध नहीं है, तो कृपया keytool कमांड लाइन टूल का उपयोग कर आपका संदेश फ़ाइल (.jks) में परिवर्तित करें. फिर, नीचे .jks फ़ाइल विकल्प चुनें.
certSign.selectKey=अपनी निजी कुंजी फ़ाइल का चयन करें (PKCS#8 प्रारूप, .pem या .der हो सकता है): certSign.selectKey=अपनी निजी कुंजी फ़ाइल का चयन करें (PKCS#8 प्रारूप, .pem या .der हो सकता है):
certSign.selectCert=अपनी प्रमाणपत्र फ़ाइल का चयन करें (X.509 प्रारूप, .pem या .der हो सकता है): certSign.selectCert=अपनी प्रमाणपत्र फ़ाइल का चयन करें (X.509 प्रारूप, .pem या .der हो सकता है):
certSign.selectP12=अपनी PKCS#12 कीस्टोर फ़ाइल का चयन करें (.p12 या .pfx) (वैकल्पिक, यदि प्रदान की गई हो, तो इसमें आपकी निजी कुंजी और प्रमाणपत्र होना चाहिए): certSign.selectP12=अपनी PKCS#12 कीस्टोर फ़ाइल का चयन करें (.p12 या .pfx) (वैकल्पिक, यदि प्रदान की गई हो, तो इसमें आपकी निजी कुंजी और प्रमाणपत्र होना चाहिए):
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore): certSign.selectJKS=आपका Java Keystore (.jks या .keystore) फ़ाइल को चुनें:
certSign.certType=प्रमाणपत्र प्रकार certSign.certType=प्रमाणपत्र प्रकार
certSign.password=अपनी कीस्टोर या निजी कुंजी पासवर्ड दर्ज करें (यदि कोई हो): certSign.password=अपनी कीस्टोर या निजी कुंजी पासवर्ड दर्ज करें (यदि कोई हो):
certSign.showSig=हस्ताक्षर दिखाएं certSign.showSig=हस्ताक्षर दिखाएं
certSign.reason=कारण certSign.reason=कारण
certSign.location=स्थान certSign.location=स्थान
certSign.name=नाम certSign.name=नाम
certSign.showLogo=लॉगो दिखाएं
certSign.submit=पीडीएफ़ पर हस्ताक्षर करें certSign.submit=पीडीएफ़ पर हस्ताक्षर करें
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=वितरण साइनचर्टर हटाएं
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=PDF में डिजिटल चार्टर को हटाएं
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=एक PDF फ़ाइल को चुनें:
removeCertSign.submit=Remove Signature removeCertSign.submit=साइनचर्टर हटाएं
#removeBlanks #removeBlanks
@@ -778,24 +783,27 @@ removeAnnotations.submit=हटाएं
#compare #compare
compare.title=तुलना करें compare.title=तुलना करें
compare.header=पीडीएफ़ तुलना करें compare.header=पीडीएफ़ तुलना करें
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=प्रकाशित रंग 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=प्रकाशित रंग 2:
compare.document.1=दस्तावेज़ 1 compare.document.1=दस्तावेज़ 1
compare.document.2=दस्तावेज़ 2 compare.document.2=दस्तावेज़ 2
compare.submit=तुलना करें compare.submit=तुलना करें
compare.complex.message=एक या दोनों प्रदान की गई संस्कृति महंगे हैं, अपरिमेयता की तुलना की शुरुआत हो सकती है
compare.large.file.message=One or Both of the provided documents are too large to process
compare.no.text.message=चयनित PDF में कोई भी प्रतीक नहीं है. कृपया प्रतीक वाले PDFs का चयन करें.
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=बुक्स और कमिक्स को PDF में
BookToPDF.header=Book to PDF BookToPDF.header=बुक्स से पीडीएफ
BookToPDF.credit=Uses Calibre BookToPDF.credit=Calibre का उपयोग करता है
BookToPDF.submit=Convert BookToPDF.submit=संवाद करें
#PDFToBook #PDFToBook
PDFToBook.title=PDF to Book PDFToBook.title=PDF से बुक्स
PDFToBook.header=PDF to Book PDFToBook.header=PDF से बुक्स
PDFToBook.selectText.1=Format PDFToBook.selectText.1=फॉर्मट
PDFToBook.credit=Uses Calibre PDFToBook.credit=Calibre का उपयोग करता है
PDFToBook.submit=Convert PDFToBook.submit=संवाद करें
#sign #sign
sign.title=हस्ताक्षर sign.title=हस्ताक्षर
@@ -805,6 +813,11 @@ sign.draw=हस्ताक्षर बनाएँ
sign.text=पाठ इनपुट sign.text=पाठ इनपुट
sign.clear=साफ़ करें sign.clear=साफ़ करें
sign.add=जोड़ें sign.add=जोड़ें
sign.saved=जोड़े हुए प्रदर्शन
sign.save=प्रदर्शन बचाएं
sign.personalSigs=मौजूदा प्रदर्शन
sign.sharedSigs=साझेदार प्रदर्शन
sign.noSavedSigs=कोई भी संवर्तित प्रदर्शन नहीं मौजूद है
#repair #repair
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=न्यूनतम कंटोर क्ष
ScannerImageSplit.selectText.8=फोटो के लिए न्यूनतम कंटोर क्षेत्र थ्रेशोल्ड को सेट करता है। ScannerImageSplit.selectText.8=फोटो के लिए न्यूनतम कंटोर क्षेत्र थ्रेशोल्ड को सेट करता है।
ScannerImageSplit.selectText.9=बॉर्डर का आकार: ScannerImageSplit.selectText.9=बॉर्डर का आकार:
ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)। ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)।
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Python नहीं इंस्टॉल है. यह संचालित करने के लिए आवश्यक है.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=OCR के साथ PDF प्रोसेस करें
extractImages.title=छवियां निकालें extractImages.title=छवियां निकालें
extractImages.header=छवियां निकालें extractImages.header=छवियां निकालें
extractImages.selectText=निकाली गई छवियों को कन्वर्ट करने के लिए छवि प्रारूप चुनें extractImages.selectText=निकाली गई छवियों को कन्वर्ट करने के लिए छवि प्रारूप चुनें
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=यह दबाव अनुमति दें
extractImages.submit=निकालें extractImages.submit=निकालें
@@ -866,7 +879,7 @@ extractImages.submit=निकालें
fileToPDF.title=फ़ाइल से पीडीएफ़ fileToPDF.title=फ़ाइल से पीडीएफ़
fileToPDF.header=किसी भी फ़ाइल को पीडीएफ़ में बदलें fileToPDF.header=किसी भी फ़ाइल को पीडीएफ़ में बदलें
fileToPDF.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice और Unoconv का उपयोग करती है। fileToPDF.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice और Unoconv का उपयोग करती है।
fileToPDF.supportedFileTypesInfo=Supported File types fileToPDF.supportedFileTypesInfo=समर्थित फ़ाइल प्रजातियाँ
fileToPDF.supportedFileTypes=समर्थित फ़ाइल प्रकार नीचे दिए गए होने चाहिए हालांकि समर्थित प्रारूपों की पूरी अद्यतन सूची के लिए कृपया LibreOffice दस्तावेज़ीकरण से संदर्भित करें fileToPDF.supportedFileTypes=समर्थित फ़ाइल प्रकार नीचे दिए गए होने चाहिए हालांकि समर्थित प्रारूपों की पूरी अद्यतन सूची के लिए कृपया LibreOffice दस्तावेज़ीकरण से संदर्भित करें
fileToPDF.submit=पीडीएफ़ में बदलें fileToPDF.submit=पीडीएफ़ में बदलें
@@ -896,7 +909,7 @@ merge.title=मर्ज
merge.header=एक से अधिक PDF एक साथ मर्ज करें (2+) merge.header=एक से अधिक PDF एक साथ मर्ज करें (2+)
merge.sortByName=नाम से क्रमबद्ध करें merge.sortByName=नाम से क्रमबद्ध करें
merge.sortByDate=तारीख से क्रमबद्ध करें merge.sortByDate=तारीख से क्रमबद्ध करें
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=संयोजित फाइल में डिजिटल साइग्नचर को हटा दें?
merge.submit=मर्ज करें merge.submit=मर्ज करें
@@ -904,24 +917,35 @@ merge.submit=मर्ज करें
pdfOrganiser.title=पेज व्यवस्थापक pdfOrganiser.title=पेज व्यवस्थापक
pdfOrganiser.header=PDF पेज व्यवस्थापक pdfOrganiser.header=PDF पेज व्यवस्थापक
pdfOrganiser.submit=पृष्ठों को पुनः व्यवस्थित करें pdfOrganiser.submit=पृष्ठों को पुनः व्यवस्थित करें
pdfOrganiser.mode=Mode pdfOrganiser.mode=रूप
pdfOrganiser.mode.1=Custom Page Order pdfOrganiser.mode.1=कस्टम पेज क्रम
pdfOrganiser.mode.2=Reverse Order pdfOrganiser.mode.2=वापसी क्रम
pdfOrganiser.mode.3=Duplex Sort pdfOrganiser.mode.3=दुबल इंस्टर क्रम
pdfOrganiser.mode.4=Booklet Sort pdfOrganiser.mode.4=बुकलत सॉर्ट
pdfOrganiser.mode.5=Side Stitch Booklet Sort pdfOrganiser.mode.5=पारित-पीछे स्टिस्ट बुकलत सॉर्ट
pdfOrganiser.mode.6=Odd-Even Split pdfOrganiser.mode.6=अशैली-बहूनी कटा-चिह्नित करना
pdfOrganiser.mode.7=Remove First pdfOrganiser.mode.7=पहली पेज हटाना
pdfOrganiser.mode.8=Remove Last pdfOrganiser.mode.8=आखिरी पेज हटाना
pdfOrganiser.mode.9=Remove First and Last pdfOrganiser.mode.9=पहली और आखिरी पेज हटाना
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=अशैली-बहूनी मिश्रण
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1) pdfOrganiser.placeholder=(जैसे 1,3,2 या 4-8,2,10-12 या 2n-1)
#multiTool #multiTool
multiTool.title=पीडीएफ मल्टी टूल multiTool.title=पीडीएफ मल्टी टूल
multiTool.header=पीडीएफ मल्टी टूल multiTool.header=पीडीएफ मल्टी टूल
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=फाइल का नाम
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=पीडीएफ देखें viewPdf.title=पीडीएफ देखें
@@ -932,7 +956,7 @@ pageRemover.title=पेज हटाने वाला
pageRemover.header=पीडीएफ पेज हटाने वाला pageRemover.header=पीडीएफ पेज हटाने वाला
pageRemover.pagesToDelete=हटाने के पेज (पृष्ठ संख्याओं की व्यवस्था के लिए एक कॉमा से अलग संख्याओं की सूची दर्ज करें): pageRemover.pagesToDelete=हटाने के पेज (पृष्ठ संख्याओं की व्यवस्था के लिए एक कॉमा से अलग संख्याओं की सूची दर्ज करें):
pageRemover.submit=पेज हटाएं pageRemover.submit=पेज हटाएं
pageRemover.placeholder=(e.g. 1,2,6 or 1-10,15-30) pageRemover.placeholder=(जैसे 1,2,6 या 1-10,15-30)
#rotate #rotate
@@ -983,7 +1007,7 @@ pdfToImage.color=रंगीन
pdfToImage.grey=ग्रे स्केल pdfToImage.grey=ग्रे स्केल
pdfToImage.blackwhite=काला और सफेद (डेटा खो सकता है!) pdfToImage.blackwhite=काला और सफेद (डेटा खो सकता है!)
pdfToImage.submit=परिवर्तित करें pdfToImage.submit=परिवर्तित करें
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=पायथन नहीं अनिस्तारित है। वेबP परिवर्तन के लिए आवश्यक है।
#addPassword #addPassword
@@ -1020,10 +1044,10 @@ watermark.selectText.6=ऊंचाई स्पेसर (प्रत्ये
watermark.selectText.7=अपारदर्शिता (0% - 100%): watermark.selectText.7=अपारदर्शिता (0% - 100%):
watermark.selectText.8=वॉटरमार्क प्रकार: watermark.selectText.8=वॉटरमार्क प्रकार:
watermark.selectText.9=वॉटरमार्क छवि: watermark.selectText.9=वॉटरमार्क छवि:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=PDF डीपीआईमज़ देखभाल करें
watermark.submit=वॉटरमार्क जोड़ें watermark.submit=वॉटरमार्क जोड़ें
watermark.type.1=Text watermark.type.1=संदेश
watermark.type.2=Image watermark.type.2=इमेज
#Change permissions #Change permissions
@@ -1075,9 +1099,9 @@ pdfToPDFA.title=PDF से PDF/A में
pdfToPDFA.header=PDF से PDF/A में pdfToPDFA.header=PDF से PDF/A में
pdfToPDFA.credit=इस सेवा में PDF/A परिवर्तन के लिए ghostscript का उपयोग किया जाता है। pdfToPDFA.credit=इस सेवा में PDF/A परिवर्तन के लिए ghostscript का उपयोग किया जाता है।
pdfToPDFA.submit=परिवर्तित करें pdfToPDFA.submit=परिवर्तित करें
pdfToPDFA.tip=Currently does not work for multiple inputs at once pdfToPDFA.tip=यह सैकड़ों प्रविष्टियाँ एक ही समय में काम करते हैं
pdfToPDFA.outputFormat=Output format pdfToPDFA.outputFormat=आउटपुट फॉर्मेट
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=यह पीडीएफ मेला हस्ताक्षर से संबद्ध है। अगले कदम में यह हटाया जाएगा。
#PDFToWord #PDFToWord
@@ -1159,14 +1183,14 @@ split-by-sections.vertical.label=लंबवत विभाजन
split-by-sections.horizontal.placeholder=क्षैतिज विभाजन की संख्या दर्ज करें split-by-sections.horizontal.placeholder=क्षैतिज विभाजन की संख्या दर्ज करें
split-by-sections.vertical.placeholder=लंबवत विभाजन की संख्या दर्ज करें split-by-sections.vertical.placeholder=लंबवत विभाजन की संख्या दर्ज करें
split-by-sections.submit=PDF को विभाजित करें split-by-sections.submit=PDF को विभाजित करें
split-by-sections.merge=Merge Into One PDF split-by-sections.merge=एक पीडीऐ में मिलाएं
#printFile #printFile
printFile.title=Print File printFile.title=फाइल प्रिंत करें
printFile.header=Print File to Printer printFile.header=प्रिंट फाइल को प्रिंटर पर प्रिंट करें
printFile.selectText.1=Select File to Print printFile.selectText.1=Select File to Print
printFile.selectText.2=Enter Printer Name printFile.selectText.2=प्रिंटर का नाम दर्ज करें
printFile.submit=Print printFile.submit=Print
@@ -1174,52 +1198,50 @@ printFile.submit=Print
licenses.nav=Licenses licenses.nav=Licenses
licenses.title=3rd Party Licenses licenses.title=3rd Party Licenses
licenses.header=3rd Party Licenses licenses.header=3rd Party Licenses
licenses.module=Module licenses.module=मॗड्यूल
licenses.version=Version licenses.version=वेरसन
licenses.license=License licenses.license=License
#survey #survey
survey.nav=Survey survey.nav=परीक्षण
survey.title=Stirling-PDF Survey survey.title=स्टार्लिंग-पीडीएफ परीक्षण
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=अंतिम परीक्षण के बाद स्टार्लिंग-पीडीएफ में कई बदलाव हो गए! अधिक जानने के लिए यहाँ हमारे ब्लॉग पोस्ट का प्रयास करें:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=इन बदलावों से हम अपने व्यवसाय सहायता और जैकड़ की मिलान पाने की कुछ आशा रख रहे हैं
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(अपडेटों के बाद स्क्वायर पपपल अक्सर निष्क्रिय होगा, लेकिन पृष्ठ की तल उस पर उपलब्ध होगा)
survey.button=Take Survey survey.button=परीक्षण करें
survey.dontShowAgain=Don't show again survey.dontShowAgain=मुद्रण फ्लास्क से नहीं मिलाएं
#error #error
error.sorry=Sorry for the issue! error.sorry=अनुभव में विफलता के लिए खेद होता है!
error.needHelp=Need help / Found an issue? error.needHelp=मदद की जरूरत है / सहायता पानी पाया?
error.contactTip=If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord: error.contactTip=अगर आप भी समस्याओं के साथ बच रहे हैं, तो हमें मदद प्राप्त करने के लिए निष्क्रियता न करके अपनी सहायता की मुद्दों को भेज सकते हैं. आप GitHub पेज पर टिकट भेज सकते हैं या Discord ग्रुप में हमसे संपर्क कर सकते हैं:
error.404.head=404 - Page Not Found | Oops, we tripped in the code! error.404.head=404 - पृष्ठ नहीं पाया | तो, कोड में कुछ गलती हुई!
error.404.1=We can't seem to find the page you're looking for. error.404.1=मेहनदरी से, आप खोज रहे पृष्ठ नहीं पाया जा सकता.
error.404.2=Something went wrong error.404.2=कुछ गलती हुई.
error.github=Submit a ticket on GitHub error.github=GitHub पर टिकट भेजें
error.showStack=Show Stack Trace error.showStack=स्टैक ट्रेस को दिखाएं
error.copyStack=Copy Stack Trace error.copyStack=स्टैक ट्रेस कopiए
error.githubSubmit=GitHub - Submit a ticket error.githubSubmit=GitHub - टिकट पहुँचाओ
error.discordSubmit=Discord - Submit Support post error.discordSubmit=Discord - समर्थन पोस्ट पोस्ट करें
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=इंजाइम हटाएं
removeImage.header=Remove image removeImage.header=इंजाइम हटाएं
removeImage.removeImage=Remove image removeImage.removeImage=इंजाइम हटाएं
removeImage.submit=Remove image removeImage.submit=इंजाइम हटाएं
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=पीडीएफ को अध्यायों द्वारा भागों में बाटें
splitByChapters.header=पीडीएफ को अध्यायों द्वारा भागों में बाटें
splitByChapters.bookmarkLevel=लेमैक्स स्तर
splitByChapters.includeMetadata=मीटाडेटा को शामिल करें
splitByChapters.allowDuplicates=डबल्स अनुमति दें
splitByChapters.desc.1=यह यंकल सिपटे एक पीडीएफ फाइल को अपनी अध्याय संरचना के आधार पर बहुतांश नेट्स में विभाजित करता है.
splitByChapters.desc.2=लेमैक्स स्तर: विभाजन के लिए उपयोग की गई लेमैक्स स्तर चुनें (0 टॉप-लेवल, 1 दूसरा-लेवल, इतर जैसे).
splitByChapters.desc.3=मॉडेटरेट का शामिल करें: यदि सत्यापित किया जाता है, प्रारंभिक PDF की मॉडेटरेट को प्रत्येक विभाग PDF में शामिल किया जाएगा।
splitByChapters.desc.4=यादृच्छिक पुनरावृत्ति अनुमोदित: यदि सत्यापित किया जाता है, एक ही पेज पर दोहरे मूल्यांकन पब्लिक पीड़एफ बनाने की संभावना देता है।
splitByChapters.submit=PDF विभाजित

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Veličina pisma
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Ime pisma
pdfPrompt=Odaberi PDF(ove) pdfPrompt=Odaberi PDF(ove)
multiPdfPrompt=Odaberi PDF-ove (2+) multiPdfPrompt=Odaberi PDF-ove (2+)
multiPdfDropPrompt=Odaberi (ili povuci i ispusti) sve potrebne PDF-ove multiPdfDropPrompt=Odaberi (ili povuci i ispusti) sve potrebne PDF-ove
@@ -27,7 +27,7 @@ bored=Dosađujete se čekajući?
alphabet=Abeceda alphabet=Abeceda
downloadPdf=Preuzmi PDF downloadPdf=Preuzmi PDF
text=Tekst text=Tekst
font=Font font=Pismo
selectFillter=-- Odaberi -- selectFillter=-- Odaberi --
pageNum=Broj stranice pageNum=Broj stranice
sizes.small=Malo sizes.small=Malo
@@ -56,12 +56,12 @@ userNotFoundMessage=Korisnik nije pronađen.
incorrectPasswordMessage=Kriva zaporka. incorrectPasswordMessage=Kriva zaporka.
usernameExistsMessage=Korisničko ime već postoji usernameExistsMessage=Korisničko ime već postoji
invalidUsernameMessage=Nevažeće korisničko ime, korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-pošte. invalidUsernameMessage=Nevažeće korisničko ime, korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-pošte.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=Lozinka ne smije biti prazna i ne smije počinjati ni završavati sa razmakom.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Nova lozinka i potvrda nove lozinke moraju biti identične.
deleteCurrentUserMessage=Nije moguće izbrisati trenutno prijavljenog korisnika. deleteCurrentUserMessage=Nije moguće izbrisati trenutno prijavljenog korisnika.
deleteUsernameExistsMessage=Korisničko ime ne postoji i ne može se izbrisati. deleteUsernameExistsMessage=Korisničko ime ne postoji i ne može se izbrisati.
downgradeCurrentUserMessage=Nije moguće vratiti unazad ulogu trenutnog korisnika downgradeCurrentUserMessage=Nije moguće vratiti unazad ulogu trenutnog korisnika
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=Trenutni korisnik ne može biti onemogućen
downgradeCurrentUserLongMessage=Nije moguće vratiti unazad ulogu trenutnog korisnika. Dakle, trenutni korisnik neće biti prikazan. downgradeCurrentUserLongMessage=Nije moguće vratiti unazad ulogu trenutnog korisnika. Dakle, trenutni korisnik neće biti prikazan.
userAlreadyExistsOAuthMessage=Korisnik već postoji kao OAuth2 korisnik. userAlreadyExistsOAuthMessage=Korisnik već postoji kao OAuth2 korisnik.
userAlreadyExistsWebMessage=Korisnik već postoji kao web korisnik. userAlreadyExistsWebMessage=Korisnik već postoji kao web korisnik.
@@ -75,16 +75,19 @@ visitGithub=Posjeti Github Repository
donate=Doniraj donate=Doniraj
color=Boja color=Boja
sponsor=Sponzor sponsor=Sponzor
info=Info info=Informacije
pro=Pro pro=Pro
page=Page page=Stranica
pages=Pages pages=Stranice
loading=Učitavanje...
addToDoc=Dodaj u dokument
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Politika privatnosti
legal.terms=Terms and Conditions legal.terms=Uspe sodržine
legal.accessibility=Accessibility legal.accessibility=Dostupnost
legal.cookie=Cookie Policy legal.cookie=Politika kolačića
legal.impressum=Impressum legal.impressum=Vedro ishoda
############### ###############
# Pipeline # # Pipeline #
@@ -96,7 +99,7 @@ pipeline.defaultOption=Prilagođeno
pipeline.submitButton=Pošalji pipeline.submitButton=Pošalji
pipeline.help=Pipeline Pomoć pipeline.help=Pipeline Pomoć
pipeline.scanHelp=Pomoć za skeniranje mapa pipeline.scanHelp=Pomoć za skeniranje mapa
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Jeste li sigurni da želite obrisati pipeline?
###################### ######################
# Pipeline Options # # Pipeline Options #
@@ -114,21 +117,21 @@ pipelineOptions.validateButton=Potvrdi
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Ažurirajte na Pro
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Ova funkcija je dostupna samo pro korisnicima.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF Pro podrzava konfiguiracione datoteke u formati YAML i druga osobine SSO.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Tražite još funkcija za upravljanje korisnicima? Razmotrite Stirling PDF Pro
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Želite li da stvarate Stirling PDF bolji?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=Stirling PDF ima uključene analitike koje nam pomažu da proizvod poboljšamo. Niste pratili nikakva osobna informacija ni sadržaj datoteka.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Razmotrite omogućivanje analitičkih podataka kako biste stvorili Stirling-PDF veće i da bismo bolje razumeli naših korisnika.
analytics.enable=Enable analytics analytics.enable=Omogući analitike
analytics.disable=Disable analytics analytics.disable=Onemogući analitike
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=Možete promijeniti postavke za analitike u datoteci config/settings.yml
############# #############
# NAVBAR # # NAVBAR #
@@ -139,13 +142,14 @@ navbar.language=Jezici
navbar.settings=Postavke navbar.settings=Postavke
navbar.allTools=Alati navbar.allTools=Alati
navbar.multiTool=Multi Tools (Alati) navbar.multiTool=Multi Tools (Alati)
navbar.search=Search
navbar.sections.organize=Organizirati navbar.sections.organize=Organizirati
navbar.sections.convertTo=Pretvori u PDF navbar.sections.convertTo=Pretvori u PDF
navbar.sections.convertFrom=Pretvori iz PDF navbar.sections.convertFrom=Pretvori iz PDF
navbar.sections.security=Potpis & sigurnost navbar.sections.security=Potpis & sigurnost
navbar.sections.advance=Napredno navbar.sections.advance=Napredno
navbar.sections.edit=Pregled & Uređivanje navbar.sections.edit=Pregled & Uređivanje
navbar.sections.popular=Popular navbar.sections.popular=Popularno
############# #############
# SETTINGS # # SETTINGS #
@@ -202,9 +206,9 @@ adminUserSettings.header=Postavka kontrole korisnika za administratora
adminUserSettings.admin=Administrator adminUserSettings.admin=Administrator
adminUserSettings.user=Korisnik adminUserSettings.user=Korisnik
adminUserSettings.addUser=Dodaj novog korisnika adminUserSettings.addUser=Dodaj novog korisnika
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Obriši korisnika
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=Treba li obračunati ovaj korisnika?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Treba li isključiti/uključiti ovog korisnika?
adminUserSettings.usernameInfo=Korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-pošte. adminUserSettings.usernameInfo=Korisničko ime može sadržavati samo slova, brojke i sljedeće posebne znakove @._+- ili mora biti važeća adresa e-pošte.
adminUserSettings.roles=Uloge adminUserSettings.roles=Uloge
adminUserSettings.role=Uloga adminUserSettings.role=Uloga
@@ -218,32 +222,33 @@ adminUserSettings.forceChange=Prisiliti korisnika da promijeni lozinku prilikom
adminUserSettings.submit=Spremi korisnika adminUserSettings.submit=Spremi korisnika
adminUserSettings.changeUserRole=Promijenite korisničku ulogu adminUserSettings.changeUserRole=Promijenite korisničku ulogu
adminUserSettings.authenticated=Autentificirano adminUserSettings.authenticated=Autentificirano
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Uredi vlastit profil
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=Omotljiv korisnik
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=Onemogućen korisnik
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Aktivni korisnici:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Isključeni korisnici:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Ukupan broj korisnika:
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Zadnji zahtjev
database.title=Database Import/Export database.title=Database Import/Export
database.header=Database Import/Export database.header=Database Import/Export
database.fileName=File Name database.fileName=Ime datoteke
database.creationDate=Creation Date database.creationDate=Datum stvaranja
database.fileSize=File Size database.fileSize=Veličina datoteke
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Obriši zadao sažeto datoteke
database.importBackupFile=Import Backup File database.importBackupFile=Uvezi sažeto datoteku
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Preuzmi sažeto datoteku
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=Kada uvažavate podatke, je ključno sigurno imati ispravan struktur. Ako niste sigurni šta uradite, tražite savjet i podršku od professionala. Greška u strukturi može uzrokovati greške u aplikaciji, do i uključujući potpunu nevjerojatnost funkcionalnosti aplikacije.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=Ime datoteke nije relevantno prijevezi. Buduće bit će ponovno oznaceno za određeni format backup_user_yyyyMMddHHmm.sql, čime se osigurava konzistentna nazivnica.
database.submit=Import Backup database.submit=Uvezi sažeto
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Uvez u bazu podataka uspio
database.fileNotFound=File not Found database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Datoteka ne smije biti null ili prazna
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=Vaš sesija je istekla. Molim vas da osvježite stranicu i pokušate ponovno.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -283,7 +288,7 @@ pdfToImage.tags=konverzija,img,jpg,slika,foto
home.pdfOrganiser.title=Organiziranje home.pdfOrganiser.title=Organiziranje
home.pdfOrganiser.desc=Uklonite/preuredite stranice bilo kojim redoslijedom home.pdfOrganiser.desc=Uklonite/preuredite stranice bilo kojim redoslijedom
pdfOrganiser.tags=duplex,even,odd,sort,move pdfOrganiser.tags=dvostrana,parne,neparni,prikupljanje,prebacivanje
home.addImage.title=Dodaj sliku home.addImage.title=Dodaj sliku
@@ -347,7 +352,7 @@ PDFToPresentation.tags=slajdovi,prikaz,office,microsoft
home.PDFToText.title=PDF u RTF (Tekst) home.PDFToText.title=PDF u RTF (Tekst)
home.PDFToText.desc=Pretvorite PDF u tekst ili RTF format home.PDFToText.desc=Pretvorite PDF u tekst ili RTF format
PDFToText.tags=richformat,richtextformat,rich text format PDFToText.tags=bojaformata,tjedentextformat,sadržanotekstformat
home.PDFToHTML.title=PDF u HTML home.PDFToHTML.title=PDF u HTML
home.PDFToHTML.desc=Pretvorite PDF u HTML format home.PDFToHTML.desc=Pretvorite PDF u HTML format
@@ -390,9 +395,9 @@ home.certSign.title=Potpišite s certifikatom
home.certSign.desc=Potpisuje PDF s certifikatom/ključem (PEM/P12) home.certSign.desc=Potpisuje PDF s certifikatom/ključem (PEM/P12)
certSign.tags=autentifikacija,PEM,P12,zvanično,šifriranje certSign.tags=autentifikacija,PEM,P12,zvanično,šifriranje
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Ukloni potpis sertifikata
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=Uklonite potpis sertifikata iz PDF-a
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=autentičiranje,PEM,P12,djelomičan dešifriranje
home.pageLayout.title=Izgled s više stranica home.pageLayout.title=Izgled s više stranica
home.pageLayout.desc=Spojite više stranica PDF dokumenta u jednu stranicu home.pageLayout.desc=Spojite više stranica PDF dokumenta u jednu stranicu
@@ -498,33 +503,33 @@ home.BookToPDF.title=Book u PDF
home.BookToPDF.desc=Pretvara format knjige/stripa u PDF format pomoću calibre home.BookToPDF.desc=Pretvara format knjige/stripa u PDF format pomoću calibre
BookToPDF.tags=Knjiga,Strip,Calibre,Pretvori,manga,amazon,kindle BookToPDF.tags=Knjiga,Strip,Calibre,Pretvori,manga,amazon,kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Ukloni sliku
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Ukloni sliku iz PDF-a kako bi se smanjio veličina datoteke
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Ukloni sliku, Rad sa stranicama, Back end, server strana
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=Podijeli PDF prema glavama
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Podijeli PDF na više datoteka prema njegovom strukturnom obliku glava.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=podjela, glave, markere, organizacija
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Zameni-inverziranje boja u PDF-u
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Zamenite boju teksta i pozadine u PDF-u te inverzirajte cijeli PDF kako bi se smanjila veličina datoteke.
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Zameni boju, Rad sa stranicama, Back end, server strana
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Optije za zamenu ili inverziranje boja
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Standardno (standarske visoko kontrastne boje)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Napčno (prilagođene boje)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Cijelo-inverzirajte (inverzirajte sve boje)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Optije visoko kontrastne boje
replace-color.selectText.6=white text on black background replace-color.selectText.6=Crna tekst na bijelu pozadini
replace-color.selectText.7=Black text on white background replace-color.selectText.7=Bijeli tekst na crvenoj pozadini
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=Žutni tekst na crnoj pozadini
replace-color.selectText.9=Green text on black background replace-color.selectText.9=Zeleni tekst na crnoj pozadini
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Izaberite boju teksta
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Izaberite pozadinu boju
replace-color.submit=Replace replace-color.submit=Zamijeni
@@ -543,18 +548,17 @@ login.locked=Vaš račun je zaključan.
login.signinTitle=Molimo vas da se prijavite login.signinTitle=Molimo vas da se prijavite
login.ssoSignIn=Prijavite se putem jedinstvene prijave login.ssoSignIn=Prijavite se putem jedinstvene prijave
login.oauth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno login.oauth2AutoCreateDisabled=OAUTH2 automatsko kreiranje korisnika je onemogućeno
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=Registracija ili prijava nekadreguiranih korisnika trenutno su blokirane. Molimo Vas da kontaktirate administratora.
login.oauth2RequestNotFound=Zahtjev za autorizaciju nije pronađen login.oauth2RequestNotFound=Zahtjev za autorizaciju nije pronađen
login.oauth2InvalidUserInfoResponse=Nevažeće informacije o korisniku login.oauth2InvalidUserInfoResponse=Nevažeće informacije o korisniku
login.oauth2invalidRequest=Neispravan zahtjev login.oauth2invalidRequest=Neispravan zahtjev
login.oauth2AccessDenied=Pristup odbijen login.oauth2AccessDenied=Pristup odbijen
login.oauth2InvalidTokenResponse=Nevažeći odgovor tokena login.oauth2InvalidTokenResponse=Nevažeći odgovor tokena
login.oauth2InvalidIdToken=Nevažeći ID token login.oauth2InvalidIdToken=Nevažeći ID token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=Korisnik je deaktiviran, prijava sa ovim korisničkim imenom je trenutno zakazana. Molimo Vas da kontaktirate administratorske osobe.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Već ste se prijavili na
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=ure. Odjavite se s ure i pokušajte ponovo.
login.toManySessions=You have too many active sessions login.toManySessions=Imate preko mrežne sesije aktivnih
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatsko uređivanje autoRedact.title=Automatsko uređivanje
@@ -729,7 +733,7 @@ pageLayout.submit=Potvrdi
scalePages.title=Podesite veličinu stranice scalePages.title=Podesite veličinu stranice
scalePages.header=Podesite veličinu stranice scalePages.header=Podesite veličinu stranice
scalePages.pageSize=Veličina stranice dokumenta. scalePages.pageSize=Veličina stranice dokumenta.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Originalna veličina
scalePages.scaleFactor=Razina zumiranja (obrezivanje) stranice. scalePages.scaleFactor=Razina zumiranja (obrezivanje) stranice.
scalePages.submit=Potvrdi scalePages.submit=Potvrdi
@@ -749,14 +753,15 @@ certSign.showSig=Prikaži potpis
certSign.reason=Razlog certSign.reason=Razlog
certSign.location=Mjesto certSign.location=Mjesto
certSign.name=Ime certSign.name=Ime
certSign.showLogo=Prikaži logo
certSign.submit=Potpiši PDF certSign.submit=Potpiši PDF
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Ukloni digitalno potpisano dokazilo
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=Uklonite digitalni potpis iz PDF-a
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=Odaberite datoteku PDF:
removeCertSign.submit=Remove Signature removeCertSign.submit=Ukloni potpisi
#removeBlanks #removeBlanks
@@ -778,11 +783,14 @@ removeAnnotations.submit=Ukloni
#compare #compare
compare.title=Uporedite compare.title=Uporedite
compare.header=Usporedite PDF-ove compare.header=Usporedite PDF-ove
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Boja osvetljenja 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Boja osvetljenja 2:
compare.document.1=Dokument 1 compare.document.1=Dokument 1
compare.document.2=Dokument 2 compare.document.2=Dokument 2
compare.submit=Uporedi compare.submit=Uporedi
compare.complex.message=Jedan ili oba unesena dokumenta su veliki datoteke, to može smanjiti preciznost usporedbi
compare.large.file.message=Jedan ili oba unesena dokumenta su prevelike za obradu
compare.no.text.message=Jedan ili oba odabrana PDF-a nema tekst. Odaberite PDF-ove s tekstom za usporedbu.
#BookToPDF #BookToPDF
BookToPDF.title=Knjige i stripovi u PDF BookToPDF.title=Knjige i stripovi u PDF
@@ -805,6 +813,11 @@ sign.draw=Nacrtaj potpis
sign.text=Tekstualni unos sign.text=Tekstualni unos
sign.clear=Obriši sign.clear=Obriši
sign.add=Dodaj sign.add=Dodaj
sign.saved=Sacuvane potpisne oznake
sign.save=Sačuvaj potpisnu oznaku
sign.personalSigs=Osobni potpisi
sign.sharedSigs=Dijeljeni potpisi
sign.noSavedSigs=Nema sacuvanih potpisa pronađenih
#repair #repair
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=Minimalna konturna površina:
ScannerImageSplit.selectText.8=Postavlja minimalni prag površine konture za fotografiju ScannerImageSplit.selectText.8=Postavlja minimalni prag površine konture za fotografiju
ScannerImageSplit.selectText.9=Veličina obruba: ScannerImageSplit.selectText.9=Veličina obruba:
ScannerImageSplit.selectText.10=Postavlja veličinu obruba koji se dodaje i uklanja kako bi se spriječili bijeli obrubi u ispisu (zadano: 1). ScannerImageSplit.selectText.10=Postavlja veličinu obruba koji se dodaje i uklanja kako bi se spriječili bijeli obrubi u ispisu (zadano: 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=Python nije instaliran. Treba je za izvršenje.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=Obradi PDF sa OCR-om
extractImages.title=Ekstrakt slika extractImages.title=Ekstrakt slika
extractImages.header=Ekstrakt slika extractImages.header=Ekstrakt slika
extractImages.selectText=Odaberite format slike za pretvaranje izdvojenih slika extractImages.selectText=Odaberite format slike za pretvaranje izdvojenih slika
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Sačuvaj duplikate slike
extractImages.submit=Izdvajanje extractImages.submit=Izdvajanje
@@ -896,7 +909,7 @@ merge.title=Spajanje
merge.header=Spajanje više PDF-ova (2+) merge.header=Spajanje više PDF-ova (2+)
merge.sortByName=Poredaj po imenu merge.sortByName=Poredaj po imenu
merge.sortByDate=Poredaj po datumu merge.sortByDate=Poredaj po datumu
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Ukloniti digitalni potpis u kombiniranom datoteku?
merge.submit=Spajanje merge.submit=Spajanje
@@ -914,7 +927,7 @@ pdfOrganiser.mode.6=Par-Nepar Podjela
pdfOrganiser.mode.7=Ukloni Prvu pdfOrganiser.mode.7=Ukloni Prvu
pdfOrganiser.mode.8=Ukloni Zadnju pdfOrganiser.mode.8=Ukloni Zadnju
pdfOrganiser.mode.9=Ukloni Prvu i Zadnju pdfOrganiser.mode.9=Ukloni Prvu i Zadnju
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Neparno-parna kombinacija
pdfOrganiser.placeholder=(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1) pdfOrganiser.placeholder=(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1)
@@ -922,6 +935,17 @@ pdfOrganiser.placeholder=(npr. 1,3,2 ili 4-8,2,10-12 ili 2n-1)
multiTool.title=PDF Višenamjenski alat multiTool.title=PDF Višenamjenski alat
multiTool.header=PDF Višenamjenski alat multiTool.header=PDF Višenamjenski alat
multiTool.uploadPrompts=Naziv datoteke multiTool.uploadPrompts=Naziv datoteke
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=Pogledaj viewPdf.title=Pogledaj
@@ -983,7 +1007,7 @@ pdfToImage.color=Boja
pdfToImage.grey=Sivi tonovi pdfToImage.grey=Sivi tonovi
pdfToImage.blackwhite=Crno-bijelo (mogu se izgubiti podaci!) pdfToImage.blackwhite=Crno-bijelo (mogu se izgubiti podaci!)
pdfToImage.submit=Pretvori pdfToImage.submit=Pretvori
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Python nije instaliran. Treba je za konverziju na WebP.
#addPassword #addPassword
@@ -1020,7 +1044,7 @@ watermark.selectText.6=Visina razmaka (Razmak između svakog vodenog žiga okomi
watermark.selectText.7=Neprozirnost (0% - 100%): watermark.selectText.7=Neprozirnost (0% - 100%):
watermark.selectText.8=Vrsta vodenog žiga: watermark.selectText.8=Vrsta vodenog žiga:
watermark.selectText.9=Slika vodenog žiga: watermark.selectText.9=Slika vodenog žiga:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=Konvertiraj PDF u PDF-Sliku
watermark.submit=Dodaj vodeni žig watermark.submit=Dodaj vodeni žig
watermark.type.1=Tekst watermark.type.1=Tekst
watermark.type.2=Slika watermark.type.2=Slika
@@ -1077,7 +1101,7 @@ pdfToPDFA.credit=Ova usluga koristi ghostscript za PDF/A pretvorbu
pdfToPDFA.submit=Pretvoriti pdfToPDFA.submit=Pretvoriti
pdfToPDFA.tip=Trenutno ne radi za više unosa odjednom pdfToPDFA.tip=Trenutno ne radi za više unosa odjednom
pdfToPDFA.outputFormat=Izlazni format pdfToPDFA.outputFormat=Izlazni format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=PDF sadrži digitalni potpis. U sledećem koraku će biti uklonjen.
#PDFToWord #PDFToWord
@@ -1179,15 +1203,15 @@ licenses.version=Verzija
licenses.license=Licenca licenses.license=Licenca
#survey #survey
survey.nav=Survey survey.nav=Upitnica
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Upitnica
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF nema praćenje pa želimo svesnost korisnika da bi poboljšali Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=Stirling-PDF je promenjen od poslednje upitnice! Za više informacija, proverite naš blog ovdje:
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=S ovim promenama dobivamo platnu podršku i financiranje poslovnim aktivnostima
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Upitnica popup će biti onemogućena u sljedećim ažuracanjima aliće se nalaziti na dnu stranice)
survey.button=Take Survey survey.button=Izvrsi upitnicu
survey.dontShowAgain=Don't show again survey.dontShowAgain=Ne prikazujući ponovo
#error #error
@@ -1205,21 +1229,19 @@ error.discordSubmit=Discord - Pošalji objavu podrške
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Ukloni sliku
removeImage.header=Remove image removeImage.header=Ukloni sliku
removeImage.removeImage=Remove image removeImage.removeImage=Ukloni sliku
removeImage.submit=Remove image removeImage.submit=Izbriši sliku
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF
splitByChapters.title=Podijeli PDF naoglazdene glave
splitByChapters.header=Podijeli PDF naoglazdene glave
splitByChapters.bookmarkLevel=Nivo oznaka
splitByChapters.includeMetadata=Uključi metapodatke
splitByChapters.allowDuplicates=Dopuštaj duplikate
splitByChapters.desc.1=Ova alatka podijeli PDF datoteku u više PDFa na teme njene strukture glava.
splitByChapters.desc.2=Nivo oznaka: Odaberite nivo oznaka koji će se koristiti za podjelu (0 za prvi nivo, 1 za drugi nivo itd.).
splitByChapters.desc.3=Uključi metapodatke: Ako je pokušano, metapodaci iz originalne PDF datoteke će biti uključeni u svaku podijeljenu PDF datoteku.
splitByChapters.desc.4=Dopuštaj duplikate: Ako je ova opcija zaštićena, dozvoljava se da se na istoj strani mogu stvoriti posebne PDF datoteke s više oznaka.
splitByChapters.submit=Podijeli PDF

View File

@@ -3,8 +3,8 @@
########### ###########
# the direction that the language is written (ltr = left to right, rtl = right to left) # the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr language.direction=ltr
addPageNumbers.fontSize=Font Size addPageNumbers.fontSize=Betűméret
addPageNumbers.fontName=Font Name addPageNumbers.fontName=Betűtípus
pdfPrompt=Válasszon PDF-fájlokat pdfPrompt=Válasszon PDF-fájlokat
multiPdfPrompt=Válasszon PDF-fájlokat (2+) multiPdfPrompt=Válasszon PDF-fájlokat (2+)
multiPdfDropPrompt=Válassza ki (vagy húzza ide) az összes szükséges PDF-fájlt multiPdfDropPrompt=Válassza ki (vagy húzza ide) az összes szükséges PDF-fájlt
@@ -12,17 +12,17 @@ imgPrompt=Válasszon képeket
genericSubmit=Beküldés genericSubmit=Beküldés
processTimeWarning=Figyelmeztetés: Ez a folyamat akár egy percig is eltarthat a fájlmérettől függően processTimeWarning=Figyelmeztetés: Ez a folyamat akár egy percig is eltarthat a fájlmérettől függően
pageOrderPrompt=Egyedi oldalsorrend (Adjon meg vesszővel elválasztott oldalszámokat vagy függvényeket, például 2n+1): pageOrderPrompt=Egyedi oldalsorrend (Adjon meg vesszővel elválasztott oldalszámokat vagy függvényeket, például 2n+1):
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) : pageSelectionPrompt=Egyedi oldal kiválasztás (Virtuális, hússzögletes lista formátumban írja meg a választott oldalak számát, például 1,5,6 vagy függvények formában: 2n+1):
goToPage=Ugrás goToPage=Ugrás
true=Igaz true=Igaz
false=Hamis false=Hamis
unknown=Ismeretlen unknown=Ismeretlen
save=Mentés save=Mentés
saveToBrowser=Save to Browser saveToBrowser=Mentés bölcskébe
close=Bezárás close=Bezárás
filesSelected=kiválasztott fájlok filesSelected=kiválasztott fájlok
noFavourites=Nincs hozzáadva kedvenc noFavourites=Nincs hozzáadva kedvenc
downloadComplete=Download Complete downloadComplete=Letöltés befejezve
bored=Unatkozol? bored=Unatkozol?
alphabet=Ábécé alphabet=Ábécé
downloadPdf=PDF letöltése downloadPdf=PDF letöltése
@@ -46,113 +46,117 @@ red=Piros
green=Zöld green=Zöld
blue=Kék blue=Kék
custom=Egyedi... custom=Egyedi...
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems! WorkInProgess=Munka folyamatban, lehetséges hibával működhet, kérjük jelentse meg bármilyen problémát!
poweredBy=Powered by poweredBy=Hozzávalója:
yes=Yes yes=Igen
no=No no=Nem
changedCredsMessage=A hitelek megváltoztak! changedCredsMessage=A hitelek megváltoztak!
notAuthenticatedMessage=Felhasználó nincs hitelesítve. notAuthenticatedMessage=Felhasználó nincs hitelesítve.
userNotFoundMessage=A felhasználó nem található. userNotFoundMessage=A felhasználó nem található.
incorrectPasswordMessage=A jelenlegi jelszó helytelen. incorrectPasswordMessage=A jelenlegi jelszó helytelen.
usernameExistsMessage=Az új felhasználónév már létezik. usernameExistsMessage=Az új felhasználónév már létezik.
invalidUsernameMessage=Invalid username, username can only contain letters, numbers and the following special characters @._+- or must be a valid email address. invalidUsernameMessage=Érvénytelen felhasználónév, a felhasználónév csak betűk, számokat és az alábbi kisebb karaktereket tartalmazhat @._+- vagy egy érvényes e-mail címnek kell lennie.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end. invalidPasswordMessage=A jelszó nem lehet üres és nem lehet teljesen tartalmazni háttérspácseket.
confirmPasswordErrorMessage=New Password and Confirm New Password must match. confirmPasswordErrorMessage=Új jelszó és Megerősítési új jelszó egyeztetése.
deleteCurrentUserMessage=Cannot delete currently logged in user. deleteCurrentUserMessage=Jelenleg bejelentkezett felhasználót nem lehet törölni.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted. deleteUsernameExistsMessage=A felhasználónév nem létezik és nem lehet törlésre került.
downgradeCurrentUserMessage=A jelenlegi felhasználó szerepkörét nem lehet visszaminősíteni downgradeCurrentUserMessage=A jelenlegi felhasználó szerepkörét nem lehet visszaminősíteni
disabledCurrentUserMessage=The current user cannot be disabled disabledCurrentUserMessage=Jelenleg bejelentkezett felhasználó nem lehet letiltva.
downgradeCurrentUserLongMessage=Az aktuális felhasználó szerepkörét nem lehet visszaminősíteni. Ezért az aktuális felhasználó nem jelenik meg. downgradeCurrentUserLongMessage=Az aktuális felhasználó szerepkörét nem lehet visszaminősíteni. Ezért az aktuális felhasználó nem jelenik meg.
userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user. userAlreadyExistsOAuthMessage=Az ezer hitelesítő szolgáltatás felhasználó ismertetve van.
userAlreadyExistsWebMessage=The user already exists as an web user. userAlreadyExistsWebMessage=A web felhasználó ismertetve van.
error=Error error=Hiba
oops=Oops! oops=Egy gond történt!
help=Help help=Segítség
goHomepage=Go to Homepage goHomepage=Kezdőoldal megnyitása
joinDiscord=Join our Discord server joinDiscord=Jönj hozzá a Discord-szervert
seeDockerHub=See Docker Hub seeDockerHub=Docker Hub-on látni
visitGithub=Visit Github Repository visitGithub=GitHub Repository megtekintése
donate=Donate donate=Szerzés működéséhez segítségnyújtás
color=Color color=Szín
sponsor=Sponsor sponsor=Támogatók bejegyzése
info=Info info=Információ
pro=Pro pro=Professionális
page=Page page=Oldal
pages=Pages pages=Oldalak
loading=Betöltés...
addToDoc=Hozzáadás dokumentumba
reset=Reset
legal.privacy=Privacy Policy legal.privacy=Adatvédelmi nyilatkozat
legal.terms=Terms and Conditions legal.terms=Feltételek és feltételek
legal.accessibility=Accessibility legal.accessibility=Elérhetőség
legal.cookie=Cookie Policy legal.cookie=Cukiernyomtatványi zászló
legal.impressum=Impressum legal.impressum=Rendszerinformáció
############### ###############
# Pipeline # # Pipeline #
############### ###############
pipeline.header=Pipeline Menu (Beta) pipeline.header=Pipelinenavigációs menü (betavizsgálat)
pipeline.uploadButton=Upload Custom pipeline.uploadButton=Feltöltés
pipeline.configureButton=Configure pipeline.configureButton=Konfigurálás
pipeline.defaultOption=Custom pipeline.defaultOption=Egyéni
pipeline.submitButton=Submit pipeline.submitButton=Küldés
pipeline.help=Pipeline Help pipeline.help=Útmutató a pipelínhez
pipeline.scanHelp=Folder Scanning Help pipeline.scanHelp=Mappák lekérése útmutatása
pipeline.deletePrompt=Are you sure you want to delete pipeline pipeline.deletePrompt=Biztosan törölni szeretné az opciókat?
###################### ######################
# Pipeline Options # # Pipeline Options #
###################### ######################
pipelineOptions.header=Pipeline Configuration pipelineOptions.header=Pipelín beállításai
pipelineOptions.pipelineNameLabel=Pipeline Name pipelineOptions.pipelineNameLabel=Pipelín neve
pipelineOptions.saveSettings=Save Operation Settings pipelineOptions.saveSettings=Beállítások mentése
pipelineOptions.pipelineNamePrompt=Enter pipeline name here pipelineOptions.pipelineNamePrompt=Írd be a pipelín nevét ide
pipelineOptions.selectOperation=Select Operation pipelineOptions.selectOperation=Művelet kiválasztása
pipelineOptions.addOperationButton=Add operation pipelineOptions.addOperationButton=Művelet hozzáadása
pipelineOptions.pipelineHeader=Pipeline: pipelineOptions.pipelineHeader=Pipelín:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Mentés
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Érvényesítés
######################## ########################
# ENTERPRISE EDITION # # ENTERPRISE EDITION #
######################## ########################
enterpriseEdition.button=Upgrade to Pro enterpriseEdition.button=Növelje a személyrendszert PRO-re
enterpriseEdition.warning=This feature is only available to Pro users. enterpriseEdition.warning=Ez a funkció csak a PRO felhasználók számára érhető el.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features. enterpriseEdition.yamlAdvert=Stirling PDF PRO támogatja a YAML konfigurációs fájlokat és más SSO jellemzőket.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro enterpriseEdition.ssoAdvert=Több felhasználókezelési funkcióra vár? Ismételje meg a figyalmazást az Stirling PDF PRO szolgáltatásaihoz.
################# #################
# Analytics # # Analytics #
################# #################
analytics.title=Do you want make Stirling PDF better? analytics.title=Szeretnéd tetszésre módosítani a Stirling PDF-t?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents. analytics.paragraph1=A Stirling PDF szöveges adatokat jellemző integrációt teszi lehetővé, hogy javítsuk a terméket. Nem folytatjuk semmit sem a személyes információk vagy fájl tartalmakat.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better. analytics.paragraph2=Köszönjük tekintse meg az integrációt, ami segít a Stirling-PDF növekedésében és segítne megértenünk a felhasználóinkat jobban.
analytics.enable=Enable analytics analytics.enable=Engedélyezze az analitikát
analytics.disable=Disable analytics analytics.disable=Letiltja az analitikát
analytics.settings=You can change the settings for analytics in the config/settings.yml file analytics.settings=A beállítások módosítása az analitikáért a config/settings.yml fájlban
############# #############
# NAVBAR # # NAVBAR #
############# #############
navbar.favorite=Favorites navbar.favorite=Kedvencek
navbar.darkmode=Sötét mód navbar.darkmode=Sötét mód
navbar.language=Languages navbar.language=Nyelvek
navbar.settings=Beállítások navbar.settings=Beállítások
navbar.allTools=Tools navbar.allTools=Eszközök
navbar.multiTool=Multi Tools navbar.multiTool=Multi Tools
navbar.sections.organize=Organize navbar.search=Search
navbar.sections.convertTo=Convert to PDF navbar.sections.organize=Összeállítás
navbar.sections.convertFrom=Convert from PDF navbar.sections.convertTo=Átalakítás PDF-be
navbar.sections.security=Sign & Security navbar.sections.convertFrom=PDF-ből átalakítás
navbar.sections.advance=Advanced navbar.sections.security=Hitelesítés & Biztonság
navbar.sections.edit=View & Edit navbar.sections.advance=Fogadott funkciók
navbar.sections.popular=Popular navbar.sections.edit=Nézés és szerkesztés
navbar.sections.popular=Populáris
############# #############
# SETTINGS # # SETTINGS #
############# #############
settings.title=Beállítások settings.title=Beállítások
settings.update=Frisítés elérhető settings.update=Frisítés elérhető
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available. settings.updateAvailable={0} az aktuális telepített verzió. Az újabb verzió ({1}) elérhető.
settings.appVersion=App Verzió: settings.appVersion=App Verzió:
settings.downloadOption.title=Válassza ki a letöltési lehetőséget (Egyetlen fájl esetén a nem tömörített letöltésekhez): settings.downloadOption.title=Válassza ki a letöltési lehetőséget (Egyetlen fájl esetén a nem tömörített letöltésekhez):
settings.downloadOption.1=Nyissa meg ugyanabban az ablakban settings.downloadOption.1=Nyissa meg ugyanabban az ablakban
@@ -161,13 +165,13 @@ settings.downloadOption.3=Töltse le a fájlt
settings.zipThreshold=Fájlok tömörítése, ha a letöltött fájlok száma meghaladja settings.zipThreshold=Fájlok tömörítése, ha a letöltött fájlok száma meghaladja
settings.signOut=Kijelentkezés settings.signOut=Kijelentkezés
settings.accountSettings=Fiókbeállítások settings.accountSettings=Fiókbeállítások
settings.bored.help=Enables easter egg game settings.bored.help=Easter Egg játék engedélyezése
settings.cacheInputs.name=Save form inputs settings.cacheInputs.name=Formulálapok mentése
settings.cacheInputs.help=Enable to store previously used inputs for future runs settings.cacheInputs.help=Engedélyezve a korábban használt adatok tárolása a következő futásokhoz
changeCreds.title=Hitelesítés megváltoztatása changeCreds.title=Hitelesítés megváltoztatása
changeCreds.header=Frissítse fiókadatait changeCreds.header=Frissítse fiókadatait
changeCreds.changePassword=You are using default login credentials. Please enter a new password changeCreds.changePassword=Használja a szükséges bejelentkezési adatokat. Kérjen meg egy új jelszót.
changeCreds.newUsername=Új felhasználónév changeCreds.newUsername=Új felhasználónév
changeCreds.oldPassword=Jelenlegi jelszó changeCreds.oldPassword=Jelenlegi jelszó
changeCreds.newPassword=Új jelszó changeCreds.newPassword=Új jelszó
@@ -202,48 +206,49 @@ adminUserSettings.header=Adminisztrátori Felhasználói Vezérlési Beállítá
adminUserSettings.admin=Adminisztrátor adminUserSettings.admin=Adminisztrátor
adminUserSettings.user=Felhasználó adminUserSettings.user=Felhasználó
adminUserSettings.addUser=Új felhasználó hozzáadása adminUserSettings.addUser=Új felhasználó hozzáadása
adminUserSettings.deleteUser=Delete User adminUserSettings.deleteUser=Törlés felhasználó
adminUserSettings.confirmDeleteUser=Should the user be deleted? adminUserSettings.confirmDeleteUser=A felhasználót töröljük?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled? adminUserSettings.confirmChangeUserStatus=Az állapot módosítása megfelelően?
adminUserSettings.usernameInfo=Username can only contain letters, numbers and the following special characters @._+- or must be a valid email address. adminUserSettings.usernameInfo=A felhasználónév csak betűk, számok és az alábbi speciális karakterek @._+- vagy egy érvényes e-mail-cím lehet.
adminUserSettings.roles=Szerepek adminUserSettings.roles=Szerepek
adminUserSettings.role=Szerep adminUserSettings.role=Szerep
adminUserSettings.actions=Műveletek adminUserSettings.actions=Műveletek
adminUserSettings.apiUser=Korlátozott API-felhasználó adminUserSettings.apiUser=Korlátozott API-felhasználó
adminUserSettings.extraApiUser=Additional Limited API User adminUserSettings.extraApiUser=További korlátozott API felhasználó
adminUserSettings.webOnlyUser=Csak webes felhasználó adminUserSettings.webOnlyUser=Csak webes felhasználó
adminUserSettings.demoUser=Demo User (No custom settings) adminUserSettings.demoUser=Demofelhasználó (nincs egyedi beállítás)
adminUserSettings.internalApiUser=Internal API User adminUserSettings.internalApiUser=Belső API felhasználó
adminUserSettings.forceChange=Kényszerítse a felhasználót a felhasználónév/jelszó megváltoztatására bejelentkezéskor adminUserSettings.forceChange=Kényszerítse a felhasználót a felhasználónév/jelszó megváltoztatására bejelentkezéskor
adminUserSettings.submit=Felhasználó mentése adminUserSettings.submit=Felhasználó mentése
adminUserSettings.changeUserRole=Felhasználó szerepkörének módosítása adminUserSettings.changeUserRole=Felhasználó szerepkörének módosítása
adminUserSettings.authenticated=Authenticated adminUserSettings.authenticated=Bejelentkezett
adminUserSettings.editOwnProfil=Edit own profile adminUserSettings.editOwnProfil=Saját profil szerkesztése
adminUserSettings.enabledUser=enabled user adminUserSettings.enabledUser=Engedélyezett felhasználó
adminUserSettings.disabledUser=disabled user adminUserSettings.disabledUser=Letiltott felhasználó
adminUserSettings.activeUsers=Active Users: adminUserSettings.activeUsers=Aktív Felhasználók:
adminUserSettings.disabledUsers=Disabled Users: adminUserSettings.disabledUsers=Letiltott Felhasználók:
adminUserSettings.totalUsers=Total Users: adminUserSettings.totalUsers=Összes Felhasználó:
adminUserSettings.lastRequest=Last Request adminUserSettings.lastRequest=Utolsó kérelem
database.title=Database Import/Export database.title=Adatbázis import/export
database.header=Database Import/Export database.header=Adatbázis import/export
database.fileName=File Name database.fileName=Fájlnév
database.creationDate=Creation Date database.creationDate=Létrehozás dátuma
database.fileSize=File Size database.fileSize=Fájlszámítás
database.deleteBackupFile=Delete Backup File database.deleteBackupFile=Visszaulasztó fájl törlése
database.importBackupFile=Import Backup File database.importBackupFile=Bemérsz visszaulastó fájl
database.downloadBackupFile=Download Backup File database.downloadBackupFile=Bemérő fájlet letöltés
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application. database.info_1=A bemeneti adatok bemérésekor fontos, hogy az helyes struktúrát biztosítsa. Ha nem tudja mit csinál, kérjen támogatást egy szakembertől. Az erőforrás hibája okozhat alkalmazás-ismerséleti gondokat, és viszontig, hogy az alkalmazás teljesen nem fut.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention. database.info_2=A fájl neve nem jelent részt a feltöltés során. Később újra néven lesz átalakítva egy konzisztens nevésrendszert követve, a formátum: visszaulasztó_user_yyyyMMddHHmm.sql.
database.submit=Import Backup database.submit=Bemérsz visszaulastó fájl
database.importIntoDatabaseSuccessed=Import into database successed database.importIntoDatabaseSuccessed=Adatbázisba importálva sikeresen
database.fileNotFound=File not Found database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=Fájlnull vagy üres nélkül nem lehet folytatni
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again. session.expired=A munkamenet letelezett. Frissítse a lapot és próbálkozzon újra.
session.refreshPage=Refresh Page
############# #############
# HOME-PAGE # # HOME-PAGE #
@@ -378,9 +383,9 @@ home.removeBlanks.title=Üres lapok eltávolítása
home.removeBlanks.desc=Felismeri és eltávolítja az üres lapokat a dokumentumból home.removeBlanks.desc=Felismeri és eltávolítja az üres lapokat a dokumentumból
removeBlanks.tags=takarítás,egyszerűsítés,nem-tartalom,szervez removeBlanks.tags=takarítás,egyszerűsítés,nem-tartalom,szervez
home.removeAnnotations.title=Remove Annotations home.removeAnnotations.title=Kijelölések eltávolítása
home.removeAnnotations.desc=Removes all comments/annotations from a PDF home.removeAnnotations.desc=Egy PDF-től minden megjegyzés/mérlegelt elemét törli ki
removeAnnotations.tags=comments,highlight,notes,markup,remove removeAnnotations.tags=megjegyzések, kiemelés, jegyzetek, módosítások, törlés
home.compare.title=Összehasonlítás home.compare.title=Összehasonlítás
home.compare.desc=Összehasonlítja és megmutatja a különbségeket két PDF dokumentum között home.compare.desc=Összehasonlítja és megmutatja a különbségeket két PDF dokumentum között
@@ -390,9 +395,9 @@ home.certSign.title=Aláírás Tanúsítvánnyal
home.certSign.desc=PDF aláírása tanúsítvánnyal/kulccsal (PEM/P12) home.certSign.desc=PDF aláírása tanúsítvánnyal/kulccsal (PEM/P12)
certSign.tags=hitelesítés,PEM,P12,hivatalos,segitít,álca certSign.tags=hitelesítés,PEM,P12,hivatalos,segitít,álca
home.removeCertSign.title=Remove Certificate Sign home.removeCertSign.title=Tanúsítványi aláírás eltávolítása
home.removeCertSign.desc=Remove certificate signature from PDF home.removeCertSign.desc=A PDF-től a tanúsítványi aláíratot törli ki
removeCertSign.tags=authenticate,PEM,P12,official,decrypt removeCertSign.tags=hitelesítés, PEM, P12, szakmai, dekriptálás
home.pageLayout.title=Több oldal elrendezése home.pageLayout.title=Több oldal elrendezése
home.pageLayout.desc=Több oldal egyesítése egy PDF dokumentumban egyetlen oldallá home.pageLayout.desc=Több oldal egyesítése egy PDF dokumentumban egyetlen oldallá
@@ -418,7 +423,7 @@ home.adjust-contrast.title=Színek/Kontraszt beállítása
home.adjust-contrast.desc=PDF kontrasztjának, telítettségének és világosságának beállítása home.adjust-contrast.desc=PDF kontrasztjának, telítettségének és világosságának beállítása
adjust-contrast.tags=szín-korrekció,beállítás,módosítás,fokoz adjust-contrast.tags=szín-korrekció,beállítás,módosítás,fokoz
home.crop.title=Crop PDF home.crop.title=PDF vágása
home.crop.desc=PDF vágása a méret csökkentése érdekében (a szöveg megőrzése mellett!) home.crop.desc=PDF vágása a méret csökkentése érdekében (a szöveg megőrzése mellett!)
crop.tags=vágás,csökkentés,szerkesztés,forma crop.tags=vágás,csökkentés,szerkesztés,forma
@@ -467,7 +472,7 @@ home.autoRedact.title=Automatikus Elrejtés
home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján
autoRedact.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett autoRedact.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
home.tableExtraxt.title=PDF to CSV home.tableExtraxt.title=PDF-től CSV-be való átalakítás
home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva
tableExtraxt.tags=CSV,Táblázat kinyerése,kinyer,konvertál tableExtraxt.tags=CSV,Táblázat kinyerése,kinyer,konvertál
@@ -485,46 +490,46 @@ home.split-by-sections.title=PDF Szakaszokra osztása
home.split-by-sections.desc=Minden oldal felosztása kisebb vízszintes és függőleges szakaszokra home.split-by-sections.desc=Minden oldal felosztása kisebb vízszintes és függőleges szakaszokra
split-by-sections.tags=Szakasz elosztás, felosztás, testreszabás split-by-sections.tags=Szakasz elosztás, felosztás, testreszabás
home.AddStampRequest.title=Add Stamp to PDF home.AddStampRequest.title=Stempel hozzáadása PDF-be
home.AddStampRequest.desc=Add text or add image stamps at set locations home.AddStampRequest.desc=Addja a szövegét vagy képkép stempelésekbe a megadott helyekre
AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize AddStampRequest.tags=Stempel, kép hozzáadása, középső rendítés, csatorna, PDF, beágyazás, személyre szokásos
home.PDFToBook.title=PDF to Book home.PDFToBook.title=PDF to könyv
home.PDFToBook.desc=Converts PDF to Book/Comic formats using calibre home.PDFToBook.desc=A calibre segítségével PDF fájlt könyvtár/szókincs formátumba alakít.
PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.BookToPDF.title=Book to PDF home.BookToPDF.title=Könyv a PDF-be
home.BookToPDF.desc=Converts Books/Comics formats to PDF using calibre home.BookToPDF.desc=A calibre segítségével könyvtár/szókincs fájlt PDF-be alakít.
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Remove image home.removeImagePdf.title=Kép törölése
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Törlés a képből a fájl méret csökkentéséhez
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Kép törlése, oldalszerkezet műveletek, háttér műveletek, kiszolgálói oldal
home.splitPdfByChapters.title=Split PDF by Chapters home.splitPdfByChapters.title=PDF felosztása fejezetek szerint
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure. home.splitPdfByChapters.desc=Fejezetei alapján egy PDF fájl több dokumentumba osztás.
splitPdfByChapters.tags=split,chapters,bookmarks,organize splitPdfByChapters.tags=Osztás, fejezetek, jelezes, organizálás
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Visszaalakítás-összevétel a színekkel PDF-ben
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Cserélje le a szöveg és háttér színét PDF-ben és visszaalakítja a teljes színt az eszköz méret csökkentéséhez
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Szín cseréje, oldalszerkezet műveletek, kiszolgálói oldal
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Cserélés-visszaalakítási opciók
replace-color.selectText.2=Default(Default high contrast colors) replace-color.selectText.2=Alapértelmezett (Alacsony kontrastos színek)
replace-color.selectText.3=Custom(Customized colors) replace-color.selectText.3=Egyéni (Egyéni színok)
replace-color.selectText.4=Full-Invert(Invert all colors) replace-color.selectText.4=Összevétel Összesen (Mind a színeket visszaalakítja)
replace-color.selectText.5=High contrast color options replace-color.selectText.5=Alacsony kontrastos szín opciók
replace-color.selectText.6=white text on black background replace-color.selectText.6=fehér szöveg fekete háttérre
replace-color.selectText.7=Black text on white background replace-color.selectText.7=fekete szöveg fehére háttérre
replace-color.selectText.8=Yellow text on black background replace-color.selectText.8=pálva szöveg fekete háttérre
replace-color.selectText.9=Green text on black background replace-color.selectText.9=zöld szöveg fekete háttérre
replace-color.selectText.10=Choose text Color replace-color.selectText.10=Válasszon színet a szövékre
replace-color.selectText.11=Choose background Color replace-color.selectText.11=Válassza a háttérszínt
replace-color.submit=Replace replace-color.submit=Cseréljön le
@@ -543,18 +548,17 @@ login.locked=A fiókja zárolva lett!
login.signinTitle=Kérjük, jelentkezzen be! login.signinTitle=Kérjük, jelentkezzen be!
login.ssoSignIn=Bejelentkezés egyszeri bejelentkezéssel login.ssoSignIn=Bejelentkezés egyszeri bejelentkezéssel
login.oauth2AutoCreateDisabled=OAUTH2 Felhasználó automatikus létrehozása letiltva login.oauth2AutoCreateDisabled=OAUTH2 Felhasználó automatikus létrehozása letiltva
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator. login.oauth2AdminBlockedUser=A nevű felhasználók regisztrációja vagy bejelentkezése megszakítva. Kérjen segítséget a rendszergazdától.
login.oauth2RequestNotFound=Authorization request not found login.oauth2RequestNotFound=Hozzájárulási kérést nem találtunk
login.oauth2InvalidUserInfoResponse=Invalid User Info Response login.oauth2InvalidUserInfoResponse=Érvénytelen felhasználói információs válasz
login.oauth2invalidRequest=Invalid Request login.oauth2invalidRequest=Érvénytelen kérelem
login.oauth2AccessDenied=Access Denied login.oauth2AccessDenied=Hozzáférés megtagadva
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Érvénytelen token-válasz
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Érvénytelen azonosító token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=A felhasználó deaktivált, a bejelentkezés jelenleg megszakítva ezzel a felhasználónévvel. Kérjen segítséget a rendszergazdától.
login.alreadyLoggedIn=You are already logged in to login.alreadyLoggedIn=Már be van jelentkezve az
login.alreadyLoggedIn2=devices. Please log out of the devices and try again. login.alreadyLoggedIn2=eszközökre. Kijelentkezzen ezekből a eszközökből, majd próbálja újra bejelentkezni.
login.toManySessions=You have too many active sessions login.toManySessions=Túl sok aktív munkamenet
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Érzékeny tartalom eltávolítása autoRedact.title=Érzékeny tartalom eltávolítása
@@ -586,7 +590,7 @@ pdfToSinglePage.submit=Átalakítás egyetlen oldallá
pageExtracter.title=Oldalak kinyerése pageExtracter.title=Oldalak kinyerése
pageExtracter.header=Oldalak kinyerése pageExtracter.header=Oldalak kinyerése
pageExtracter.submit=Kinyerés pageExtracter.submit=Kinyerés
pageExtracter.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1) pageExtracter.placeholder=(pl. 1,2,8 vagy 4,7,12-16 vagy 2n-1)
#getPdfInfo #getPdfInfo
@@ -618,37 +622,37 @@ HTMLToPDF.header=HTML >> PDF
HTMLToPDF.help=Elfogad HTML fájlokat és ZIP-fájlokat, amelyek tartalmaznak html/css/képeket stb. HTMLToPDF.help=Elfogad HTML fájlokat és ZIP-fájlokat, amelyek tartalmaznak html/css/képeket stb.
HTMLToPDF.submit=Átalakítás HTMLToPDF.submit=Átalakítás
HTMLToPDF.credit=WeasyPrint alkalmazása HTMLToPDF.credit=WeasyPrint alkalmazása
HTMLToPDF.zoom=Zoom level for displaying the website. HTMLToPDF.zoom=Oldalnéző szint a weboldal megjelenítésére.
HTMLToPDF.pageWidth=Width of the page in centimeters. (Blank to default) HTMLToPDF.pageWidth=Oldal szélessége centiméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.pageHeight=Height of the page in centimeters. (Blank to default) HTMLToPDF.pageHeight=Oldal magassága centiméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.marginTop=Top margin of the page in millimeters. (Blank to default) HTMLToPDF.marginTop=Oldal felső marginalása milliméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.marginBottom=Bottom margin of the page in millimeters. (Blank to default) HTMLToPDF.marginBottom=Oldal alsó marginalása milliméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.marginLeft=Left margin of the page in millimeters. (Blank to default) HTMLToPDF.marginLeft=Oldal bal oldali marginalása milliméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.marginRight=Right margin of the page in millimeters. (Blank to default) HTMLToPDF.marginRight=Oldal jobb oldali marginalása milliméterben. (Törlés esetén az alapértelmezett érték lesz)
HTMLToPDF.printBackground=Render the background of websites. HTMLToPDF.printBackground=Oldalsáv háttérét nyomtatásra jelenítse meg.
HTMLToPDF.defaultHeader=Enable Default Header (Name and page number) HTMLToPDF.defaultHeader=Alapértelmezett fejléc (Nevezés és oldal szám) engedélyezése
HTMLToPDF.cssMediaType=Change the CSS media type of the page. HTMLToPDF.cssMediaType=Oldal CSS média típusának módosítása.
HTMLToPDF.none=None HTMLToPDF.none=Nincs
HTMLToPDF.print=Print HTMLToPDF.print=Nyomtatás
HTMLToPDF.screen=Screen HTMLToPDF.screen=Élő képernyő
#AddStampRequest #AddStampRequest
AddStampRequest.header=Stamp PDF AddStampRequest.header=Stempel PDF-be
AddStampRequest.title=Stamp PDF AddStampRequest.title=Stempel PDF-be
AddStampRequest.stampType=Stamp Type AddStampRequest.stampType=Stempel típusa
AddStampRequest.stampText=Stamp Text AddStampRequest.stampText=Stempel szövege
AddStampRequest.stampImage=Stamp Image AddStampRequest.stampImage=Stempel képsora
AddStampRequest.alphabet=Alphabet AddStampRequest.alphabet=Alphabet
AddStampRequest.fontSize=Font/Image Size AddStampRequest.fontSize=Betűméret/stépésnév
AddStampRequest.rotation=Rotation AddStampRequest.rotation=Fordítás
AddStampRequest.opacity=Opacity AddStampRequest.opacity=Átlátszathossz
AddStampRequest.position=Position AddStampRequest.position=Pozíció
AddStampRequest.overrideX=Override X Coordinate AddStampRequest.overrideX=Överrite X koordinátája
AddStampRequest.overrideY=Override Y Coordinate AddStampRequest.overrideY=Överrite Y koordinátája
AddStampRequest.customMargin=Custom Margin AddStampRequest.customMargin=Egyéni mezők marginalája
AddStampRequest.customColor=Custom Text Color AddStampRequest.customColor=Egyéni szövegszín
AddStampRequest.submit=Submit AddStampRequest.submit=Küldés
#sanitizePDF #sanitizePDF
@@ -694,7 +698,7 @@ adjustContrast.download=Letöltés
#crop #crop
crop.title=Körülvágás crop.title=Körülvágás
crop.header=Crop PDF crop.header=PDF kivágása
crop.submit=Elküldés crop.submit=Elküldés
@@ -729,7 +733,7 @@ pageLayout.submit=Elküldés
scalePages.title=Oldalméret beállítása scalePages.title=Oldalméret beállítása
scalePages.header=Oldalméret beállítása scalePages.header=Oldalméret beállítása
scalePages.pageSize=A dokumentum egy oldalának mérete. scalePages.pageSize=A dokumentum egy oldalának mérete.
scalePages.keepPageSize=Original Size scalePages.keepPageSize=Váltás az eredeti méretre
scalePages.scaleFactor=Az oldal nagyításának szintje (vágás). scalePages.scaleFactor=Az oldal nagyításának szintje (vágás).
scalePages.submit=Küldés scalePages.submit=Küldés
@@ -738,25 +742,26 @@ scalePages.submit=Küldés
certSign.title=Tanúsítvánnyal történő aláírás certSign.title=Tanúsítvánnyal történő aláírás
certSign.header=Aláírás PDF tanúsítvánnyal (fejlesztés alatt) certSign.header=Aláírás PDF tanúsítvánnyal (fejlesztés alatt)
certSign.selectPDF=Válasszon PDF fájlt az aláíráshoz: certSign.selectPDF=Válasszon PDF fájlt az aláíráshoz:
certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below. certSign.jksNote=Megjegyzés: Ha a tanúsítvány típusa nem szerepel a fenti listában, konvertálja Java Keystore (.jks) formátumba a keytool parancssor segítségével. Válassza az alábbi .jks vagy .keystore fájl opciót.
certSign.selectKey=Válassza ki a saját kulcsfájlját (PKCS#8 formátum, lehet .pem vagy .der kiterjesztésű): certSign.selectKey=Válassza ki a saját kulcsfájlját (PKCS#8 formátum, lehet .pem vagy .der kiterjesztésű):
certSign.selectCert=Válassza ki a tanúsítványfájlját (X.509 formátum, lehet .pem vagy .der kiterjesztésű): certSign.selectCert=Válassza ki a tanúsítványfájlját (X.509 formátum, lehet .pem vagy .der kiterjesztésű):
certSign.selectP12=Válassza ki a PKCS#12 kulcstár fájlját (.p12 vagy .pfx) (Opcionális, ha rendelkezésre áll, tartalmaznia kell a privát kulcsot és a tanúsítványt.): certSign.selectP12=Válassza ki a PKCS#12 kulcstár fájlját (.p12 vagy .pfx) (Opcionális, ha rendelkezésre áll, tartalmaznia kell a privát kulcsot és a tanúsítványt.):
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore): certSign.selectJKS=Java Keystore-fájl választása (.jks vagy .keystore):
certSign.certType=Tanúsítvány típusa certSign.certType=Tanúsítvány típusa
certSign.password=Adja meg a kulcstár vagy a privát kulcs jelszavát (ha van): certSign.password=Adja meg a kulcstár vagy a privát kulcs jelszavát (ha van):
certSign.showSig=Aláírás megjelenítése certSign.showSig=Aláírás megjelenítése
certSign.reason=Ok certSign.reason=Ok
certSign.location=Hely certSign.location=Hely
certSign.name=Név certSign.name=Név
certSign.showLogo=Logó megjelenítése
certSign.submit=PDF aláírása certSign.submit=PDF aláírása
#removeCertSign #removeCertSign
removeCertSign.title=Remove Certificate Signature removeCertSign.title=Tanúsítvány aláírás eltávolítása
removeCertSign.header=Remove the digital certificate from the PDF removeCertSign.header=PDF-ből törölje a digitális tanúsítványt
removeCertSign.selectPDF=Select a PDF file: removeCertSign.selectPDF=PDF fájl kiválasztása:
removeCertSign.submit=Remove Signature removeCertSign.submit=Aláírást törlés
#removeBlanks #removeBlanks
@@ -770,32 +775,35 @@ removeBlanks.submit=Üres oldalak eltávolítása
#removeAnnotations #removeAnnotations
removeAnnotations.title=Remove Annotations removeAnnotations.title=Számítógépes bejegyzések törlése
removeAnnotations.header=Remove Annotations removeAnnotations.header=Számítógépes bejegyzések törlése
removeAnnotations.submit=Remove removeAnnotations.submit=Töröl
#compare #compare
compare.title=Összehasonlítás compare.title=Összehasonlítás
compare.header=PDF-ek összehasonlítása compare.header=PDF-ek összehasonlítása
compare.highlightColor.1=Highlight Color 1: compare.highlightColor.1=Kötłówiteli szín 1:
compare.highlightColor.2=Highlight Color 2: compare.highlightColor.2=Kijelzési szín 2:
compare.document.1=Dokumentum 1 compare.document.1=Dokumentum 1
compare.document.2=Dokumentum 2 compare.document.2=Dokumentum 2
compare.submit=Összehasonlítás compare.submit=Összehasonlítás
compare.complex.message=Egy vagy mindkét kiválasztott dokumentum nagy, az összehasonlítás precizégének csökkenhet.
compare.large.file.message=Egy vagy mindkét kiválasztott dokumentum túl nagy a feldolgozáshoz.
compare.no.text.message=Egy vagy mindkét kiválasztott PDF nincs szöveggal. Kérjük, válasszon szöveg tartalmazó PDF-t.
#BookToPDF #BookToPDF
BookToPDF.title=Books and Comics to PDF BookToPDF.title=Könyvek és kézirattak PDF-be
BookToPDF.header=Book to PDF BookToPDF.header=Könyv to PDF
BookToPDF.credit=Uses Calibre BookToPDF.credit=Használja a Calibre-t
BookToPDF.submit=Convert BookToPDF.submit=Konvertálás
#PDFToBook #PDFToBook
PDFToBook.title=PDF to Book PDFToBook.title=PDF-ből könyv
PDFToBook.header=PDF to Book PDFToBook.header=PDF to Book
PDFToBook.selectText.1=Format PDFToBook.selectText.1=Formátum
PDFToBook.credit=Uses Calibre PDFToBook.credit=Használja a Calibre-t
PDFToBook.submit=Convert PDFToBook.submit=Konvertálás
#sign #sign
sign.title=Aláírás sign.title=Aláírás
@@ -805,6 +813,11 @@ sign.draw=Aláírás rajzolása
sign.text=Szöveg beírása sign.text=Szöveg beírása
sign.clear=Törlés sign.clear=Törlés
sign.add=Hozzáadás sign.add=Hozzáadás
sign.saved=Mentett aláírások
sign.save=Aláíráshoz mentés
sign.personalSigs=Személyi aláíráshoz
sign.sharedSigs=Megosztott aláíráshoz
sign.noSavedSigs=Nincsenek mentett aláírások találat
#repair #repair
@@ -816,7 +829,7 @@ repair.submit=Javítás
#flatten #flatten
flatten.title=Kiegyenlítés flatten.title=Kiegyenlítés
flatten.header=PDF-ek kiegyenlítése flatten.header=PDF-ek kiegyenlítése
flatten.flattenOnlyForms=Flatten only forms flatten.flattenOnlyForms=Csak formákat átalakít
flatten.submit=Kiegyenlítés flatten.submit=Kiegyenlítés
@@ -831,7 +844,7 @@ ScannerImageSplit.selectText.7=Minimális kontúr terület:
ScannerImageSplit.selectText.8=A fotók minimális kontúrterületének beállítása ScannerImageSplit.selectText.8=A fotók minimális kontúrterületének beállítása
ScannerImageSplit.selectText.9=Keret mérete: ScannerImageSplit.selectText.9=Keret mérete:
ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1). ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1).
ScannerImageSplit.info=Python is not installed. It is required to run. ScannerImageSplit.info=A Python nincs telepítve. Összefogóként szükséges.
#OCR #OCR
@@ -858,7 +871,7 @@ ocr.submit=PDF feldolgozása OCR-rel
extractImages.title=Képek kinyerése extractImages.title=Képek kinyerése
extractImages.header=Képek kinyerése extractImages.header=Képek kinyerése
extractImages.selectText=Válassza ki a képformátumot a kinyert képek konvertálásához extractImages.selectText=Válassza ki a képformátumot a kinyert képek konvertálásához
extractImages.allowDuplicates=Save duplicate images extractImages.allowDuplicates=Duplikált képek mentése
extractImages.submit=Kinyerés extractImages.submit=Kinyerés
@@ -866,7 +879,7 @@ extractImages.submit=Kinyerés
fileToPDF.title=Fájl PDF dokumentummá alakítása fileToPDF.title=Fájl PDF dokumentummá alakítása
fileToPDF.header=Konvertáljon bármilyen fájlt PDF dokumentummá fileToPDF.header=Konvertáljon bármilyen fájlt PDF dokumentummá
fileToPDF.credit=Ez a szolgáltatás a LibreOffice-t és az Unoconv-ot használja a fájlkonverzióhoz. fileToPDF.credit=Ez a szolgáltatás a LibreOffice-t és az Unoconv-ot használja a fájlkonverzióhoz.
fileToPDF.supportedFileTypesInfo=Supported File types fileToPDF.supportedFileTypesInfo=Támogatott fájltípusok
fileToPDF.supportedFileTypes=A funkció az alábbi fájltípusokat támogatja, azonban a teljesen friss támogatott formátumok listájáért kérjük, tekintse meg a LibreOffice dokumentációját fileToPDF.supportedFileTypes=A funkció az alábbi fájltípusokat támogatja, azonban a teljesen friss támogatott formátumok listájáért kérjük, tekintse meg a LibreOffice dokumentációját
fileToPDF.submit=Konvertálás PDF dokumentummá fileToPDF.submit=Konvertálás PDF dokumentummá
@@ -896,7 +909,7 @@ merge.title=Összevonás
merge.header=Több PDF összevonása (2+) merge.header=Több PDF összevonása (2+)
merge.sortByName=Név szerinti rendezés merge.sortByName=Név szerinti rendezés
merge.sortByDate=Dátum szerinti rendezés merge.sortByDate=Dátum szerinti rendezés
merge.removeCertSign=Remove digital signature in the merged file? merge.removeCertSign=Eltávolítja a megyérismereteket az összefuzött fájlban?
merge.submit=Összevonás merge.submit=Összevonás
@@ -904,24 +917,35 @@ merge.submit=Összevonás
pdfOrganiser.title=Oldalszervező pdfOrganiser.title=Oldalszervező
pdfOrganiser.header=PDF Oldalszervező pdfOrganiser.header=PDF Oldalszervező
pdfOrganiser.submit=Oldalak átrendezése pdfOrganiser.submit=Oldalak átrendezése
pdfOrganiser.mode=Mode pdfOrganiser.mode=Mód
pdfOrganiser.mode.1=Custom Page Order pdfOrganiser.mode.1=Törzsbeírás szabályos sorrend
pdfOrganiser.mode.2=Reverse Order pdfOrganiser.mode.2=Fordított sorrend
pdfOrganiser.mode.3=Duplex Sort pdfOrganiser.mode.3=Dupla oldal rendezés
pdfOrganiser.mode.4=Booklet Sort pdfOrganiser.mode.4=Könyvrész letrehozása rendezés
pdfOrganiser.mode.5=Side Stitch Booklet Sort pdfOrganiser.mode.5=Oldalsarkatásos könyvrész letrehozása rendezés
pdfOrganiser.mode.6=Odd-Even Split pdfOrganiser.mode.6=Tökéletes páratlan-páros split
pdfOrganiser.mode.7=Remove First pdfOrganiser.mode.7=Először is eltávolítanunk
pdfOrganiser.mode.8=Remove Last pdfOrganiser.mode.8=Utolsó törölése
pdfOrganiser.mode.9=Remove First and Last pdfOrganiser.mode.9=Először és utolsó törlése
pdfOrganiser.mode.10=Odd-Even Merge pdfOrganiser.mode.10=Tökéletes páratlan-páros összekeverés
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1) pdfOrganiser.placeholder=(pl.: 1,3,2 vagy 4-8,2,10-12 vagy 2n-1)
#multiTool #multiTool
multiTool.title=PDF többfunkciós eszköz multiTool.title=PDF többfunkciós eszköz
multiTool.header=PDF többfunkciós eszköz multiTool.header=PDF többfunkciós eszköz
multiTool.uploadPrompts=File Name multiTool.uploadPrompts=Fájl neve
multiTool.selectAll=Select All
multiTool.deselectAll=Deselect All
multiTool.selectPages=Page Select
multiTool.selectedPages=Selected Pages
multiTool.page=Page
multiTool.deleteSelected=Delete Selected
multiTool.downloadAll=Export
multiTool.downloadSelected=Export Selected
#multiTool-advert
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
#view pdf #view pdf
viewPdf.title=PDF megtekintése viewPdf.title=PDF megtekintése
@@ -932,7 +956,7 @@ pageRemover.title=Oldaltörlő
pageRemover.header=PDF oldaltörlő pageRemover.header=PDF oldaltörlő
pageRemover.pagesToDelete=Törlendő oldalak (adja meg az oldalszámok vesszővel elválasztott listáját): pageRemover.pagesToDelete=Törlendő oldalak (adja meg az oldalszámok vesszővel elválasztott listáját):
pageRemover.submit=Oldalak törlése pageRemover.submit=Oldalak törlése
pageRemover.placeholder=(e.g. 1,2,6 or 1-10,15-30) pageRemover.placeholder=(pl.: 1,2,6 vagy 1-10,15-30)
#rotate #rotate
@@ -983,7 +1007,7 @@ pdfToImage.color=színes
pdfToImage.grey=szürkeárnyalatos pdfToImage.grey=szürkeárnyalatos
pdfToImage.blackwhite=fekete-fehér (adatvesztéssel járhat!) pdfToImage.blackwhite=fekete-fehér (adatvesztéssel járhat!)
pdfToImage.submit=Átalakítás pdfToImage.submit=Átalakítás
pdfToImage.info=Python is not installed. Required for WebP conversion. pdfToImage.info=Nincs telepítve a Python. Szükséges a WebP konverzióhoz.
#addPassword #addPassword
@@ -1020,10 +1044,10 @@ watermark.selectText.6=heightSpacer (Hely a vízjelek között függőlegesen):
watermark.selectText.7=Átlátszóság (0% - 100%): watermark.selectText.7=Átlátszóság (0% - 100%):
watermark.selectText.8=Vízjel típusa: watermark.selectText.8=Vízjel típusa:
watermark.selectText.9=Vízjel képe: watermark.selectText.9=Vízjel képe:
watermark.selectText.10=Convert PDF to PDF-Image watermark.selectText.10=PDF-t PDF-ra átalakítás
watermark.submit=Vízjel hozzáadása watermark.submit=Vízjel hozzáadása
watermark.type.1=Text watermark.type.1=Szöveg
watermark.type.2=Image watermark.type.2=Kép
#Change permissions #Change permissions
@@ -1075,9 +1099,9 @@ pdfToPDFA.title=PDF >> PDF/A
pdfToPDFA.header=PDF >> PDF/A pdfToPDFA.header=PDF >> PDF/A
pdfToPDFA.credit=Ez a szolgáltatás az ghostscript-t használja a PDF/A konverzióhoz pdfToPDFA.credit=Ez a szolgáltatás az ghostscript-t használja a PDF/A konverzióhoz
pdfToPDFA.submit=Konvertálás pdfToPDFA.submit=Konvertálás
pdfToPDFA.tip=Currently does not work for multiple inputs at once pdfToPDFA.tip=Jelenleg egyszerre több fájl nem működik ezzel a funkcióval
pdfToPDFA.outputFormat=Output format pdfToPDFA.outputFormat=Kimeneti formátum
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step. pdfToPDFA.pdfWithDigitalSignature=A PDF tartalmaz digitális alásszegyeztetést. Ez lesz eltávolítva az alábbi lépésben.
#PDFToWord #PDFToWord
@@ -1159,67 +1183,65 @@ split-by-sections.vertical.label=Vízszintes szakaszok
split-by-sections.horizontal.placeholder=Adja meg a vízszintes szakaszok számát split-by-sections.horizontal.placeholder=Adja meg a vízszintes szakaszok számát
split-by-sections.vertical.placeholder=Adja meg a függőleges szakaszok számát split-by-sections.vertical.placeholder=Adja meg a függőleges szakaszok számát
split-by-sections.submit=Felosztás split-by-sections.submit=Felosztás
split-by-sections.merge=Merge Into One PDF split-by-sections.merge=Egyesítsük a dokumentumokat egybe
#printFile #printFile
printFile.title=Print File printFile.title=Fájl kinyomtatása
printFile.header=Print File to Printer printFile.header=Fájlt nyomtatás a számítógépes kiíróra
printFile.selectText.1=Select File to Print printFile.selectText.1=Válasszon ki a kinyomtatandó fájlt
printFile.selectText.2=Enter Printer Name printFile.selectText.2=Add meg a kiíró nevét
printFile.submit=Print printFile.submit=Nyomtatás
#licenses #licenses
licenses.nav=Licenses licenses.nav=Licenses
licenses.title=3rd Party Licenses licenses.title=3rd Party Licenses
licenses.header=3rd Party Licenses licenses.header=3rd Party Licenses
licenses.module=Module licenses.module=Modul
licenses.version=Version licenses.version=Verzió
licenses.license=License licenses.license=License
#survey #survey
survey.nav=Survey survey.nav=Kérdőív
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Kérdőív
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=A Stirling-PDF nincs bejelentkezési adatokat tároló funkciója miatt szeretnénk a felhasználóink véleményét gyűjteni, hogy javítsuk meg a Stirling-PDF-t!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here: survey.changes=A Stirling-PDF változásai a visszaérkező kérdőív után! További információért látogasson el az alábbi blogfelsorolást.
survey.changes2=With these changes we are getting paid business support and funding survey.changes2=Ezek a változtatások során kapunk fizetendő üzleti támogatást és finanszírozást
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(A kérdőív bejelentkezés nélküli megjelenése le lesz tilos további frissítések után, de folyamatosan elérhető a oldal tetején)
survey.button=Take Survey survey.button=Kérdőív végrehajtása
survey.dontShowAgain=Don't show again survey.dontShowAgain=Más nincs mutatni ugyanarra a képernyőre
#error #error
error.sorry=Sorry for the issue! error.sorry=Sajnáljuk, hogy probléma van!
error.needHelp=Need help / Found an issue? error.needHelp=Segítségüket kérünk! / Hiba találkoztak?
error.contactTip=If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord: error.contactTip=Ha további nehézségekkel találkozna, ne szudirmáld a segítségre kérését. A GitHub oldalán egy típusot is lehet kiküldeni, vagy a Discordban kapcsolatba lépheted veleink:
error.404.head=404 - Page Not Found | Oops, we tripped in the code! error.404.head=404 - Nincs ilyen oldal | Sajnáljuk, hogy valami meghibásodott!
error.404.1=We can't seem to find the page you're looking for. error.404.1=Nem tudom megkerülni az oldalt, amit keresed.
error.404.2=Something went wrong error.404.2=Valami meghibásodott
error.github=Submit a ticket on GitHub error.github=Típusot kiküldheted a GitHub-on
error.showStack=Show Stack Trace error.showStack=Lássuk meg a sorozatot
error.copyStack=Copy Stack Trace error.copyStack=Kövesse a sorozat másolását
error.githubSubmit=GitHub - Submit a ticket error.githubSubmit=GitHub - Típus kiküldése
error.discordSubmit=Discord - Submit Support post error.discordSubmit=Discord - Jegyzettömb kijavítása
#remove-image #remove-image
removeImage.title=Remove image removeImage.title=Távolítsa el az kép
removeImage.header=Remove image removeImage.header=Távolítsa el a képet
removeImage.removeImage=Remove image removeImage.removeImage=Távolítsa el a képet
removeImage.submit=Remove image removeImage.submit=Távolítsa el a képet
splitByChapters.title=Split PDF by Chapters splitByChapters.title=PDF fájlt fejezések szerint bontson fel
splitByChapters.header=Split PDF by Chapters splitByChapters.header=PDF fájlt fejezések szerint bontson fel
splitByChapters.bookmarkLevel=Bookmark Level splitByChapters.bookmarkLevel=Fejezet címkézése szintje
splitByChapters.includeMetadata=Include Metadata splitByChapters.includeMetadata=Metadata beleszerkesztése
splitByChapters.allowDuplicates=Allow Duplicates splitByChapters.allowDuplicates=Duplikációk engedélyezése
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure. splitByChapters.desc.1=Ez az eszköz osztja fel a PDF-fájlt szövegszerkezet alapján lévő több fájlra.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.). splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF. splitByChapters.desc.3=Metaadatok belefoglalása: Ha bevanítva van, az eredeti PDF fájl metaadatai megtartódnak minden osztott fájlban.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs. splitByChapters.desc.4=Duplikációk engedélyezése: Ha bevanítva van, lehetővé teszi a megadott oldalon lévő több kijelzőszint alapján új PDF-ek létrehozása.
splitByChapters.submit=Split PDF splitByChapters.submit=PDF osztás

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