Compare commits

...
Author SHA1 Message Date
albanobattistella ac88a952d5 Update messages_it_IT.properties (#4609)
# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 23:07:14 +01:00
Peter Dave Hello 42ed0f59ea Update zh_TW Traditional Chinese locale (#4615)
# Description of Changes

Update and improve the zh-TW Traditional Chinese translation

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings
2025-10-16 23:06:02 +01:00
Balázs Szücs 42f1fd543a refactor: remove unused imports (#4566)
# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2025-10-16 23:05:49 +01:00
Balázs Szücs 2ef89101c2 feat(pdf-info): refactor and add more info on attachments, images, forms, and give technical overview (#4643)
# Description of Changes

### UI and Summary Enhancements

* Added a "Technical Details" section to the PDF summary UI, displaying
information such as images, fonts, color spaces, form fields, embedded
files, JavaScript, layers, bookmarks, and multimedia. This includes new
HTML markup and corresponding translation string.
* Populated the new technical details fields in the summary using data
from the backend response, including logic to count and display images,
fonts, color spaces, form fields, embedded files, JavaScript scripts,
layers, bookmarks, and multimedia items.

### Refactor:

- Refactored getPdfInfo function (which was 400 lines) to multiple
manageable size functions

- Extract magic numbers to named constants:
  - `72` (PPI) should be a named constant like `POINTS_PER_INCH`
- `1.0f` (tolerance) should be a named constant like `DEFAULT_TOLERANCE`
- `5` (max logged errors) should be a named constant like
`MAX_LOGGED_ERRORS`
- Make the keyBuilder optimization for page prefixes effective
- Used `String.format()` for better readability in complex string
constructions
- Replace abbreviated variable names with descriptive alternatives:
  - `ap` (AccessPermission) → `accessPermission`
  - `is` (InputStream) → `inputStream` or `pdfInputStream`
- Improved attachment processing, and other features see below:



### Features:
#### Technical details overview:

<img width="658" height="737" alt="image"
src="https://github.com/user-attachments/assets/60d0658c-27f1-4a48-afbd-7f6a8594dffc"
/>

#### Form fields:

<img width="458" height="800" alt="image"
src="https://github.com/user-attachments/assets/d985b7e1-a9a2-4d27-a856-da8754fbb133"
/>

#### Embedded file new fields; MIME type, creation/modification date

<img width="506" height="794" alt="image"
src="https://github.com/user-attachments/assets/067eac9e-28b9-4659-af97-56c9a90cb0ec"
/>


#### Images:

<img width="658" height="247" alt="image"
src="https://github.com/user-attachments/assets/c915bd45-8de8-4ef0-95cc-04b2cd23bfdb"
/>

And few other more minor improvements.




<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2025-10-16 22:54:25 +01:00
Balázs Szücs 3a6c0c7722 feat(flatten): Add support for configuring rendering DPI in Flatten PDF feature (#4669)
# Description of Changes

Rendering on high DPI can needlessly increase the file size and
processing time, even when users would prefer smaller size, (with lesser
quality)

This PR adds support for configurable DPI, so that users can choose
their preferred balance between processing time/file size and quality.


**Backend logic and data model updates:**

* The `FlattenController` now processes an optional `renderDpi`
parameter from the request, using it to set the rendering DPI for each
page. It enforces minimum and maximum values based on system
configuration and ensures a sensible default if not provided.
* The `FlattenRequest` model has a new `renderDpi` field to carry the
requested DPI through the API and backend logic.

**User interface and documentation improvements:**

* The flatten form in `flatten.html` includes a new input field for DPI,
with validation and help text to guide users about its impact and usage.
* English resource messages have been updated to describe the new DPI
field and provide help text explaining its effects.

**UI:**
<img width="595" height="604" alt="image"
src="https://github.com/user-attachments/assets/f78a0401-0348-490b-920a-91475cab224b"
/>
**File size before after (100 DPI vs 500 DPI):**
<img width="493" height="141" alt="image"
src="https://github.com/user-attachments/assets/fe21bf79-a18f-4674-bbb5-c99b3d3bd7be"
/>
Sample used was originally 8 MB.

Sample used are attached here:


[image-doc-1.pdf](https://github.com/user-attachments/files/22889873/image-doc-1.pdf)

[image-doc-2.pdf](https://github.com/user-attachments/files/22889876/image-doc-2.pdf)

Strange stuff, I can personally _barely_ tell difference between 500 vs
100 DPI tbh, but the file size difference is very significant.


Closes: #4668

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2025-10-16 22:50:04 +01:00
tkymmm dbf0a4fdf4 Update messages_ja_JP.properties (#4663)
# Description of Changes

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 22:47:29 +01:00
stirlingbot[bot] 4f9a261e4c Update 3rd Party Licenses (#4532)
Auto-generated by stirlingbot[bot]

Signed-off-by: stirlingbot[bot] <stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-10-16 22:42:04 +01:00
Ludy 955a26f32b fix(security): Harden website-to-PDF conversion (#4638)
# Description of Changes

**What was changed**
- Fetch remote HTML content via `HttpClient` before invoking WeasyPrint
to inspect and sanitize input.
- Reject conversions when downloaded HTML contains disallowed `file:`
scheme references (including encoded/obfuscated variants) using a
compiled `Pattern`.
- Write fetched HTML to a secured temporary file and pass that path to
WeasyPrint instead of the remote URL.
- Provide `--base-url` to WeasyPrint so relative resources resolve
correctly while avoiding direct remote fetching as the primary input.
- Add comprehensive unit tests:
- Ensure command invocation uses local temp HTML + `--base-url` and
cleans up temp files.
  - Verify redirect with error when disallowed content is detected.
  - Cover temp file deletion behavior and error handling paths.
- Improve resource cleanup in `finally` blocks for both temp HTML and
output PDF artifacts.

**Why the change was made**
- Prevents traversal/local file exposure risks by blocking `file:` (and
encoded equivalents) discovered in fetched HTML.
- Reduces attack surface of URL-to-PDF by avoiding direct handing of
remote URLs to the renderer and enabling pre-validation.
- Strengthens deterministic behavior of conversions and improves safety
against SSRF-like vectors.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 22:41:04 +01:00
dependabot[bot] e40f41d79a build(deps): bump alpine from 3.22.1 to 3.22.2 (#4673)
Bumps alpine from 3.22.1 to 3.22.2.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=alpine&package-manager=docker&previous-version=3.22.1&new-version=3.22.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 22:40:27 +01:00
Ludy 9ed0283f15 fix(ci): 🛡️mitigate CVE-2025-8869 by pinning pip to patched commit and upgrading dev dependency pins (#4630)
# Description of Changes

**Summary**
- Enforce wheels-only installs for CI/dev workflows where feasible and
pin `pip` to a specific, patched VCS commit as an interim mitigation.
- Replace the explicit `pip==25.2` entry with a VCS-pinned `pip`
reference in `.github/scripts/requirements_dev.in` and the regenerated
`.github/scripts/requirements_dev.txt`.
- Refresh and re-hash multiple development dependency pins in the locked
`requirements_dev.txt` to ensure reproducible installs and reduce
exposure to vulnerable transitive packages.
- Add notes and guidance for maintainers on reverting the VCS pin once
an official pip release contains the fix.

**Why the change was made**
- CVE-2025-8869 allows malicious sdists to include links that escape the
intended extraction directory, enabling arbitrary file overwrite during
`pip install`. CI and developer automation that installs dev
dependencies are at risk if they process attacker-controlled sdists.
- This PR reduces immediate attack surface by preferring wheel
installations where possible and pinning pip to a known patched commit
until an official fixed pip release is available.


---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 22:40:14 +01:00
Ludy bd179579e6 fix(security): harden URL reachability to block SSRF to private/reserved networks and add unit tests (#4637)
# Description of Changes

- **What was changed**
- Introduced a stricter network safety check in
`GeneralUtils.isURLReachable(...)`:
- Block resolution to local, private, link-local, multicast, and
reserved ranges for both IPv4 and IPv6 (including IPv4-mapped and
IPv4-compatible IPv6).
- Added a DNS records cap (`MAX_DNS_ADDRESSES = 20`) to mitigate DNS
answer explosions and reduce SSRF blast radius.
    - Treat DNS resolution failures as unsafe (fail closed).
- Reject empty/invalid hosts early and disallow non-HTTP(S) protocols.
- Ensure `HttpURLConnection` is properly disconnected in a `finally`
block to avoid resource leaks.
- Added comprehensive unit tests in `GeneralUtilsAdditionalTest` to
verify blocking of sensitive ranges (e.g., `127.0.0.1`, `10.0.0.0/8`,
`172.16.0.0/12`, `192.168.0.0/16`, CGNAT `100.64.0.0/10`, link-local
`169.254.0.0/16`, TEST-NETs, multicast `224.0.0.0/4`, IPv6 ULA
`fc00::/7`, and IPv4-mapped `::ffff:127.0.0.1`).
- Renamed and refactored helper logic to
`isDisallowedNetworkLocation(...)` and split out
`isSensitiveAddress(...)`, `isPrivateOrReservedIPv4(...)`,
`isUniqueLocalIPv6(...)`, and `isIPv4MappedAddress(...)` for clarity and
testability.

- **Why the change was made**
- To prevent Server-Side Request Forgery (SSRF) and related abuses in
features that fetch external URLs (e.g., website-to-PDF and similar
utilities).
- Ensures the application cannot be coerced into contacting internal
infrastructure or special-purpose address spaces.
- Adds explicit resource cleanup and safer defaults (fail closed) to
improve reliability and security.


---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 22:40:08 +01:00
Ludy 4ef2e4ab79 ci: restrict workflow to main branch PRs (#4677)
This pull request updates GitHub Actions workflow configuration files to
ensure that automated checks and labeling only run for pull requests
targeting specific branches, primarily `main`. This helps prevent
workflows from running unnecessarily on other branches and tightens
control over automation.

Workflow branch targeting updates:

* Updated `.github/workflows/auto-labelerV2.yml` to trigger the Auto
Pull Request Labeler V2 workflow only when pull requests target the
`main` or `V2` branches.
* Updated `.github/workflows/check_properties.yml` to trigger the check
only for pull requests targeting the `main` branch.

Workflow execution condition:

* Added a condition to the `check-files` job in
`.github/workflows/check_properties.yml` so it only runs if the pull
request's base branch is `main`.
2025-10-16 22:39:07 +01:00
stirlingbot[bot] 347aaba8b4 🌐 Sync Translations + Update README Progress Table (#4692)
### Description of Changes

This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:

#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.

#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.

#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.

---

Auto-generated by [create-pull-request][1].

[1]: https://github.com/peter-evans/create-pull-request

---------

Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-10-16 22:37:00 +01:00
Ludy dd0e8543e1 fix(multitool): avoid duplicate resource embedding on export to prevent huge PDFs (#4684)
# Description of Changes

**What was changed**
- Reworked Multi-Tool export to **group page copies per source PDF** and
reuse them during assembly.
- Eliminates repeated embedding of identical resources (fonts, XObjects,
images) that previously occurred when copying pages one-by-one.
- Keeps original vector content whenever possible instead of rasterizing
unchanged pages.
- Minor internal refactor to reduce repeated `copyPages` calls and add
pages from a pre-copied cache.

**Why the change was made**
- Users reported that exporting a PDF via Multi-Tool—without making any
edits—could inflate file size by 5x+.
- Root cause: exporting pages individually caused duplicated resources
in the output document, dramatically increasing size.
- Grouping and reusing copied pages avoids redundant embeddings and
yields output sizes much closer to the original.

Closes #4681

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 22:36:33 +01:00
Ludy cc1caa993f feat(attachments): add “Extract Attachments” tool to export embedded files as ZIP (#4645)
This pull request introduces a new feature that allows users to extract
all embedded attachments from a PDF and download them as a ZIP archive.
The implementation includes backend support for extracting attachments,
a new API endpoint, updates to the service layer, internationalization
for UI strings, and a new web form for user interaction.

**New PDF Attachment Extraction Feature**

_Backend/API:_
* Added a new API endpoint `/api/v1/misc/extract-attachments` in
`AttachmentController` to extract all embedded attachments from a PDF
and return them as a ZIP archive. Returns an error if no attachments are
found.
* Implemented `extractAttachments` method in `AttachmentService` and its
interface to traverse embedded files in the PDF, collect them, and
package them into a ZIP. Handles unique filenames and file metadata.
[[1]](diffhunk://#diff-31bc10a74e0d6a01a558585a760f1861009719d76de323eedf7205f1cd6dd417R109-R266)
[[2]](diffhunk://#diff-67f2128bf0a88be44c20ca02d5b03be5496d70160377da4e66e72379e8f5ddc8R14-R15)
* Introduced `ExtractAttachmentsRequest` model to handle extraction
requests.

_User Interface:_
* Added a new web form (`misc/extract-attachments.html`) for users to
upload a PDF and download its attachments as a ZIP.
* Created a new web route and controller method to serve the extraction
form.
* Updated navigation menus to include the new "Extract Attachments"
tool.
[[1]](diffhunk://#diff-22a78471c93650a470526aa92780ba43739d475858fd528f180272039dfaa543R261-R263)
[[2]](diffhunk://#diff-0bdef49007d770c7afb60ea9c618869ad3a4e96366e82a00b9424b88cdaa3f76R296-R298)

_Internationalization & Messaging:_
* Added English and German translations for all new UI elements and
error messages related to attachment extraction.
[[1]](diffhunk://#diff-ee1c6999a33498cfa3abba4a384e73a8b8269856899438de80560c965079a9fdR236)
[[2]](diffhunk://#diff-482633b22866efc985222c4a14efc5b7d2487b59f39b953f038273a39d0362f7R236)
[[3]](diffhunk://#diff-ee1c6999a33498cfa3abba4a384e73a8b8269856899438de80560c965079a9fdR643-R646)
[[4]](diffhunk://#diff-482633b22866efc985222c4a14efc5b7d2487b59f39b953f038273a39d0362f7R643-R646)
[[5]](diffhunk://#diff-ee1c6999a33498cfa3abba4a384e73a8b8269856899438de80560c965079a9fdR1342-R1347)
[[6]](diffhunk://#diff-482633b22866efc985222c4a14efc5b7d2487b59f39b953f038273a39d0362f7R1342-R1347)

These changes together provide a seamless way for users to extract and
download all embedded files from a PDF document.

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
- [ ]
2025-10-16 22:23:24 +01:00
Balázs Szücs 614d410dce feat(conversion): add PDF to Vector Image conversions (#4651)
# Description of Changes


This pull request adds support for converting between PDF and vector
formats (EPS, PS, PCL, XPS) using Ghostscript, including both backend
API endpoints and frontend UI integration. It introduces new
controllers, request models, configuration, and user interface elements
for these conversion features.

### Backend
* Added `PdfVectorExportController` with endpoints for converting PDF to
vector formats and vector formats to PDF, using Ghostscript for
processing.
(`app/core/src/main/java/stirling/software/SPDF/controller/api/converters/PdfVectorExportController.java`)
* Introduced `PdfVectorExportRequest` model to support new conversion
options and parameters.
(`app/core/src/main/java/stirling/software/SPDF/model/api/converters/PdfVectorExportRequest.java`)
* Added a utility method for Ghostscript conversion exceptions.
(`app/common/src/main/java/stirling/software/common/util/ExceptionUtils.java`)

### Configuration
* Registered new endpoints and alternatives for PDF/vector conversion in
the `EndpointConfiguration`.
(`app/core/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java`)

### Frontend
* Added Thymeleaf templates for "PDF to Vector" and "Vector to PDF"
conversion forms.
(`app/core/src/main/resources/templates/convert/pdf-to-vector.html`,
`app/core/src/main/resources/templates/convert/vector-to-pdf.html`)
* Integrated new conversion tools into the navigation bar and feature
groups.
(`app/core/src/main/resources/templates/fragments/navElements.html`)
* Added controller routes for the new conversion forms.
(`app/core/src/main/java/stirling/software/SPDF/controller/web/ConverterWebController.java`)

### UI
<img width="629" height="551" alt="image"
src="https://github.com/user-attachments/assets/37491db7-1ae8-47d4-b69b-412bf7b02acf"
/>
<img width="629" height="551" alt="image"
src="https://github.com/user-attachments/assets/b33d3d40-5f26-415f-bd60-467f23701003"
/>




Closes: #4491

<!--
Please provide a summary of the changes, including:

- What was changed
- Why the change was made
- Any challenges encountered

Closes #(issue_number)
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [x] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
2025-10-16 22:22:36 +01:00
dependabot[bot] a259378451 build(deps): bump commonmarkVersion from 0.26.0 to 0.27.0 (#4670)
Bumps `commonmarkVersion` from 0.26.0 to 0.27.0.
Updates `org.commonmark:commonmark` from 0.26.0 to 0.27.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/commonmark/commonmark-java/releases">org.commonmark:commonmark's
releases</a>.</em></p>
<blockquote>
<h2>commonmark-java 0.27.0</h2>
<h3>Added</h3>
<ul>
<li>
<p>Autolink extension: Now supports configuration of different link
types that
should be recognized and converted to links. See
<code>AutolinkExtension#builder</code></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Default?</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>URL</code></td>
<td>Yes</td>
<td>URL with a protocol such as <code>https://example.com</code></td>
</tr>
<tr>
<td><code>EMAIL</code></td>
<td>Yes</td>
<td>Email address such as <code>foo@example.com</code></td>
</tr>
<tr>
<td><code>WWW</code></td>
<td>Yes</td>
<td>Address beginning with <code>www</code> such as
<code>www.example.com</code></td>
</tr>
</tbody>
</table>
<p>Note that this changes the behavior of
<code>AutolinkExtension.create()</code> to now also
include <code>WWW</code> links by default. To re-enable the previous
behavior, use:</p>
<pre
lang="java"><code>AutolinkExtension.builder().linkTypes(AutolinkType.URL,
AutolinkType.EMAIL).build();
</code></pre>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md">org.commonmark:commonmark's
changelog</a>.</em></p>
<blockquote>
<h2>[0.27.0] - 2025-10-12</h2>
<h3>Added</h3>
<ul>
<li>
<p>Autolink extension: Now supports configuration of different link
types that
should be recognized and converted to links. See
<code>AutolinkExtension#builder</code></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Default?</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>URL</code></td>
<td>Yes</td>
<td>URL with a protocol such as <code>https://example.com</code></td>
</tr>
<tr>
<td><code>EMAIL</code></td>
<td>Yes</td>
<td>Email address such as <code>foo@example.com</code></td>
</tr>
<tr>
<td><code>WWW</code></td>
<td>Yes</td>
<td>Address beginning with <code>www</code> such as
<code>www.example.com</code></td>
</tr>
</tbody>
</table>
<p>Note that this changes the behavior of
<code>AutolinkExtension.create()</code> to now also
include <code>WWW</code> links by default. To re-enable the previous
behavior, use:</p>
<pre
lang="java"><code>AutolinkExtension.builder().linkTypes(AutolinkType.URL,
AutolinkType.EMAIL).build();
</code></pre>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/70f6819d263a506ea20f4d0fb18631ca21bab2e6"><code>70f6819</code></a>
[maven-release-plugin] prepare release commonmark-parent-0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/d2138afa123efb85c4459867fad58e167f6d8a2d"><code>d2138af</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/407">#407</a>
from commonmark/release-0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/9fd4b9ae59f04084d81dacda9aaf3022c6f38ea1"><code>9fd4b9a</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/408">#408</a>
from commonmark/java-25</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/de91f05a96061f5afe5b2c107610e27c1e9c2703"><code>de91f05</code></a>
Test on Java 25</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/c55b0ecf5655d7265dfc60dbf454d1d78282b84a"><code>c55b0ec</code></a>
Prepare for version 0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/76b2168d9b8ad2b186cb05e1d985a37629b32318"><code>76b2168</code></a>
Prepare CHANGELOG for version 0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/2a4f4c4f811b0d8187e58fc81e43a8d703d14f9e"><code>2a4f4c4</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/406">#406</a>
from rdestefa/issue-298-www-links</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/889709c57578369685f4ece88917c1ffa8df44c2"><code>889709c</code></a>
Typo</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/53bf47d5cf6e7854dee03af658b1f7960c585dcf"><code>53bf47d</code></a>
Fix Test Failure</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/e49094cf8e0912b79737e6fed66a8e245b8285e0"><code>e49094c</code></a>
Address PR Comments 2</li>
<li>Additional commits viewable in <a
href="https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.26.0...commonmark-parent-0.27.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `org.commonmark:commonmark-ext-gfm-tables` from 0.26.0 to 0.27.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/commonmark/commonmark-java/releases">org.commonmark:commonmark-ext-gfm-tables's
releases</a>.</em></p>
<blockquote>
<h2>commonmark-java 0.27.0</h2>
<h3>Added</h3>
<ul>
<li>
<p>Autolink extension: Now supports configuration of different link
types that
should be recognized and converted to links. See
<code>AutolinkExtension#builder</code></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Default?</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>URL</code></td>
<td>Yes</td>
<td>URL with a protocol such as <code>https://example.com</code></td>
</tr>
<tr>
<td><code>EMAIL</code></td>
<td>Yes</td>
<td>Email address such as <code>foo@example.com</code></td>
</tr>
<tr>
<td><code>WWW</code></td>
<td>Yes</td>
<td>Address beginning with <code>www</code> such as
<code>www.example.com</code></td>
</tr>
</tbody>
</table>
<p>Note that this changes the behavior of
<code>AutolinkExtension.create()</code> to now also
include <code>WWW</code> links by default. To re-enable the previous
behavior, use:</p>
<pre
lang="java"><code>AutolinkExtension.builder().linkTypes(AutolinkType.URL,
AutolinkType.EMAIL).build();
</code></pre>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/commonmark/commonmark-java/blob/main/CHANGELOG.md">org.commonmark:commonmark-ext-gfm-tables's
changelog</a>.</em></p>
<blockquote>
<h2>[0.27.0] - 2025-10-12</h2>
<h3>Added</h3>
<ul>
<li>
<p>Autolink extension: Now supports configuration of different link
types that
should be recognized and converted to links. See
<code>AutolinkExtension#builder</code></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Default?</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>URL</code></td>
<td>Yes</td>
<td>URL with a protocol such as <code>https://example.com</code></td>
</tr>
<tr>
<td><code>EMAIL</code></td>
<td>Yes</td>
<td>Email address such as <code>foo@example.com</code></td>
</tr>
<tr>
<td><code>WWW</code></td>
<td>Yes</td>
<td>Address beginning with <code>www</code> such as
<code>www.example.com</code></td>
</tr>
</tbody>
</table>
<p>Note that this changes the behavior of
<code>AutolinkExtension.create()</code> to now also
include <code>WWW</code> links by default. To re-enable the previous
behavior, use:</p>
<pre
lang="java"><code>AutolinkExtension.builder().linkTypes(AutolinkType.URL,
AutolinkType.EMAIL).build();
</code></pre>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/70f6819d263a506ea20f4d0fb18631ca21bab2e6"><code>70f6819</code></a>
[maven-release-plugin] prepare release commonmark-parent-0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/d2138afa123efb85c4459867fad58e167f6d8a2d"><code>d2138af</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/407">#407</a>
from commonmark/release-0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/9fd4b9ae59f04084d81dacda9aaf3022c6f38ea1"><code>9fd4b9a</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/408">#408</a>
from commonmark/java-25</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/de91f05a96061f5afe5b2c107610e27c1e9c2703"><code>de91f05</code></a>
Test on Java 25</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/c55b0ecf5655d7265dfc60dbf454d1d78282b84a"><code>c55b0ec</code></a>
Prepare for version 0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/76b2168d9b8ad2b186cb05e1d985a37629b32318"><code>76b2168</code></a>
Prepare CHANGELOG for version 0.27.0</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/2a4f4c4f811b0d8187e58fc81e43a8d703d14f9e"><code>2a4f4c4</code></a>
Merge pull request <a
href="https://redirect.github.com/commonmark/commonmark-java/issues/406">#406</a>
from rdestefa/issue-298-www-links</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/889709c57578369685f4ece88917c1ffa8df44c2"><code>889709c</code></a>
Typo</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/53bf47d5cf6e7854dee03af658b1f7960c585dcf"><code>53bf47d</code></a>
Fix Test Failure</li>
<li><a
href="https://github.com/commonmark/commonmark-java/commit/e49094cf8e0912b79737e6fed66a8e245b8285e0"><code>e49094c</code></a>
Address PR Comments 2</li>
<li>Additional commits viewable in <a
href="https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.26.0...commonmark-parent-0.27.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 22:21:20 +01:00
stirlingbot[bot] 77fef2fce3 🌐 Sync Translations + Update README Progress Table (#4607)
### Description of Changes

This Pull Request was automatically generated to synchronize updates to
translation files and documentation. Below are the details of the
changes made:

#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes
in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language
files.
- Highlighted any missing or incomplete translations.

#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported
languages.
- Included up-to-date statistics on translation coverage.

#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.

---

Auto-generated by [create-pull-request][1].

[1]: https://github.com/peter-evans/create-pull-request

---------

Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-10-16 22:21:01 +01:00
dependabot[bot] e8207e99f2 build(deps): bump com.diffplug.spotless from 7.2.1 to 8.0.0 (#4546)
Bumps com.diffplug.spotless from 7.2.1 to 8.0.0.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.diffplug.spotless&package-manager=gradle&previous-version=7.2.1&new-version=8.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-16 22:19:15 +01:00
OUNZAR AymaneandYAOU Reda 9ea0edccde A fix for the bug : Extract Pages produce output pdf of same size (issue #1480) (#4636)
# Description of Changes

<!--
Please provide a summary of the changes, including:

Previously, the extraction logic reused the same PDF document instance.
It deleted all existing pages, then re-added only the pages that needed
to be extracted. However, some PDFs define a shared Resources dictionary
at the document level. In those cases, even after page deletion, the
shared resources remained, leading to incorrect or bloated output.

The updated implementation now creates a new PDF document based on the
old document. It copies only the selected pages from the original
document into this new file. This ensures no leftover shared resources
or unwanted metadata are carried over from the source PDF.

Closes #1480 
-->

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [x] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: YAOU Reda <yaoureda24@gmail.com>
2025-10-16 22:19:05 +01:00
Anthony Stirling 74c9176000 Version bump to 1.5.0 for new analytics flags (#4691)
# Description of Changes

https://docs.stirlingpdf.com/analytics-telemetry
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
2025-10-16 20:57:36 +01:00
ConnorYohandConnor Yoh 1a3552d1f7 Dynamic tracking services (#4690)
Added bean for both scarf and posthog
followed documentation at
https://docs.stirlingpdf.com/analytics-telemetry

Co-authored-by: Connor Yoh <connor@stirlingpdf.com>
2025-10-16 12:21:52 +01:00
100 changed files with 4356 additions and 1040 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
pip
pip @ git+https://github.com/pypa/pip.git@2e05cae3da2cfafa6dce58167a25b7dba4bc2a33 # CVE-2025-8869 mitigation - revert to released version once pip 25.3+ is available
setuptools
WeasyPrint
pdf2image
+241 -186
View File
@@ -131,74 +131,91 @@ brotli==1.1.0 \
--hash=sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2 \
--hash=sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064
# via fonttools
cffi==1.17.1 \
--hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
--hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
--hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
--hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
--hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
--hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
--hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
--hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
--hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
--hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
--hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
--hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
--hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
--hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
--hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
--hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
--hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
--hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
--hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
--hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
--hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
--hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
--hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
--hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
--hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
--hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
--hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
--hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
--hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
--hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
--hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
--hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
--hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
--hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
--hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
--hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
--hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
--hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
--hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
--hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
--hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \
--hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \
--hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \
--hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \
--hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \
--hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \
--hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \
--hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \
--hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \
--hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \
--hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \
--hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \
--hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \
--hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \
--hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \
--hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \
--hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \
--hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \
--hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \
--hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \
--hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \
--hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \
--hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \
--hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \
--hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \
--hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \
--hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b
cffi==2.0.0 \
--hash=sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb \
--hash=sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b \
--hash=sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f \
--hash=sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9 \
--hash=sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44 \
--hash=sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2 \
--hash=sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c \
--hash=sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75 \
--hash=sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65 \
--hash=sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e \
--hash=sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a \
--hash=sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e \
--hash=sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25 \
--hash=sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a \
--hash=sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe \
--hash=sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b \
--hash=sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91 \
--hash=sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592 \
--hash=sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187 \
--hash=sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c \
--hash=sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1 \
--hash=sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94 \
--hash=sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba \
--hash=sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb \
--hash=sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165 \
--hash=sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529 \
--hash=sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca \
--hash=sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c \
--hash=sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6 \
--hash=sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c \
--hash=sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0 \
--hash=sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743 \
--hash=sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63 \
--hash=sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5 \
--hash=sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5 \
--hash=sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4 \
--hash=sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d \
--hash=sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b \
--hash=sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93 \
--hash=sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205 \
--hash=sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27 \
--hash=sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512 \
--hash=sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d \
--hash=sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c \
--hash=sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037 \
--hash=sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26 \
--hash=sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322 \
--hash=sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb \
--hash=sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c \
--hash=sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8 \
--hash=sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4 \
--hash=sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414 \
--hash=sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9 \
--hash=sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664 \
--hash=sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9 \
--hash=sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775 \
--hash=sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739 \
--hash=sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc \
--hash=sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062 \
--hash=sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe \
--hash=sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9 \
--hash=sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92 \
--hash=sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5 \
--hash=sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13 \
--hash=sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d \
--hash=sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26 \
--hash=sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f \
--hash=sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495 \
--hash=sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b \
--hash=sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6 \
--hash=sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c \
--hash=sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef \
--hash=sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5 \
--hash=sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18 \
--hash=sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad \
--hash=sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3 \
--hash=sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7 \
--hash=sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5 \
--hash=sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534 \
--hash=sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49 \
--hash=sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2 \
--hash=sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5 \
--hash=sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453 \
--hash=sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf
# via weasyprint
cfgv==3.4.0 \
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
@@ -212,57 +229,73 @@ distlib==0.4.0 \
--hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \
--hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d
# via virtualenv
filelock==3.18.0 \
--hash=sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2 \
--hash=sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de
filelock==3.19.1 \
--hash=sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58 \
--hash=sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d
# via virtualenv
fonttools==4.59.0 \
--hash=sha256:052444a5d0151878e87e3e512a1aa1a0ab35ee4c28afde0a778e23b0ace4a7de \
--hash=sha256:169b99a2553a227f7b5fea8d9ecd673aa258617f466b2abc6091fe4512a0dcd0 \
--hash=sha256:209b75943d158f610b78320eacb5539aa9e920bee2c775445b2846c65d20e19d \
--hash=sha256:21e606b2d38fed938dde871c5736822dd6bda7a4631b92e509a1f5cd1b90c5df \
--hash=sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d \
--hash=sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe \
--hash=sha256:2e7cf8044ce2598bb87e44ba1d2c6e45d7a8decf56055b92906dc53f67c76d64 \
--hash=sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e \
--hash=sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01 \
--hash=sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705 \
--hash=sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c \
--hash=sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2 \
--hash=sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b \
--hash=sha256:4c908a7036f0f3677f8afa577bcd973e3e20ddd2f7c42a33208d18bee95cdb6f \
--hash=sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97 \
--hash=sha256:524133c1be38445c5c0575eacea42dbd44374b310b1ffc4b60ff01d881fabb96 \
--hash=sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2 \
--hash=sha256:60f6665579e909b618282f3c14fa0b80570fbf1ee0e67678b9a9d43aa5d67a37 \
--hash=sha256:62224a9bb85b4b66d1b46d45cbe43d71cbf8f527d332b177e3b96191ffbc1e64 \
--hash=sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757 \
--hash=sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e \
--hash=sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3 \
--hash=sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2 \
--hash=sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c \
--hash=sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0 \
--hash=sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1 \
--hash=sha256:8b4309a2775e4feee7356e63b163969a215d663399cce1b3d3b65e7ec2d9680e \
--hash=sha256:8d77f92438daeaddc05682f0f3dac90c5b9829bcac75b57e8ce09cb67786073c \
--hash=sha256:902425f5afe28572d65d2bf9c33edd5265c612ff82c69e6f83ea13eafc0dcbea \
--hash=sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5 \
--hash=sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6 \
--hash=sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c \
--hash=sha256:b818db35879d2edf7f46c7e729c700a0bce03b61b9412f5a7118406687cb151d \
--hash=sha256:b8974b2a266b54c96709bd5e239979cddfd2dbceed331aa567ea1d7c4a2202db \
--hash=sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14 \
--hash=sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38 \
--hash=sha256:d40dcf533ca481355aa7b682e9e079f766f35715defa4929aeb5597f9604272e \
--hash=sha256:e93df708c69a193fc7987192f94df250f83f3851fda49413f02ba5dded639482 \
--hash=sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4 \
--hash=sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b \
--hash=sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464 \
--hash=sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b
fonttools==4.60.1 \
--hash=sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c \
--hash=sha256:026290e4ec76583881763fac284aca67365e0be9f13a7fb137257096114cb3bc \
--hash=sha256:0b0835ed15dd5b40d726bb61c846a688f5b4ce2208ec68779bc81860adb5851a \
--hash=sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856 \
--hash=sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2 \
--hash=sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259 \
--hash=sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c \
--hash=sha256:1525796c3ffe27bb6268ed2a1bb0dcf214d561dfaf04728abf01489eb5339dce \
--hash=sha256:154cb6ee417e417bf5f7c42fe25858c9140c26f647c7347c06f0cc2d47eff003 \
--hash=sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272 \
--hash=sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77 \
--hash=sha256:268ecda8ca6cb5c4f044b1fb9b3b376e8cd1b361cef275082429dc4174907038 \
--hash=sha256:282dafa55f9659e8999110bd8ed422ebe1c8aecd0dc396550b038e6c9a08b8ea \
--hash=sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854 \
--hash=sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2 \
--hash=sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258 \
--hash=sha256:4ba4bd646e86de16160f0fb72e31c3b9b7d0721c3e5b26b9fa2fc931dfdb2652 \
--hash=sha256:5664fd1a9ea7f244487ac8f10340c4e37664675e8667d6fee420766e0fb3cf08 \
--hash=sha256:583b7f8e3c49486e4d489ad1deacfb8d5be54a8ef34d6df824f6a171f8511d99 \
--hash=sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7 \
--hash=sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914 \
--hash=sha256:66929e2ea2810c6533a5184f938502cfdaea4bc3efb7130d8cc02e1c1b4108d6 \
--hash=sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed \
--hash=sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb \
--hash=sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217 \
--hash=sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc \
--hash=sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f \
--hash=sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c \
--hash=sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877 \
--hash=sha256:875cb7764708b3132637f6c5fb385b16eeba0f7ac9fa45a69d35e09b47045801 \
--hash=sha256:8a44788d9d91df72d1a5eac49b31aeb887a5f4aab761b4cffc4196c74907ea85 \
--hash=sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a \
--hash=sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb \
--hash=sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383 \
--hash=sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401 \
--hash=sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28 \
--hash=sha256:9d0ced62b59e0430b3690dbc5373df1c2aa7585e9a8ce38eff87f0fd993c5b01 \
--hash=sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036 \
--hash=sha256:a184b2ea57b13680ab6d5fbde99ccef152c95c06746cb7718c583abd8f945ccc \
--hash=sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac \
--hash=sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903 \
--hash=sha256:a884aef09d45ba1206712c7dbda5829562d3fea7726935d3289d343232ecb0d3 \
--hash=sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6 \
--hash=sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c \
--hash=sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da \
--hash=sha256:b6379e7546ba4ae4b18f8ae2b9bc5960936007a1c0e30b342f662577e8bc3299 \
--hash=sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15 \
--hash=sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199 \
--hash=sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf \
--hash=sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1 \
--hash=sha256:e852d9dda9f93ad3651ae1e3bb770eac544ec93c3807888798eccddf84596537 \
--hash=sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d \
--hash=sha256:ee0c0b3b35b34f782afc673d503167157094a16f442ace7c6c5e0ca80b08f50c \
--hash=sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4 \
--hash=sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9 \
--hash=sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed \
--hash=sha256:f3d5be054c461d6a2268831f04091dc82753176f6ea06dc6047a5e168265a987 \
--hash=sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa
# via weasyprint
identify==2.6.13 \
--hash=sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b \
--hash=sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32
identify==2.6.15 \
--hash=sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757 \
--hash=sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf
# via pre-commit
nodeenv==1.9.1 \
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
@@ -449,17 +482,17 @@ pillow==11.3.0 \
# -r .github/scripts/requirements_dev.in
# pdf2image
# weasyprint
platformdirs==4.3.8 \
--hash=sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc \
--hash=sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4
platformdirs==4.4.0 \
--hash=sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85 \
--hash=sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf
# via virtualenv
pre-commit==4.3.0 \
--hash=sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8 \
--hash=sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16
# via -r .github/scripts/requirements_dev.in
pycparser==2.22 \
--hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \
--hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc
pycparser==2.23 \
--hash=sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2 \
--hash=sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934
# via cffi
pydyf==0.11.0 \
--hash=sha256:0aaf9e2ebbe786ec7a78ec3fbffa4cdcecde53fd6f563221d53c6bc1328848a3 \
@@ -469,60 +502,80 @@ pyphen==0.17.2 \
--hash=sha256:3a07fb017cb2341e1d9ff31b8634efb1ae4dc4b130468c7c39dd3d32e7c3affd \
--hash=sha256:f60647a9c9b30ec6c59910097af82bc5dd2d36576b918e44148d8b07ef3b4aa3
# via weasyprint
pyyaml==6.0.2 \
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
--hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
--hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
--hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
--hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
--hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
--hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
--hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
--hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
--hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
--hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
--hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
--hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
--hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
--hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
--hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
--hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
--hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
--hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
--hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
--hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
--hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
--hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
--hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
--hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
--hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
--hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
--hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
--hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
--hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
--hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
--hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
--hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
--hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
--hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
--hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
--hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
--hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
pyyaml==6.0.3 \
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
--hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \
--hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \
--hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \
--hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \
--hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \
--hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \
--hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \
--hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \
--hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \
--hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \
--hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \
--hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \
--hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \
--hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \
--hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \
--hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \
--hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \
--hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \
--hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \
--hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \
--hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \
--hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \
--hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \
--hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \
--hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \
--hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \
--hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \
--hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \
--hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \
--hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \
--hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \
--hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \
--hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \
--hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \
--hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \
--hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \
--hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \
--hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \
--hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \
--hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \
--hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \
--hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \
--hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \
--hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \
--hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \
--hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \
--hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \
--hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \
--hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \
--hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \
--hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \
--hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \
--hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \
--hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \
--hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \
--hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \
--hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \
--hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \
--hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \
--hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \
--hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \
--hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \
--hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \
--hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \
--hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \
--hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \
--hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \
--hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \
--hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \
--hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \
--hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \
--hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0
# via pre-commit
tinycss2==1.4.0 \
--hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \
@@ -534,13 +587,13 @@ tinyhtml5==2.0.0 \
--hash=sha256:086f998833da24c300c414d9fe81d9b368fd04cb9d2596a008421cbc705fcfcc \
--hash=sha256:13683277c5b176d070f82d099d977194b7a1e26815b016114f581a74bbfbf47e
# via weasyprint
unoserver==3.3.2 \
--hash=sha256:1eeb7467cf6b56b8eff3b576e2d1b2b2ff4e0eb2052e995ac80a1456de300639 \
--hash=sha256:87e144f903ee21951b2e06a97549450c13ed7eca5bcebad942d3352d4e882616
unoserver==3.4 \
--hash=sha256:3dcf2204013def1d1ddd3671f38b11346bdf349fef9728277462666a8a634419 \
--hash=sha256:64c24d33d4f65d680a2d9f676518cb28e7fd6c1f9d9a745c33e4a4cb59afdfcd
# via -r .github/scripts/requirements_dev.in
virtualenv==20.33.1 \
--hash=sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67 \
--hash=sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8
virtualenv==20.34.0 \
--hash=sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026 \
--hash=sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a
# via pre-commit
weasyprint==66.0 \
--hash=sha256:82b0783b726fcd318e2c977dcdddca76515b30044bc7a830cc4fbe717582a6d0 \
@@ -628,9 +681,11 @@ zopfli==0.2.3.post1 \
# via fonttools
# The following packages are considered to be unsafe in a requirements file:
pip==25.2 \
--hash=sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2 \
--hash=sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717
# VCS pin for pip to mitigate CVE-XXXX-YYYY (replace with actual CVE or issue reference).
# This pin ensures we use a commit with the required fix before it is released on PyPI.
# Maintainers: Once a fixed version of pip is released on PyPI, remove this VCS pin
# and restore a standard version specifier (e.g., pip==<new_version>).
pip @ git+https://github.com/pypa/pip.git@2e05cae3da2cfafa6dce58167a25b7dba4bc2a33
# via -r .github/scripts/requirements_dev.in
setuptools==80.9.0 \
--hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \
+3
View File
@@ -2,6 +2,9 @@ name: "Auto Pull Request Labeler V2"
on:
pull_request_target:
types: [opened, synchronize]
branches:
- main
- V2
permissions:
contents: read
+2
View File
@@ -5,6 +5,8 @@ on:
types: [opened, synchronize, reopened]
paths:
- "app/core/src/main/resources/messages_*.properties"
branches:
- main
# cancel in-progress jobs if a new job is triggered
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
+1 -1
View File
@@ -1,5 +1,5 @@
# Main stage
FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
# Copy necessary files
COPY scripts /scripts
+1 -1
View File
@@ -22,7 +22,7 @@ RUN DISABLE_ADDITIONAL_FEATURES=false \
./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube
# Main stage
FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
# Copy necessary files
COPY scripts /scripts
+1 -1
View File
@@ -1,5 +1,5 @@
# use alpine
FROM alpine:3.22.1@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1
FROM alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
ARG VERSION_TAG
+40 -38
View File
@@ -52,6 +52,7 @@ All documentation available at [https://docs.stirlingpdf.com/](https://docs.stir
- **CBZ to PDF**: Convert comic book archives
- **CBR to PDF**: Convert comic book rar archives
- **Email to PDF**: Convert email files to PDF
- **Vector Image to PDF**: Convert vector images (PS, EPS, EPSF) to PDF format
#### Convert from PDF
- **PDF to Word**: Convert to documet (docx, doc, odt) format
@@ -65,6 +66,7 @@ All documentation available at [https://docs.stirlingpdf.com/](https://docs.stir
- **PDF to Markdown**: Convert PDF to Markdown
- **PDF to CBZ**: Convert to comic book archive
- **PDF to CBR**: Convert to comic book rar archive
- **PDF to Vector Image**: Convert PDF to vector image (EPS, PS, PCL, XPS) format
#### Sign & Security
- **Sign**: Add digital signatures
@@ -131,47 +133,47 @@ Stirling-PDF currently supports 40 languages!
| Language | Progress |
|----------------------------------------------|----------------------------------------|
| Arabic (العربية) (ar_AR) | ![59%](https://geps.dev/progress/59) |
| Azerbaijani (Azərbaycan Dili) (az_AZ) | ![60%](https://geps.dev/progress/60) |
| Arabic (العربية) (ar_AR) | ![58%](https://geps.dev/progress/58) |
| Azerbaijani (Azərbaycan Dili) (az_AZ) | ![59%](https://geps.dev/progress/59) |
| Basque (Euskara) (eu_ES) | ![35%](https://geps.dev/progress/35) |
| Bulgarian (Български) (bg_BG) | ![66%](https://geps.dev/progress/66) |
| Catalan (Català) (ca_CA) | ![66%](https://geps.dev/progress/66) |
| Croatian (Hrvatski) (hr_HR) | ![96%](https://geps.dev/progress/96) |
| Czech (Česky) (cs_CZ) | ![68%](https://geps.dev/progress/68) |
| Danish (Dansk) (da_DK) | ![60%](https://geps.dev/progress/60) |
| Dutch (Nederlands) (nl_NL) | ![58%](https://geps.dev/progress/58) |
| Bulgarian (Български) (bg_BG) | ![65%](https://geps.dev/progress/65) |
| Catalan (Català) (ca_CA) | ![65%](https://geps.dev/progress/65) |
| Croatian (Hrvatski) (hr_HR) | ![94%](https://geps.dev/progress/94) |
| Czech (Česky) (cs_CZ) | ![67%](https://geps.dev/progress/67) |
| Danish (Dansk) (da_DK) | ![59%](https://geps.dev/progress/59) |
| Dutch (Nederlands) (nl_NL) | ![57%](https://geps.dev/progress/57) |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| French (Français) (fr_FR) | ![88%](https://geps.dev/progress/88) |
| German (Deutsch) (de_DE) | ![95%](https://geps.dev/progress/95) |
| Greek (Ελληνικά) (el_GR) | ![65%](https://geps.dev/progress/65) |
| Hindi (हिंदी) (hi_IN) | ![65%](https://geps.dev/progress/65) |
| Hungarian (Magyar) (hu_HU) | ![97%](https://geps.dev/progress/97) |
| Indonesian (Bahasa Indonesia) (id_ID) | ![60%](https://geps.dev/progress/60) |
| Irish (Gaeilge) (ga_IE) | ![66%](https://geps.dev/progress/66) |
| Italian (Italiano) (it_IT) | ![96%](https://geps.dev/progress/96) |
| Japanese (日本語) (ja_JP) | ![90%](https://geps.dev/progress/90) |
| Korean (한국어) (ko_KR) | ![66%](https://geps.dev/progress/66) |
| Norwegian (Norsk) (no_NB) | ![64%](https://geps.dev/progress/64) |
| Persian (فارسی) (fa_IR) | ![62%](https://geps.dev/progress/62) |
| Polish (Polski) (pl_PL) | ![70%](https://geps.dev/progress/70) |
| Portuguese (Português) (pt_PT) | ![67%](https://geps.dev/progress/67) |
| Portuguese Brazilian (Português) (pt_BR) | ![74%](https://geps.dev/progress/74) |
| Romanian (Română) (ro_RO) | ![56%](https://geps.dev/progress/56) |
| Russian (Русский) (ru_RU) | ![90%](https://geps.dev/progress/90) |
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![97%](https://geps.dev/progress/97) |
| Simplified Chinese (简体中文) (zh_CN) | ![91%](https://geps.dev/progress/91) |
| Slovakian (Slovensky) (sk_SK) | ![50%](https://geps.dev/progress/50) |
| Slovenian (Slovenščina) (sl_SI) | ![69%](https://geps.dev/progress/69) |
| Spanish (Español) (es_ES) | ![95%](https://geps.dev/progress/95) |
| Swedish (Svenska) (sv_SE) | ![63%](https://geps.dev/progress/63) |
| Thai (ไทย) (th_TH) | ![57%](https://geps.dev/progress/57) |
| Tibetan (བོད་ཡིག་) (bo_CN) | ![63%](https://geps.dev/progress/63) |
| Traditional Chinese (繁體中文) (zh_TW) | ![97%](https://geps.dev/progress/97) |
| Turkish (Türkçe) (tr_TR) | ![96%](https://geps.dev/progress/96) |
| Ukrainian (Українська) (uk_UA) | ![69%](https://geps.dev/progress/69) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![55%](https://geps.dev/progress/55) |
| Malayalam (മലയാളം) (ml_IN) | ![71%](https://geps.dev/progress/71) |
| French (Français) (fr_FR) | ![87%](https://geps.dev/progress/87) |
| German (Deutsch) (de_DE) | ![98%](https://geps.dev/progress/98) |
| Greek (Ελληνικά) (el_GR) | ![64%](https://geps.dev/progress/64) |
| Hindi (हिंदी) (hi_IN) | ![64%](https://geps.dev/progress/64) |
| Hungarian (Magyar) (hu_HU) | ![98%](https://geps.dev/progress/98) |
| Indonesian (Bahasa Indonesia) (id_ID) | ![59%](https://geps.dev/progress/59) |
| Irish (Gaeilge) (ga_IE) | ![65%](https://geps.dev/progress/65) |
| Italian (Italiano) (it_IT) | ![95%](https://geps.dev/progress/95) |
| Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) |
| Korean (한국어) (ko_KR) | ![64%](https://geps.dev/progress/64) |
| Norwegian (Norsk) (no_NB) | ![63%](https://geps.dev/progress/63) |
| Persian (فارسی) (fa_IR) | ![61%](https://geps.dev/progress/61) |
| Polish (Polski) (pl_PL) | ![69%](https://geps.dev/progress/69) |
| Portuguese (Português) (pt_PT) | ![66%](https://geps.dev/progress/66) |
| Portuguese Brazilian (Português) (pt_BR) | ![72%](https://geps.dev/progress/72) |
| Romanian (Română) (ro_RO) | ![55%](https://geps.dev/progress/55) |
| Russian (Русский) (ru_RU) | ![88%](https://geps.dev/progress/88) |
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![95%](https://geps.dev/progress/95) |
| Simplified Chinese (简体中文) (zh_CN) | ![89%](https://geps.dev/progress/89) |
| Slovakian (Slovensky) (sk_SK) | ![49%](https://geps.dev/progress/49) |
| Slovenian (Slovenščina) (sl_SI) | ![68%](https://geps.dev/progress/68) |
| Spanish (Español) (es_ES) | ![93%](https://geps.dev/progress/93) |
| Swedish (Svenska) (sv_SE) | ![62%](https://geps.dev/progress/62) |
| Thai (ไทย) (th_TH) | ![56%](https://geps.dev/progress/56) |
| Tibetan (བོད་ཡིག་) (bo_CN) | ![62%](https://geps.dev/progress/62) |
| Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) |
| Turkish (Türkçe) (tr_TR) | ![95%](https://geps.dev/progress/95) |
| Ukrainian (Українська) (uk_UA) | ![67%](https://geps.dev/progress/67) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![54%](https://geps.dev/progress/54) |
| Malayalam (മലയാളം) (ml_IN) | ![70%](https://geps.dev/progress/70) |
## Stirling PDF Enterprise
@@ -271,9 +271,14 @@ public class AppConfig {
return "NORMAL";
}
@Bean(name = "disablePixel")
public boolean disablePixel() {
return Boolean.parseBoolean(env.getProperty("DISABLE_PIXEL", "false"));
@Bean(name = "scarfEnabled")
public boolean scarfEnabled() {
return applicationProperties.getSystem().isScarfEnabled();
}
@Bean(name = "posthogEnabled")
public boolean posthogEnabled() {
return applicationProperties.getSystem().isPosthogEnabled();
}
@Bean(name = "machineType")
@@ -320,6 +320,8 @@ public class ApplicationProperties {
private String tessdataDir;
private Boolean enableAlphaFunctionality;
private Boolean enableAnalytics;
private Boolean enablePosthog;
private Boolean enableScarf;
private Datasource datasource;
private Boolean disableSanitize;
private int maxDPI;
@@ -333,6 +335,18 @@ public class ApplicationProperties {
public boolean isAnalyticsEnabled() {
return this.getEnableAnalytics() != null && this.getEnableAnalytics();
}
public boolean isPosthogEnabled() {
// Treat null as enabled when analytics is enabled
return this.isAnalyticsEnabled()
&& (this.getEnablePosthog() == null || this.getEnablePosthog());
}
public boolean isScarfEnabled() {
// Treat null as enabled when analytics is enabled
return this.isAnalyticsEnabled()
&& (this.getEnableScarf() == null || this.getEnableScarf());
}
}
@Data
@@ -56,7 +56,7 @@ public class PostHogService {
}
private void captureSystemInfo() {
if (!applicationProperties.getSystem().isAnalyticsEnabled()) {
if (!applicationProperties.getSystem().isPosthogEnabled()) {
return;
}
try {
@@ -67,7 +67,7 @@ public class PostHogService {
}
public void captureEvent(String eventName, Map<String, Object> properties) {
if (!applicationProperties.getSystem().isAnalyticsEnabled()) {
if (!applicationProperties.getSystem().isPosthogEnabled()) {
return;
}
@@ -225,6 +225,11 @@ public class ExceptionUtils {
return createIOException("error.commandFailed", "{0} command failed", cause, "QPDF");
}
public static IOException createGhostscriptConversionException(String outputType) {
return createIOException(
"error.commandFailed", "{0} command failed", null, "Ghostscript " + outputType);
}
/**
* Check if an exception indicates a corrupted PDF and wrap it with appropriate message.
*
@@ -33,6 +33,9 @@ import stirling.software.common.configuration.InstallationPathConfig;
@UtilityClass
public class GeneralUtils {
/** Maximum number of resolved DNS addresses allowed for a host before it is considered unsafe. */
private static final int MAX_DNS_ADDRESSES = 20;
private final Set<String> DEFAULT_VALID_SCRIPTS = Set.of("png_to_webp.py", "split_photos.py");
private final Set<String> DEFAULT_VALID_PIPELINE =
Set.of(
@@ -153,7 +156,7 @@ public class GeneralUtils {
return matcher.find() ? matcher.replaceFirst("") : filename;
}
/*
/**
* Append suffix to base name with null safety.
*
* @param baseName the base filename, null becomes "default"
@@ -164,7 +167,7 @@ public class GeneralUtils {
return (baseName == null ? "default" : baseName) + (suffix != null ? suffix : "");
}
/*
/**
* Generate a PDF filename by removing extension from first file and adding suffix.
*
* <p>High-level utility method for common PDF naming scenarios. Handles null safety and uses
@@ -179,7 +182,7 @@ public class GeneralUtils {
return appendSuffix(baseName, suffix);
}
/*
/**
* Process a list of filenames by removing extensions and adding suffix.
*
* <p>Efficiently processes multiple filenames using streaming operations and bulk operations
@@ -200,7 +203,7 @@ public class GeneralUtils {
.forEach(processor);
}
/*
/**
* Extract title from filename by removing extension, with fallback handling.
*
* <p>Returns "Untitled" for null or empty filenames, otherwise removes the extension using the
@@ -268,6 +271,12 @@ public class GeneralUtils {
.getResources(pattern);
}
/**
* Validates URL syntax and disallows common-infrastructure targets to reduce SSRF risk.
*
* @param urlStr a URL string to validate
* @return {@code true} if the URL is syntactically valid and allowed; {@code false} otherwise
*/
public boolean isValidURL(String urlStr) {
try {
Urls.create(
@@ -278,7 +287,7 @@ public class GeneralUtils {
}
}
/*
/**
* Checks if a URL is reachable with proper timeout configuration and error handling.
*
* @param urlStr the URL string to check
@@ -288,15 +297,17 @@ public class GeneralUtils {
return isURLReachable(urlStr, 5000, 5000);
}
/*
* Checks if a URL is reachable with configurable timeouts.
/**
* Checks whether a URL is reachable using configurable timeouts. Only {@code http} and
* {@code https} protocols are permitted, and local/private/multicast ranges are blocked.
*
* @param urlStr the URL string to check
* @param urlStr the URL to probe
* @param connectTimeout connection timeout in milliseconds
* @param readTimeout read timeout in milliseconds
* @return true if URL is reachable, false otherwise
* @return {@code true} if a HEAD request returns a 2xx or 3xx status; {@code false} otherwise
*/
public boolean isURLReachable(String urlStr, int connectTimeout, int readTimeout) {
HttpURLConnection connection = null;
try {
// Parse the URL
URL url = URI.create(urlStr).toURL();
@@ -307,14 +318,17 @@ public class GeneralUtils {
return false; // Disallow other protocols
}
// Check if the host is a local address
String host = url.getHost();
if (isLocalAddress(host)) {
return false; // Exclude local addresses
if (host == null || host.isBlank()) {
return false;
}
if (isDisallowedNetworkLocation(host)) {
return false; // Exclude local, private or otherwise sensitive addresses
}
// Check if the URL is reachable
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(readTimeout);
@@ -325,29 +339,173 @@ public class GeneralUtils {
} catch (Exception e) {
log.debug("URL {} is not reachable: {}", urlStr, e.getMessage());
return false; // Return false in case of any exception
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
private boolean isLocalAddress(String host) {
/**
* Determines whether the specified host resolves to a disallowed network location, such as
* local, private, multicast, or reserved ranges. Excessive DNS results are also blocked.
*
* @param host the hostname to resolve
* @return {@code true} if the host should be considered unsafe
*/
private boolean isDisallowedNetworkLocation(String host) {
// Resolution is delegated to the JVM/OS resolver which already applies system
// configured query limits and timeouts. We only need the resolved addresses here so
// that we can enforce the MAX_DNS_ADDRESSES limit and perform the sensitive range
// checks below.
try {
// Resolve DNS to IP address
InetAddress address = InetAddress.getByName(host);
// Check for local addresses
return address.isAnyLocalAddress()
|| // Matches 0.0.0.0 or similar
address.isLoopbackAddress()
|| // Matches 127.0.0.1 or ::1
address.isSiteLocalAddress()
|| // Matches private IPv4 ranges: 192.168.x.x, 10.x.x.x, 172.16.x.x to
// 172.31.x.x
address.getHostAddress()
.startsWith("fe80:"); // Matches link-local IPv6 addresses
InetAddress[] addresses = InetAddress.getAllByName(host);
if (addresses.length > MAX_DNS_ADDRESSES) {
log.debug(
"Blocking URL to host {} due to excessive DNS records (>{})",
host,
MAX_DNS_ADDRESSES);
return true;
}
for (InetAddress address : addresses) {
if (address == null || isSensitiveAddress(address)) {
log.debug("Blocking URL to host {} resolved to {}", host, address);
return true;
}
}
return false;
} catch (Exception e) {
return false; // Return false for invalid or unresolved addresses
log.debug("Unable to resolve host {}: {}", host, e.getMessage());
return true; // Treat resolution issues as unsafe to avoid SSRF
}
}
/**
* Returns whether the given IP address lies within ranges that should not be contacted by the
* server (loopback, link-local, private, multicast, etc.). IPv6 ULA and IPv4-mapped addresses
* are handled.
*
* @param address the resolved address
* @return {@code true} if the address is considered sensitive
*/
private boolean isSensitiveAddress(InetAddress address) {
if (address.isAnyLocalAddress()
|| address.isLoopbackAddress()
|| address.isLinkLocalAddress()
|| address.isSiteLocalAddress()
|| address.isMulticastAddress()) {
return true;
}
byte[] rawAddress = address.getAddress();
if (address instanceof Inet4Address) {
return isPrivateOrReservedIPv4(rawAddress);
}
if (address instanceof Inet6Address inet6Address) {
if (isUniqueLocalIPv6(rawAddress)) {
return true;
}
if (isIPv4MappedAddress(rawAddress) || inet6Address.isIPv4CompatibleAddress()) {
byte[] ipv4 =
Arrays.copyOfRange(rawAddress, rawAddress.length - 4, rawAddress.length);
return isPrivateOrReservedIPv4(ipv4);
}
}
return false;
}
/**
* Checks whether an IPv4 address is private or reserved. Any malformed input defaults to
* {@code true} (conservative) to avoid misuse.
*
* @param address 4-byte IPv4 address
* @return {@code true} if private/reserved
*/
private boolean isPrivateOrReservedIPv4(byte[] address) {
// IPv4 addresses must be exactly 4 bytes. Treat null or unexpected lengths as
// sensitive to avoid processing malformed input.
if (address == null || address.length != 4) {
return true;
}
int first = Byte.toUnsignedInt(address[0]);
int second = Byte.toUnsignedInt(address[1]);
if (first == 0 || first == 127) {
return true; // 0.0.0.0/8 and 127.0.0.0/8
}
if (first == 100 && second >= 64 && second <= 127) {
return true; // 100.64.0.0/10 Carrier-grade NAT
}
if (first == 169 && second == 254) {
return true; // 169.254.0.0/16 Link-local
}
if (first == 172 && second >= 16 && second <= 31) {
return true; // 172.16.0.0/12 Private
}
if (first == 192 && second == 0 && Byte.toUnsignedInt(address[2]) == 0) {
return true; // 192.0.0.0/24 IETF Protocol Assignments
}
if (first == 192 && second == 0 && Byte.toUnsignedInt(address[2]) == 2) {
return true; // 192.0.2.0/24 TEST-NET-1
}
if (first == 192 && second == 168) {
return true; // 192.168.0.0/16 Private
}
if (first == 198 && (second == 18 || second == 19)) {
return true; // 198.18.0.0/15 Benchmark tests
}
if (first == 198 && second == 51 && Byte.toUnsignedInt(address[2]) == 100) {
return true; // 198.51.100.0/24 TEST-NET-2
}
if (first == 203 && second == 0 && Byte.toUnsignedInt(address[2]) == 113) {
return true; // 203.0.113.0/24 TEST-NET-3
}
if (first == 10) {
return true; // 10.0.0.0/8 Private
}
if (first >= 224) {
return true; // 224.0.0.0/4 Multicast and 240.0.0.0/4 Reserved for future use
}
return false;
}
/**
* Checks whether an IPv6 address is a Unique Local Address (ULA, fc00::/7). Any malformed input
* defaults to {@code true} (conservative) to avoid misuse.
*
* @param address 16-byte IPv6 address
* @return {@code true} if ULA
*/
private boolean isUniqueLocalIPv6(byte[] address) {
if (address == null || address.length != 16) {
return true;
}
int first = Byte.toUnsignedInt(address[0]);
return (first & 0xFE) == 0xFC; // fc00::/7 Unique local addresses
}
/**
* Checks whether an IPv6 address is an IPv4-mapped address (::ffff:0:0/96). Any malformed
* input defaults to {@code false} (conservative) to avoid misuse.
*
* @param address 16-byte IPv6 address
* @return {@code true} if IPv4-mapped
*/
private boolean isIPv4MappedAddress(byte[] address) {
if (address == null || address.length != 16) {
return false;
}
for (int i = 0; i < 10; i++) {
if (address[i] != 0) {
return false;
}
}
return address[10] == (byte) 0xFF && address[11] == (byte) 0xFF;
}
/*
* Improved multipart file conversion using the shared helper method.
*
@@ -1,7 +1,6 @@
package stirling.software.common.service;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static stirling.software.common.service.SpyPDFDocumentFactory.*;
@@ -22,7 +21,6 @@ import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import stirling.software.common.model.api.PDFFile;
import stirling.software.common.service.SpyPDFDocumentFactory.StrategyType;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@@ -1,9 +1,6 @@
package stirling.software.common.service;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.AdditionalAnswers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import java.io.IOException;
@@ -1,8 +1,6 @@
package stirling.software.common.service;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.*;
import java.io.File;
@@ -29,6 +29,21 @@ class GeneralUtilsAdditionalTest {
assertTrue(GeneralUtils.isValidURL("https://example.com"));
assertFalse(GeneralUtils.isValidURL("htp:/bad"));
assertFalse(GeneralUtils.isURLReachable("http://localhost"));
assertFalse(GeneralUtils.isURLReachable("http://0.0.0.0"));
assertFalse(GeneralUtils.isURLReachable("http://192.168.1.1"));
assertFalse(GeneralUtils.isURLReachable("http://169.254.0.1"));
assertFalse(GeneralUtils.isURLReachable("http://172.16.0.1"));
assertFalse(GeneralUtils.isURLReachable("http://192.0.2.1"));
assertFalse(GeneralUtils.isURLReachable("http://192.0.0.0"));
assertFalse(GeneralUtils.isURLReachable("http://192.168.0.0"));
assertFalse(GeneralUtils.isURLReachable("http://198.18.0.1"));
assertFalse(GeneralUtils.isURLReachable("http://198.51.100.0"));
assertFalse(GeneralUtils.isURLReachable("http://203.0.113.0"));
assertFalse(GeneralUtils.isURLReachable("http://10.0.0.0"));
assertFalse(GeneralUtils.isURLReachable("http://100.64.0.1"));
assertFalse(GeneralUtils.isURLReachable("http://224.0.0.0"));
assertFalse(GeneralUtils.isURLReachable("http://[::ffff:127.0.0.1]/"));
assertFalse(GeneralUtils.isURLReachable("http://[fd12:3456:789a::1]/"));
assertFalse(GeneralUtils.isURLReachable("ftp://example.com"));
assertTrue(GeneralUtils.isValidUUID("123e4567-e89b-12d3-a456-426614174000"));
@@ -260,6 +260,8 @@ public class EndpointConfiguration {
addEndpointToGroup("Convert", "pdf-to-csv");
addEndpointToGroup("Convert", "pdf-to-markdown");
addEndpointToGroup("Convert", "eml-to-pdf");
addEndpointToGroup("Convert", "pdf-to-vector");
addEndpointToGroup("Convert", "vector-to-pdf");
// Adding endpoints to "Security" group
addEndpointToGroup("Security", "add-password");
@@ -373,6 +375,8 @@ public class EndpointConfiguration {
addEndpointToGroup("Java", "extract-page");
addEndpointToGroup("Java", "pdf-to-single-page");
addEndpointToGroup("Java", "markdown-to-pdf");
addEndpointToGroup("Java", "vector-to-pdf");
addEndpointToGroup("Java", "pdf-to-vector");
addEndpointToGroup("Java", "show-javascript");
addEndpointToGroup("Java", "auto-redact");
addEndpointToGroup("Java", "redact");
@@ -403,6 +407,8 @@ public class EndpointConfiguration {
addEndpointToGroup("Ghostscript", "compress-pdf");
addEndpointToGroup("Ghostscript", "crop");
addEndpointToGroup("Ghostscript", "replace-invert-pdf");
addEndpointToGroup("Ghostscript", "pdf-to-vector");
addEndpointToGroup("Ghostscript", "vector-to-pdf");
/* tesseract */
addEndpointToGroup("tesseract", "ocr-pdf");
@@ -260,18 +260,17 @@ public class RearrangePagesPDFController {
newPages.add(document.getPage(newPageOrder.get(i)));
}
// Remove all the pages from the original document
for (int i = document.getNumberOfPages() - 1; i >= 0; i--) {
document.removePage(i);
}
// Create a new document based on the original one
PDDocument rearrangedDocument =
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document);
// Add the pages in the new order
for (PDPage page : newPages) {
document.addPage(page);
rearrangedDocument.addPage(page);
}
return WebResponseUtils.pdfDocToWebResponse(
document,
rearrangedDocument,
GeneralUtils.generateFilename(
pdfFile.getOriginalFilename(), "_rearranged.pdf"));
} catch (IOException e) {
@@ -2,10 +2,18 @@ package stirling.software.SPDF.controller.api.converters;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.HttpStatus;
@@ -44,6 +52,11 @@ public class ConvertWebsiteToPDF {
private final RuntimePathConfig runtimePathConfig;
private final ApplicationProperties applicationProperties;
private static final Pattern FILE_SCHEME_PATTERN =
Pattern.compile("(?<![a-z0-9_])file\\s*:(?:/{1,3}|%2f|%5c|%3a|&#x2f;|&#47;)");
private static final Pattern NUMERIC_HTML_ENTITY_PATTERN = Pattern.compile("&#(x?[0-9a-f]+);");
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/url/pdf")
@Operation(
summary = "Convert a URL to a PDF",
@@ -91,14 +104,33 @@ public class ConvertWebsiteToPDF {
}
Path tempOutputFile = null;
Path tempHtmlInput = null;
PDDocument doc = null;
try {
// Download the remote content first to ensure we don't allow dangerous schemes
String htmlContent = fetchRemoteHtml(URL);
if (containsDisallowedUriScheme(htmlContent)) {
URI rejectionLocation =
uriComponentsBuilder
.queryParam("error", "error.disallowedUrlContent")
.build()
.toUri();
log.warn("Rejected URL to PDF conversion due to disallowed content references");
return ResponseEntity.status(status).location(rejectionLocation).build();
}
tempHtmlInput = Files.createTempFile("url_input_", ".html");
Files.writeString(tempHtmlInput, htmlContent, StandardCharsets.UTF_8);
// Prepare the output file path
tempOutputFile = Files.createTempFile("output_", ".pdf");
// Prepare the WeasyPrint command
List<String> command = new ArrayList<>();
command.add(runtimePathConfig.getWeasyPrintPath());
command.add(tempHtmlInput.toString());
command.add("--base-url");
command.add(URL);
command.add("--pdf-forms");
command.add(tempOutputFile.toString());
@@ -120,6 +152,13 @@ public class ConvertWebsiteToPDF {
}
return response;
} finally {
if (tempHtmlInput != null) {
try {
Files.deleteIfExists(tempHtmlInput);
} catch (IOException e) {
log.error("Error deleting temporary HTML input file", e);
}
}
if (tempOutputFile != null) {
try {
@@ -131,6 +170,90 @@ public class ConvertWebsiteToPDF {
}
}
private String fetchRemoteHtml(String url) throws IOException, InterruptedException {
HttpClient client =
HttpClient.newBuilder()
.followRedirects(HttpClient.Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(10))
.build();
HttpRequest request =
HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(20))
.GET()
.header("User-Agent", "Stirling-PDF/URL-to-PDF")
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
if (response.statusCode() >= 400 || response.body() == null) {
throw new IOException(
"Failed to retrieve remote HTML. Status: " + response.statusCode());
}
return response.body();
}
private boolean containsDisallowedUriScheme(String htmlContent) {
if (htmlContent == null || htmlContent.isEmpty()) {
return false;
}
String normalized = normalizeForSchemeDetection(htmlContent);
return FILE_SCHEME_PATTERN.matcher(normalized).find();
}
private String normalizeForSchemeDetection(String htmlContent) {
String lowerCaseContent = htmlContent.toLowerCase(Locale.ROOT);
String decodedHtmlEntities = decodeNumericHtmlEntities(lowerCaseContent);
decodedHtmlEntities =
decodedHtmlEntities
.replace("&colon;", ":")
.replace("&sol;", "/")
.replace("&frasl;", "/");
return percentDecode(decodedHtmlEntities);
}
private String percentDecode(String content) {
StringBuilder result = new StringBuilder(content.length());
for (int i = 0; i < content.length(); i++) {
char current = content.charAt(i);
if (current == '%' && i + 2 < content.length()) {
String hex = content.substring(i + 1, i + 3);
try {
int value = Integer.parseInt(hex, 16);
result.append((char) value);
i += 2;
continue;
} catch (NumberFormatException ignored) {
// Fall through to append the literal characters when parsing fails
}
}
result.append(current);
}
return result.toString();
}
private String decodeNumericHtmlEntities(String content) {
Matcher matcher = NUMERIC_HTML_ENTITY_PATTERN.matcher(content);
StringBuffer decoded = new StringBuffer();
while (matcher.find()) {
String entityBody = matcher.group(1);
try {
int radix = entityBody.startsWith("x") ? 16 : 10;
int codePoint =
Integer.parseInt(radix == 16 ? entityBody.substring(1) : entityBody, radix);
matcher.appendReplacement(
decoded, Matcher.quoteReplacement(Character.toString((char) codePoint)));
} catch (NumberFormatException ex) {
matcher.appendReplacement(decoded, matcher.group(0));
}
}
matcher.appendTail(decoded);
return decoded.toString();
}
private String convertURLToFileName(String url) {
String safeName = GeneralUtils.convertToFileName(url);
if (safeName == null || safeName.isBlank()) {
@@ -0,0 +1,237 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.commons.io.FilenameUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.EndpointConfiguration;
import stirling.software.SPDF.model.api.converters.PdfVectorExportRequest;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.TempFile;
import stirling.software.common.util.TempFileManager;
import stirling.software.common.util.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/convert")
@Slf4j
@Tag(name = "Convert", description = "Convert APIs")
@RequiredArgsConstructor
public class PdfVectorExportController {
private static final MediaType PDF_MEDIA_TYPE = MediaType.APPLICATION_PDF;
private static final Set<String> GHOSTSCRIPT_INPUTS =
Set.of("ps", "eps", "epsf"); // PCL/PXL/XPS require GhostPDL (gpcl6/gxps)
private final TempFileManager tempFileManager;
private final EndpointConfiguration endpointConfiguration;
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/vector/pdf")
@Operation(
summary = "Convert PostScript formats to PDF",
description =
"Converts PostScript vector inputs (PS, EPS, EPSF) to PDF using Ghostscript."
+ " Input:PS/EPS Output:PDF Type:SISO")
public ResponseEntity<byte[]> convertGhostscriptInputsToPdf(
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
String originalName =
request.getFileInput() != null
? request.getFileInput().getOriginalFilename()
: null;
String extension =
originalName != null
? FilenameUtils.getExtension(originalName).toLowerCase(Locale.ROOT)
: "";
try (TempFile inputTemp =
new TempFile(tempFileManager, extension.isEmpty() ? "" : "." + extension);
TempFile outputTemp = new TempFile(tempFileManager, ".pdf")) {
request.getFileInput().transferTo(inputTemp.getFile());
if (GHOSTSCRIPT_INPUTS.contains(extension)) {
boolean prepress = request.getPrepress() != null && request.getPrepress();
runGhostscriptToPdf(inputTemp.getPath(), outputTemp.getPath(), prepress);
} else if ("pdf".equals(extension)) {
Files.copy(
inputTemp.getPath(),
outputTemp.getPath(),
StandardCopyOption.REPLACE_EXISTING);
} else {
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat",
"Unsupported Ghostscript input format {0}",
extension);
}
byte[] pdfBytes = Files.readAllBytes(outputTemp.getPath());
String outputName = GeneralUtils.generateFilename(originalName, "_converted.pdf");
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputName, PDF_MEDIA_TYPE);
}
}
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/pdf/vector")
@Operation(
summary = "Convert PDF to vector format",
description =
"Converts PDF to Ghostscript vector formats (EPS, PS, PCL, or XPS)."
+ " Input:PDF Output:VECTOR Type:SISO")
public ResponseEntity<byte[]> convertPdfToVector(
@Valid @ModelAttribute PdfVectorExportRequest request) throws Exception {
String originalName =
request.getFileInput() != null
? request.getFileInput().getOriginalFilename()
: null;
String outputFormat = request.getOutputFormat();
if (outputFormat == null || outputFormat.isEmpty()) {
outputFormat = "eps";
}
outputFormat = outputFormat.toLowerCase(Locale.ROOT);
try (TempFile inputTemp = new TempFile(tempFileManager, ".pdf");
TempFile outputTemp = new TempFile(tempFileManager, "." + outputFormat)) {
request.getFileInput().transferTo(inputTemp.getFile());
runGhostscriptPdfToVector(inputTemp.getPath(), outputTemp.getPath(), outputFormat);
byte[] vectorBytes = Files.readAllBytes(outputTemp.getPath());
String outputName =
GeneralUtils.generateFilename(originalName, "_converted." + outputFormat);
MediaType mediaType;
switch (outputFormat.toLowerCase(Locale.ROOT)) {
case "eps":
case "ps":
mediaType = MediaType.parseMediaType("application/postscript");
break;
case "pcl":
mediaType = MediaType.parseMediaType("application/vnd.hp-PCL");
break;
case "xps":
mediaType = MediaType.parseMediaType("application/vnd.ms-xpsdocument");
break;
default:
mediaType = MediaType.APPLICATION_OCTET_STREAM;
}
return WebResponseUtils.bytesToWebResponse(vectorBytes, outputName, mediaType);
}
}
private void runGhostscriptPdfToVector(Path inputPath, Path outputPath, String outputFormat)
throws IOException, InterruptedException {
if (!endpointConfiguration.isGroupEnabled("Ghostscript")) {
throw ExceptionUtils.createGhostscriptConversionException(outputFormat);
}
List<String> command = new ArrayList<>();
command.add("gs");
// Set device based on output format
String device;
switch (outputFormat.toLowerCase(Locale.ROOT)) {
case "eps":
device = "eps2write";
break;
case "ps":
device = "ps2write";
break;
case "pcl":
device = "pxlcolor"; // PCL XL color
break;
case "xps":
device = "xpswrite";
break;
default:
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat", "Unsupported output format: {0}", outputFormat);
}
command.add("-sDEVICE=" + device);
command.add("-dNOPAUSE");
command.add("-dBATCH");
command.add("-dSAFER");
command.add("-sOutputFile=" + outputPath.toAbsolutePath());
command.add(inputPath.toAbsolutePath().toString());
log.debug("Executing Ghostscript command: {}", String.join(" ", command));
ProcessExecutorResult result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.GHOSTSCRIPT)
.runCommandWithOutputHandling(command);
if (result.getRc() != 0) {
log.error(
"Ghostscript PDF to {} conversion failed with rc={} and messages={}. Command: {}",
outputFormat.toUpperCase(),
result.getRc(),
result.getMessages(),
String.join(" ", command));
throw ExceptionUtils.createGhostscriptConversionException(outputFormat);
}
}
private void runGhostscriptToPdf(Path inputPath, Path outputPath, boolean prepress)
throws IOException, InterruptedException {
if (!endpointConfiguration.isGroupEnabled("Ghostscript")) {
throw ExceptionUtils.createGhostscriptConversionException("pdfwrite");
}
List<String> command = new ArrayList<>();
command.add("gs");
command.add("-sDEVICE=pdfwrite");
command.add("-dNOPAUSE");
command.add("-dBATCH");
command.add("-dSAFER");
command.add("-dCompatibilityLevel=1.4");
if (prepress) {
command.add("-dPDFSETTINGS=/prepress");
}
command.add("-sOutputFile=" + outputPath.toAbsolutePath());
command.add(inputPath.toAbsolutePath().toString());
log.debug("Executing Ghostscript PostScript-to-PDF command: {}", String.join(" ", command));
ProcessExecutorResult result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.GHOSTSCRIPT)
.runCommandWithOutputHandling(command);
if (result.getRc() != 0) {
log.error(
"Ghostscript PostScript-to-PDF conversion failed with rc={} and messages={}. Command: {}",
result.getRc(),
result.getMessages(),
String.join(" ", command));
throw ExceptionUtils.createGhostscriptConversionException("pdfwrite");
}
}
}
@@ -2,6 +2,7 @@ package stirling.software.SPDF.controller.api.misc;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.MediaType;
@@ -20,8 +21,10 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.api.misc.AddAttachmentRequest;
import stirling.software.SPDF.model.api.misc.ExtractAttachmentsRequest;
import stirling.software.SPDF.service.AttachmentServiceInterface;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.GeneralUtils;
import stirling.software.common.util.WebResponseUtils;
@@ -56,4 +59,33 @@ public class AttachmentController {
Filenames.toSimpleFileName(fileInput.getOriginalFilename()),
"_with_attachments.pdf"));
}
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/extract-attachments")
@Operation(
summary = "Extract attachments from PDF",
description =
"This endpoint extracts all embedded attachments from a PDF into a ZIP archive."
+ " Input:PDF Output:ZIP Type:SISO")
public ResponseEntity<byte[]> extractAttachments(
@ModelAttribute ExtractAttachmentsRequest request) throws IOException {
try (PDDocument document = pdfDocumentFactory.load(request, true)) {
Optional<byte[]> extracted = pdfAttachmentService.extractAttachments(document);
if (extracted.isEmpty()) {
throw ExceptionUtils.createIllegalArgumentException(
"error.noAttachmentsFound",
"No embedded attachments found in the provided PDF");
}
MultipartFile fileInput = request.getFileInput();
String sourceName =
fileInput != null ? fileInput.getOriginalFilename() : request.getFileId();
String outputName =
Filenames.toSimpleFileName(
GeneralUtils.generateFilename(sourceName, "_attachments.zip"));
return WebResponseUtils.bytesToWebResponse(
extracted.get(), outputName, MediaType.APPLICATION_OCTET_STREAM);
}
}
}
@@ -67,19 +67,32 @@ public class FlattenController {
PDFRenderer pdfRenderer = new PDFRenderer(document);
PDDocument newDocument =
pdfDocumentFactory.createNewDocumentBasedOnOldDocument(document);
int defaultRenderDpi = 100; // Default fallback
ApplicationProperties properties =
ApplicationContextProvider.getBean(ApplicationProperties.class);
Integer configuredMaxDpi = null;
if (properties != null && properties.getSystem() != null) {
configuredMaxDpi = properties.getSystem().getMaxDPI();
}
int maxDpi =
(configuredMaxDpi != null && configuredMaxDpi > 0)
? configuredMaxDpi
: defaultRenderDpi;
Integer requestedDpi = request.getRenderDpi();
int renderDpi = maxDpi;
if (requestedDpi != null) {
renderDpi = Math.min(requestedDpi, maxDpi);
renderDpi = Math.max(renderDpi, 72);
}
int numPages = document.getNumberOfPages();
for (int i = 0; i < numPages; i++) {
try {
BufferedImage image;
// Use global maximum DPI setting, fallback to 300 if not set
int renderDpi = 300; // Default fallback
ApplicationProperties properties =
ApplicationContextProvider.getBean(ApplicationProperties.class);
if (properties != null && properties.getSystem() != null) {
renderDpi = properties.getSystem().getMaxDPI();
}
try {
image = pdfRenderer.renderImageWithDPI(i, renderDpi, ImageType.RGB);
} catch (OutOfMemoryError e) {
@@ -166,6 +166,20 @@ public class ConverterWebController {
return "convert/pdf-to-pdfa";
}
@GetMapping("/pdf-to-vector")
@Hidden
public String pdfToVectorForm(Model model) {
model.addAttribute("currentPage", "pdf-to-vector");
return "convert/pdf-to-vector";
}
@GetMapping("/vector-to-pdf")
@Hidden
public String vectorToPdfForm(Model model) {
model.addAttribute("currentPage", "vector-to-pdf");
return "convert/vector-to-pdf";
}
@GetMapping("/eml-to-pdf")
@Hidden
public String convertEmlToPdfForm(Model model) {
@@ -198,4 +198,11 @@ public class OtherWebController {
model.addAttribute("currentPage", "add-attachments");
return "misc/add-attachments";
}
@GetMapping("/extract-attachments")
@Hidden
public String extractAttachmentsForm(Model model) {
model.addAttribute("currentPage", "extract-attachments");
return "misc/extract-attachments";
}
}
@@ -0,0 +1,29 @@
package stirling.software.SPDF.model.api.converters;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.common.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper = true)
public class PdfVectorExportRequest extends PDFFile {
@Schema(
description = "Target vector format extension",
allowableValues = {"eps", "ps", "pcl", "xps"},
defaultValue = "eps")
@Pattern(regexp = "(?i)(eps|ps|pcl|xps)")
private String outputFormat = "eps";
@Schema(
description = "Apply Ghostscript prepress settings",
requiredMode = Schema.RequiredMode.REQUIRED,
allowableValues = {"true", "false"},
defaultValue = "false")
private Boolean prepress;
}
@@ -0,0 +1,10 @@
package stirling.software.SPDF.model.api.misc;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.common.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper = true)
public class ExtractAttachmentsRequest extends PDFFile {}
@@ -18,4 +18,10 @@ public class FlattenRequest extends PDFFile {
requiredMode = Schema.RequiredMode.REQUIRED,
defaultValue = "false")
private Boolean flattenOnlyForms;
@Schema(
description = "Optional DPI for page rendering when flattening the full document.",
requiredMode = Schema.RequiredMode.NOT_REQUIRED,
minimum = "72")
private Integer renderDpi;
}
@@ -2,14 +2,22 @@ package stirling.software.SPDF.service;
import static stirling.software.common.util.AttachmentUtils.setCatalogViewerPreferences;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
@@ -17,17 +25,37 @@ import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
import org.apache.pdfbox.pdmodel.PDEmbeddedFilesNameTreeNode;
import org.apache.pdfbox.pdmodel.PageMode;
import org.apache.pdfbox.pdmodel.common.PDNameTreeNode;
import org.apache.pdfbox.pdmodel.common.filespecification.PDComplexFileSpecification;
import org.apache.pdfbox.pdmodel.common.filespecification.PDEmbeddedFile;
import org.apache.pdfbox.pdmodel.common.filespecification.PDFileSpecification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class AttachmentService implements AttachmentServiceInterface {
private static final long DEFAULT_MAX_ATTACHMENT_SIZE_BYTES = 50L * 1024 * 1024; // 50 MB
private static final long DEFAULT_MAX_TOTAL_ATTACHMENT_SIZE_BYTES =
200L * 1024 * 1024; // 200 MB
private final long maxAttachmentSizeBytes;
private final long maxTotalAttachmentSizeBytes;
public AttachmentService() {
this(DEFAULT_MAX_ATTACHMENT_SIZE_BYTES, DEFAULT_MAX_TOTAL_ATTACHMENT_SIZE_BYTES);
}
public AttachmentService(long maxAttachmentSizeBytes, long maxTotalAttachmentSizeBytes) {
this.maxAttachmentSizeBytes = maxAttachmentSizeBytes;
this.maxTotalAttachmentSizeBytes = maxTotalAttachmentSizeBytes;
}
@Override
public PDDocument addAttachment(PDDocument document, List<MultipartFile> attachments)
throws IOException {
@@ -93,6 +121,216 @@ public class AttachmentService implements AttachmentServiceInterface {
return document;
}
@Override
public Optional<byte[]> extractAttachments(PDDocument document) throws IOException {
PDDocumentCatalog catalog = document.getDocumentCatalog();
if (catalog == null) {
return Optional.empty();
}
PDDocumentNameDictionary documentNames = catalog.getNames();
if (documentNames == null) {
return Optional.empty();
}
PDEmbeddedFilesNameTreeNode embeddedFilesTree = documentNames.getEmbeddedFiles();
if (embeddedFilesTree == null) {
return Optional.empty();
}
Map<String, PDComplexFileSpecification> embeddedFiles = new LinkedHashMap<>();
collectEmbeddedFiles(embeddedFilesTree, embeddedFiles);
if (embeddedFiles.isEmpty()) {
return Optional.empty();
}
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(baos)) {
Set<String> usedNames = new HashSet<>();
boolean hasExtractedAttachments = false;
long totalBytesWritten = 0L;
for (Map.Entry<String, PDComplexFileSpecification> entry : embeddedFiles.entrySet()) {
PDComplexFileSpecification fileSpecification = entry.getValue();
PDEmbeddedFile embeddedFile = getEmbeddedFile(fileSpecification);
if (embeddedFile == null) {
log.debug(
"Skipping attachment {} because embedded file was null",
entry.getKey());
continue;
}
String filename = determineFilename(entry.getKey(), fileSpecification);
filename = Filenames.toSimpleFileName(filename);
String sanitizedFilename = sanitizeFilename(filename);
Optional<byte[]> attachmentData = readAttachmentData(embeddedFile);
if (attachmentData.isEmpty()) {
log.warn(
"Skipping attachment '{}' because it exceeds the size limit of {} bytes",
sanitizedFilename,
maxAttachmentSizeBytes);
continue;
}
byte[] data = attachmentData.get();
if (maxTotalAttachmentSizeBytes > 0
&& (data.length + totalBytesWritten) > maxTotalAttachmentSizeBytes) {
log.warn(
"Skipping attachment '{}' because the total size would exceed {} bytes",
sanitizedFilename,
maxTotalAttachmentSizeBytes);
continue;
}
String uniqueFilename = ensureUniqueFilename(sanitizedFilename, usedNames);
ZipEntry zipEntry = new ZipEntry(uniqueFilename);
if (embeddedFile.getModDate() != null) {
zipEntry.setLastModifiedTime(
FileTime.from(embeddedFile.getModDate().toInstant()));
}
if (embeddedFile.getCreationDate() != null) {
zipEntry.setCreationTime(
FileTime.from(embeddedFile.getCreationDate().toInstant()));
}
zipEntry.setSize(data.length);
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(data);
zipOutputStream.closeEntry();
hasExtractedAttachments = true;
totalBytesWritten += data.length;
log.info("Extracted attachment '{}' ({} bytes)", uniqueFilename, data.length);
}
zipOutputStream.finish();
if (!hasExtractedAttachments) {
return Optional.empty();
}
return Optional.of(baos.toByteArray());
}
}
private String sanitizeFilename(String candidate) {
String sanitized = Filenames.toSimpleFileName(candidate);
if (StringUtils.isBlank(sanitized)) {
sanitized = generateDefaultFilename();
}
return sanitized;
}
private String generateDefaultFilename() {
return "unknown_attachment_" + System.currentTimeMillis();
}
private Optional<byte[]> readAttachmentData(PDEmbeddedFile embeddedFile) throws IOException {
try (var inputStream = embeddedFile.createInputStream();
var buffer = new ByteArrayOutputStream()) {
byte[] chunk = new byte[8192];
long total = 0L;
int read;
while ((read = inputStream.read(chunk)) != -1) {
total += read;
if (maxAttachmentSizeBytes > 0 && total > maxAttachmentSizeBytes) {
return Optional.empty();
}
buffer.write(chunk, 0, read);
}
return Optional.of(buffer.toByteArray());
}
}
private void collectEmbeddedFiles(
PDNameTreeNode<PDComplexFileSpecification> node,
Map<String, PDComplexFileSpecification> collector)
throws IOException {
if (node == null) {
return;
}
Map<String, PDComplexFileSpecification> names = node.getNames();
if (names != null) {
collector.putAll(names);
}
List<PDNameTreeNode<PDComplexFileSpecification>> kids = node.getKids();
if (kids != null) {
for (PDNameTreeNode<PDComplexFileSpecification> kid : kids) {
collectEmbeddedFiles(kid, collector);
}
}
}
private PDEmbeddedFile getEmbeddedFile(PDFileSpecification fileSpecification) {
if (!(fileSpecification instanceof PDComplexFileSpecification complexSpecification)) {
return null;
}
if (complexSpecification.getEmbeddedFileUnicode() != null) {
return complexSpecification.getEmbeddedFileUnicode();
}
if (complexSpecification.getEmbeddedFile() != null) {
return complexSpecification.getEmbeddedFile();
}
if (complexSpecification.getEmbeddedFileDos() != null) {
return complexSpecification.getEmbeddedFileDos();
}
if (complexSpecification.getEmbeddedFileMac() != null) {
return complexSpecification.getEmbeddedFileMac();
}
return complexSpecification.getEmbeddedFileUnix();
}
private String determineFilename(String key, PDComplexFileSpecification specification) {
if (specification == null) {
return fallbackFilename(key);
}
String name = specification.getFileUnicode();
if (StringUtils.isBlank(name)) {
name = specification.getFilename();
}
if (StringUtils.isBlank(name)) {
name = specification.getFile();
}
if (StringUtils.isBlank(name)) {
name = key;
}
return fallbackFilename(name);
}
private String fallbackFilename(String candidate) {
if (StringUtils.isBlank(candidate)) {
return "unknown_attachment_" + System.currentTimeMillis();
}
return candidate;
}
private String ensureUniqueFilename(String filename, Set<String> usedNames) {
String baseName = filename;
String extension = "";
int lastDot = filename.lastIndexOf('.');
if (lastDot > 0 && lastDot < filename.length() - 1) {
baseName = filename.substring(0, lastDot);
extension = filename.substring(lastDot);
}
String uniqueName = filename;
int counter = 1;
while (usedNames.contains(uniqueName)) {
uniqueName = baseName + "_" + counter + extension;
counter++;
}
usedNames.add(uniqueName);
return uniqueName;
}
private PDEmbeddedFilesNameTreeNode getEmbeddedFilesTree(PDDocument document) {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDDocumentNameDictionary documentNames = catalog.getNames();
@@ -2,6 +2,7 @@ package stirling.software.SPDF.service;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.web.multipart.MultipartFile;
@@ -10,4 +11,6 @@ public interface AttachmentServiceInterface {
PDDocument addAttachment(PDDocument document, List<MultipartFile> attachments)
throws IOException;
Optional<byte[]> extractAttachments(PDDocument document) throws IOException;
}
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=حذف
username=اسم المستخدم
password=كلمة المرور
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=إضافة علامة مائية
home.watermark.desc=أضف علامة مائية مخصصة إلى مستند PDF الخاص بك.
watermark.tags=نص,تكرار,تسمية,خاص,حقوق النشر,علامة تجارية,صورة,jpg,صورة,صورة فوتوغرافية
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=دمج
merge.header=دمج ملفات PDF متعددة (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Sil
username=İstifadəçi Adı
password=Şifr
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Watermark əlavə et
home.watermark.desc=PDF sənədinə fərdi watermark əlavə et.
watermark.tags=Mətn,təkrarlanan,nişan,sahib olmaq,müəllif hüquqları,əmtəə nişanı,şəkil,jpg,fotoşəkil,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Birləşdirin
merge.header=Çoxsaylı PDF-ləri birləşdirin (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Изтрий
username=Потребителско име
password=Парола
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Добавяне на воден знак
home.watermark.desc=Добавете персонализиран воден знак към вашия PDF документ.
watermark.tags=Текст,повтарящ се,етикет,собствено,авторско право,търговска марка,img,jpg,изображение,снимка
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Обединяване
merge.header=Обединяване на множество PDF файлове (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=སུབ་པ།
username=སྤྱོད་མཁན་མིང་།
password=གསང་ཚིག།
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=ཆུ་རྟགས་སྣོན་པ།
home.watermark.desc=PDF ཡིག་ཆར་རང་སྒྲིག་གི་ཆུ་རྟགས་སྣོན་པ།
watermark.tags=ཡི་གེ,བསྐྱར་ཟློས།,ཁ་ཡིག,རང་དབང་།,པར་དབང་།,ཚོང་རྟགས།,པར་རིས།,jpg,པར།,འདྲ་པར།
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=སྡེབ་སྦྱོར།
merge.header=Merge multiple PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Esborra
username=Usuari
password=Contrasenya
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Afegir Marca d'aigua
home.watermark.desc=Afegir una marca d'aigua personalitzada en un PDF
watermark.tags=text,repetició,etiqueta,propia,copyright,marca registrada,img,jpg,imatge,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Fusiona
merge.header=Fusiona múltiples PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Smazat
username=Uživatelské jméno
password=Heslo
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Přidat vodoznak
home.watermark.desc=Přidat vlastní vodoznak do vašeho PDF dokumentu.
watermark.tags=Text,opakující se,popisek,vlastní,copyright,ochranná známka,img,jpg,obrázek,fotka
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Sloučit
merge.header=Sloučit více PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Slet
username=Brugernavn
password=Adgangskode
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Tilføj Vandmærke
home.watermark.desc=Tilføj et brugerdefineret vandmærke til dit PDF-dokument.
watermark.tags=Tekst,gentagne,etiket,egen,ophavsret,varemærke,img,jpg,billede,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Flet
merge.header=Flet flere PDF'er (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Der Winkel muss ein Vielfaches von 90 sein.
error.pdfBookmarksNotFound=Keine PDF-Lesezeichen/Gliederung im Dokument gefunden.
error.fontLoadingFailed=Fehler bei der Verarbeitung der Schriftdatei.
error.fontDirectoryReadFailed=Konnte das Schriftverzeichnis nicht lesen.
error.noAttachmentsFound=Keine eingebetteten Anhänge im bereitgestellten PDF gefunden.
delete=Löschen
username=Benutzername
password=Passwort
@@ -639,6 +640,10 @@ home.attachments.title=Anhänge hinzufügen
home.attachments.desc=Eingebettete Dateien (Anhänge) zu einem PDF hinzufügen oder daraus entfernen
attachments.tags=einbetten, anhängen, datei, anhang, anhänge
home.extractAttachments.title=Anhänge extrahieren
home.extractAttachments.desc=Eingebettete Dateien (Anhänge) aus einem PDF als ZIP herunterladen
extractAttachments.tags=anhänge,extrahieren,einbetten,dateien,zip
home.watermark.title=Wasserzeichen hinzufügen
home.watermark.desc=Fügen Sie ein eigenes Wasserzeichen zu Ihrem PDF hinzu
watermark.tags=text,wiederholend,beschriftung,besitzen,urheberrecht,marke,img,jpg,bild,foto
@@ -1334,6 +1339,12 @@ attachments.description=Ermöglicht das Hinzufügen von Anhängen zum PDF
attachments.descriptionPlaceholder=Beschreibung für die Anhänge eingeben...
attachments.addButton=Anhänge hinzufügen
#extractAttachments
extractAttachments.title=Anhänge extrahieren
extractAttachments.header=Anhänge extrahieren
extractAttachments.description=Exportiert alle eingebetteten Dateien aus dem PDF in ein ZIP-Archiv.
extractAttachments.downloadButton=Anhänge extrahieren
#merge
merge.title=Zusammenführen
merge.header=Mehrere PDFs zusammenführen (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Immer aktiviert
cookieBanner.preferencesModal.necessary.description=Diese Cookies sind für das ordnungsgemäße Funktionieren der Website unerlässlich. Sie ermöglichen grundlegende Funktionen wie das Festlegen Ihrer Datenschutzeinstellungen, das Anmelden und das Ausfüllen von Formularen. Daher können sie nicht deaktiviert werden.
cookieBanner.preferencesModal.analytics.title=Analyse
cookieBanner.preferencesModal.analytics.description=Diese Cookies helfen uns zu verstehen, wie unsere Tools genutzt werden, damit wir uns darauf konzentrieren können, die Funktionen zu entwickeln, die unserer Community am meisten am Herzen liegen. Seien Sie beruhigt Stirling PDF kann und wird niemals den Inhalt der Dokumente verfolgen, mit denen Sie arbeiten.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner-Effect-PDF
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Mit diesem Werkzeug können Sie das Inhaltsverzeichni
editTableOfContents.desc.2=Sie können eine hierarchische Struktur erstellen, indem Sie untergeordnete Lesezeichen zu übergeordneten hinzufügen.
editTableOfContents.desc.3=Jedes Lesezeichen benötigt einen Titel und eine Seitenzahl.
editTableOfContents.submit=Inhaltsverzeichnis anwenden
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Διαγραφή
username=Όνομα χρήστη
password=Κωδικός
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Προσθήκη υδατογραφήματος
home.watermark.desc=Προσθήκη προσαρμοσμένου υδατογραφήματος στο έγγραφο PDF.
watermark.tags=κείμενο,επαναλαμβανόμενο,ετικέτα,ιδιοκτησία,πνευματικά δικαιώματα,εμπορικό σήμα,εικόνα,jpg,φωτογραφία
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Συγχώνευση
merge.header=Συγχώνευση πολλαπλών PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -194,6 +194,7 @@ error.fileFormatRequired=File must be in {0} format
error.invalidFormat=Invalid {0} format: {1}
error.endpointDisabled=This endpoint has been disabled by the admin
error.urlNotReachable=URL is not reachable, please provide a valid URL
error.disallowedUrlContent=URL content references disallowed resources and cannot be converted
error.invalidUrlFormat=Invalid URL format provided. The provided format is invalid.
# DPI and image rendering messages - used by frontend for dynamic translation
@@ -233,6 +234,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Delete
username=Username
password=Password
@@ -639,6 +641,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Add Watermark
home.watermark.desc=Add a custom watermark to your PDF document.
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
@@ -1011,6 +1017,7 @@ getPdfInfo.summary.all.permissions.alert=All Permissions Allowed
getPdfInfo.summary.compliance.alert={0} Compliant
getPdfInfo.summary.no.compliance.alert=No Compliance Standards
getPdfInfo.summary.security.section=Security Status
getPdfInfo.summary.technical.section=Technical Details
getPdfInfo.section.BasicInfo=Basic Information about the PDF document including file size, page count, and language
getPdfInfo.section.Metadata=Document metadata including title, author, creation date and other document properties
getPdfInfo.section.DocumentInfo=Technical details about the PDF document structure and version
@@ -1253,6 +1260,8 @@ repair.submit=Repair
flatten.title=Flatten
flatten.header=Flatten PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.renderDpi=Rendering DPI (optional, recommended 150 DPI):
flatten.renderDpi.help=Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size.
flatten.submit=Flatten
@@ -1334,6 +1343,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Merge
merge.header=Merge multiple PDFs (2+)
@@ -1898,6 +1913,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1974,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Delete
username=Username
password=Password
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Add Watermark
home.watermark.desc=Add a custom watermark to your PDF document.
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Merge
merge.header=Merge multiple PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=El ángulo debe ser múltiplo de 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error al procesar el archivo de fuente
error.fontDirectoryReadFailed=Error al leer el directorio de fuentes
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Borrar
username=Nombre de usuario
password=Contraseña
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Añadir marca de agua
home.watermark.desc=Añadir una marca de agua predefinida al documento PDF
watermark.tags=Texto,repetir,etiquetar,propietario,copyright,marca comercial,img,jpg,imagen,fotografía
@@ -1334,6 +1339,12 @@ attachments.description=Le permite añadir adjuntos al PDF
attachments.descriptionPlaceholder=Introduzca una descripción para los adjuntos...
attachments.addButton=Añadir adjuntos
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Unir
merge.header=Unir múltiples PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Siempre activado
cookieBanner.preferencesModal.necessary.description=Estas cookies son esenciales para que el sitio web funcione correctamente. Permiten funciones básicas como configurar sus preferencias de privacidad, iniciar sesión y completar formularios, por lo que no se pueden desactivar.
cookieBanner.preferencesModal.analytics.title=Análisis
cookieBanner.preferencesModal.analytics.description=Estas cookies nos ayudan a entender cómo se están utilizando nuestras herramientas, para que podamos centrarnos en desarrollar las funciones que nuestra comunidad valora más. Tenga la seguridad de que Stirling PDF no puede y nunca podrá rastrear el contenido de los documentos con los que trabaja.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Efecto de escáner
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Esta herramienta le permite añadir o editar la tabla
editTableOfContents.desc.2=Puede crear una estructura jerárquica añadiendo marcadores hijo a los marcadores padre.
editTableOfContents.desc.3=Cada marcador necesita de un título y un número de pagina destino.
editTableOfContents.submit=Aplicar tabla de contenidos
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=ezabatu
username=Erabiltzaile izena
password=Pasahitza
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Gehitu ur-marka
home.watermark.desc=Gehitu aurrez zehaztutako ur-marka bat PFD dokumentuari
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Elkartu
merge.header=Elkartu zenbait PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=حذف
username=نام کاربری
password=رمز عبور
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=افزودن واترمارک
home.watermark.desc=افزودن یک واترمارک سفارشی به سند PDF.
watermark.tags=متن،تکراری،برچسب،خود،کپی‌رایت،علامت تجاری،تصویر،jpg،عکس
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=ادغام
merge.header=ادغام چندین PDF (۲+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=L'angle doit être un multiple de 90
error.pdfBookmarksNotFound=Aucun signet ou plan PDF trouvé dans le document
error.fontLoadingFailed=Erreur lors du traitement du fichier de police
error.fontDirectoryReadFailed=Échec de la lecture du répertoire de polices
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Supprimer
username=Nom d'utilisateur
password=Mot de passe
@@ -639,6 +640,10 @@ home.attachments.title=Ajouter des pièces jointes
home.attachments.desc=Ajouter ou supprimer des fichiers intégrés (pièces jointes) dans un PDF
attachments.tags=intégrer,joindre,fichier,pièce,jointe,embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Ajouter un filigrane
home.watermark.desc=Ajoutez un filigrane personnalisé à votre PDF.
watermark.tags=texte,filigrane,label,propriété,droit d'auteur,marque déposée,img,jpg,image,photo,copyright,trademark
@@ -1334,6 +1339,12 @@ attachments.description=Permet d'ajouter des pièces jointes au PDF
attachments.descriptionPlaceholder=Entrez une description pour les pièces jointes...
attachments.addButton=Ajouter des pièces jointes
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Fusionner
merge.header=Fusionner plusieurs PDF
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Toujours activés
cookieBanner.preferencesModal.necessary.description=Ces cookies sont essentiels au bon fonctionnement du site. Ils permettent des fonctionnalités de base comme la gestion de vos préférences de confidentialité, la connexion et le remplissage de formulaires — c'est pourquoi ils ne peuvent pas être désactivés.
cookieBanner.preferencesModal.analytics.title=Analyse
cookieBanner.preferencesModal.analytics.description=Ces cookies nous aident à comprendre comment nos outils sont utilisés, afin que nous puissions nous concentrer sur les fonctionnalités les plus appréciées par notre communauté. Soyez rassuré — Stirling PDF ne peut pas et ne suivra jamais le contenu des documents que vous utilisez.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Fausse numérisation
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Cet outil vous permet d'ajouter ou de modifier la tab
editTableOfContents.desc.2=Vous pouvez créer une structure hiérarchique en ajoutant des signets enfants à des signets parents.
editTableOfContents.desc.3=Chaque signet nécessite un titre et un numéro de page cible.
editTableOfContents.submit=Appliquer la table des matières
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Scrios
username=Ainm úsáideora
password=Pasfhocal
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Cuir Uisce leis
home.watermark.desc=Cuir comhartha uisce saincheaptha le do dhoiciméad PDF.
watermark.tags=Téacs, athrá, lipéad, úinéireacht, cóipcheart, trádmharc, img, jpg, pictiúr, grianghraf
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Cumaisc
merge.header=Cumaisc PDFanna iolracha (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=हटाएं
username=उपयोगकर्ता नाम
password=पासवर्ड
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=वॉटरमार्क जोड़ें
home.watermark.desc=अपने PDF दस्तावेज में कस्टम वॉटरमार्क जोड़ें।
watermark.tags=टेक्स्ट,दोहराव,लेबल,स्वयं,कॉपीराइट,ट्रेडमार्क,img,jpg,चित्र,फोटो
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=मर्ज करें
merge.header=कई PDF मर्ज करें (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Kut mora biti višekratnik od 90
error.pdfBookmarksNotFound=U dokumentu nisu pronađene PDF oznake/sadržaj
error.fontLoadingFailed=Pogreška pri obradi datoteke fonta
error.fontDirectoryReadFailed=Čitanje direktorija fontova nije uspjelo
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Izbriši
username=Korisničko ime
password=Lozinka
@@ -639,6 +640,10 @@ home.attachments.title=Dodaj privitke
home.attachments.desc=Dodajte ili uklonite ugrađene datoteke (privitke) u/iz PDF-a
attachments.tags=ugradi,privitak,datoteka,privitci
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Dodaj vodeni žig
home.watermark.desc=Dodajte prilagođeni vodeni žig u svoj PDF dokument.
watermark.tags=tekst,ponavljanje,oznaka,vlastiti,autorsko pravo,zaštitni znak,img,jpg,slika,fotografija
@@ -1334,6 +1339,12 @@ attachments.description=Omogućuje dodavanje privitaka u PDF
attachments.descriptionPlaceholder=Unesite opis za privitke...
attachments.addButton=Dodaj privitke
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Spajanje
merge.header=Spajanje više PDF-ova (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Uvijek omogućeno
cookieBanner.preferencesModal.necessary.description=Ovi kolačići su ključni za ispravno funkcioniranje web stranice. Omogućuju osnovne značajke poput postavljanja vaših postavki privatnosti, prijave i ispunjavanja obrazaca—zbog čega se ne mogu isključiti.
cookieBanner.preferencesModal.analytics.title=Analitika
cookieBanner.preferencesModal.analytics.description=Ovi kolačići nam pomažu razumjeti kako se koriste naši alati, tako da se možemo usredotočiti na izgradnju značajki koje naša zajednica najviše cijeni. Budite sigurni—Stirling PDF ne može i nikada neće pratiti sadržaj dokumenata s kojima radite.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Efekt skenera
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Ovaj alat omogućuje dodavanje ili uređivanje sadrž
editTableOfContents.desc.2=Možete stvoriti hijerarhijsku strukturu dodavanjem podređenih oznaka roditeljskim oznakama.
editTableOfContents.desc.3=Svaka oznaka zahtijeva naslov i ciljni broj stranice.
editTableOfContents.submit=Primijeni sadržaj
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=A szögnek 90-nel oszthatónak kell lennie
error.pdfBookmarksNotFound=Nem található PDF-könyvjelző/vázlat a dokumentumban
error.fontLoadingFailed=Hiba a betűtípusfájl feldolgozása közben
error.fontDirectoryReadFailed=Nem sikerült beolvasni a betűtípus-könyvtárat
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Törlés
username=Felhasználónév
password=Jelszó
@@ -639,6 +640,10 @@ home.attachments.title=Csatolmányok hozzáadása a PDF-hez
home.attachments.desc=Csatolmányok (beágyazott fájlok) hozzáadása vagy eltávolítása a PDF-ből
attachments.tags=beágyazás,csatolás,fájl,csatolmány,csatolmányok
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Vízjel hozzáadása
home.watermark.desc=Egyedi vízjel hozzáadása PDF dokumentumhoz
watermark.tags=Szöveg,ismétlődő,címke,egyedi,szerzői jog,védjegy,kép,jpg,fotó,fénykép
@@ -1334,6 +1339,12 @@ attachments.description=Lehetővé teszi mellékletek hozzáadását a PDF-hez
attachments.descriptionPlaceholder=Adjon meg egy leírást a mellékletekhez...
attachments.addButton=Mellékletek hozzáadása
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Egyesítés
merge.header=Több PDF egyesítése (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Mindig aktív
cookieBanner.preferencesModal.necessary.description=Ezek a sütik elengedhetetlenek a weboldal megfelelő működéséhez. Olyan alapvető funkciókat tesznek lehetővé, mint az adatvédelmi beállítások megadása, a bejelentkezés és az űrlapok kitöltése-ezért nem kapcsolhatók ki.
cookieBanner.preferencesModal.analytics.title=Adatelemzések
cookieBanner.preferencesModal.analytics.description=Ezek a sütik segítenek megérteni, hogyan használják eszközeinket, így a közösségünk által leginkább értékelt funkciókra összpontosíthatunk. Nyugodt lehet-a Stirling PDF nem képes és soha nem is fog nyomon követni az Ön által használt dokumentumok tartalmát.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Látszat szkennelés
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Ez az eszköz lehetővé teszi a tartalomjegyzék (k
editTableOfContents.desc.2=Hierarchikus struktúrákat hozhat létre, ha gyermek könyvjelzőket ad a szülő könyvjelzőkhöz.
editTableOfContents.desc.3=Minden könyvjelzőhöz szükséges egy cím és egy céloldalszám.
editTableOfContents.submit=Alkalmazza a tartalomjegyzéket
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Hapus
username=Nama pengguna
password=Kata sandi
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Tambahkan watermark
home.watermark.desc=Menambahkan watermark khusus ke dokumen PDF Anda.
watermark.tags=Teks,berulang,label,sendiri,hak cipta,watermark,img,jpg,picture,photo
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Gabungkan
merge.header=Gabungkan beberapa PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=L'angolo deve essere un multiplo di 90
error.pdfBookmarksNotFound=Nessun segnalibro/schema PDF trovato nel documento
error.fontLoadingFailed=Errore durante l'elaborazione del font file
error.fontDirectoryReadFailed=Impossibile leggere la directory dei font
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Elimina
username=Nome utente
password=Password
@@ -606,21 +607,21 @@ home.imageToPdf.title=Da immagine a PDF
home.imageToPdf.desc=Converti un'immagine (PNG, JPEG, GIF) in PDF.
imageToPdf.tags=conversione,img,jpg,immagine,foto
home.cbzToPdf.title=CBZ to PDF
home.cbzToPdf.desc=Convert CBZ comic book archives to PDF format.
cbzToPdf.tags=conversion,comic,book,archive,cbz,zip
home.cbzToPdf.title=CBZ in PDF
home.cbzToPdf.desc=Converti gli archivi dei fumetti CBZ in formato PDF.
cbzToPdf.tags=conversione,fumetto,libro,archivio,cbz,zip
home.cbrToPdf.title=CBR to PDF
home.cbrToPdf.desc=Convert CBR comic book archives to PDF format.
cbrToPdf.tags=conversion,comic,book,archive,cbr,rar
home.cbrToPdf.title=CBR in PDF
home.cbrToPdf.desc=Converti gli archivi dei fumetti CBR in formato PDF.
cbrToPdf.tags=conversione,fumetto,libro,archivio,cbr,rar
home.pdfToCbz.title=PDF to CBZ
home.pdfToCbz.desc=Convert PDF files to CBZ comic book archives.
pdfToCbz.tags=conversion,comic,book,archive,cbz,pdf
home.pdfToCbz.title=PDF in CBZ
home.pdfToCbz.desc=Converti i file PDF negli archivi di fumetti CBZ.
pdfToCbz.tags=conversione,fumetto,libro,archivio,cbz,pdf
home.pdfToCbr.title=PDF to CBR
home.pdfToCbr.desc=Convert PDF files to CBR comic book archives.
pdfToCbr.tags=conversion,comic,book,archive,cbr,rar
home.pdfToCbr.title=PDF in CBR
home.pdfToCbr.desc=Converti i file PDF in archivi di fumetti CBR.
pdfToCbr.tags=conversione,fumetto,libro,archivio,cbr,rar
home.pdfToImage.title=Da PDF a immagine
home.pdfToImage.desc=Converti un PDF in un'immagine. (PNG, JPEG, GIF)
@@ -639,6 +640,10 @@ home.attachments.title=Aggiungi allegati
home.attachments.desc=Aggiungere o rimuovere file incorporati (allegati) da/a un PDF
attachments.tags=incorporare,allegare,file,allegato,allegati
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Aggiungi Filigrana
home.watermark.desc=Aggiungi una filigrana al tuo PDF.
watermark.tags=Testo,ripetizione,etichetta,proprio,copyright,marchio,img,jpg,immagine,foto
@@ -1334,6 +1339,12 @@ attachments.description=Consente di aggiungere allegati al PDF
attachments.descriptionPlaceholder=Inserisci una descrizione per gli allegati...
attachments.addButton=Aggiungi allegati
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Unisci
merge.header=Unisci 2 o più PDF
@@ -1453,7 +1464,7 @@ cbzToPDF.title=CBZ in PDF
cbzToPDF.header=CBZ in PDF
cbzToPDF.submit=Converti in PDF
cbzToPDF.selectText=Seleziona il file CBZ
cbzToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbzToPDF.optimizeForEbook=Ottimizza PDF per lettori di ebook (utilizza Ghostscript)
#pdfToCBZ
pdfToCBZ.title=PDF in CBZ
@@ -1463,19 +1474,19 @@ pdfToCBZ.selectText=Seleziona file PDF
pdfToCBZ.dpi=DPI (Dots Per Inch)
#cbrToPDF
cbrToPDF.title=CBR to PDF
cbrToPDF.header=CBR to PDF
cbrToPDF.submit=Convert to PDF
cbrToPDF.selectText=Select CBR file
cbrToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbrToPDF.title=CBR in PDF
cbrToPDF.header=CBR in PDF
cbrToPDF.submit=Converti in PDF
cbrToPDF.selectText=Seleziona file CBR
cbrToPDF.optimizeForEbook=Ottimizza PDF per lettori di ebook (utilizza Ghostscript)
#pdfToCBR
pdfToCBR.title=PDF to CBR
pdfToCBR.header=PDF to CBR
pdfToCBR.submit=Convert to CBR
pdfToCBR.selectText=Select PDF file
pdfToCBR.title=PDF in CBR
pdfToCBR.header=PDF in CBR
pdfToCBR.submit=Converti in CBR
pdfToCBR.selectText=Seleziona file PDF
pdfToCBR.dpi=DPI (Dots Per Inch)
pdfToCBR.dpiHelp=Higher DPI results in better quality but larger file size.
pdfToCBR.dpiHelp=Un DPI più alto si traduce in una qualità migliore ma in dimensioni del file maggiori.
#pdfToImage
pdfToImage.title=PDF a immagine
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Sempre abilitati
cookieBanner.preferencesModal.necessary.description=Questi cookie sono essenziali per il corretto funzionamento del sito web. Abilitano funzionalità fondamentali come l'impostazione delle preferenze sulla privacy, l'accesso e la compilazione di moduli, motivo per cui non possono essere disattivati.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=Questi cookie ci aiutano a capire come vengono utilizzati i nostri strumenti, così possiamo concentrarci sullo sviluppo delle funzionalità che la nostra community apprezza di più. Non preoccuparti: Stirling PDF non può e non traccerà mai il contenuto dei documenti con cui lavori.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Falsa scansione
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Questo strumento consente di aggiungere o modificare
editTableOfContents.desc.2=È possibile creare una struttura gerarchica aggiungendo segnalibri secondari a quelli principali.
editTableOfContents.desc.3=Ogni segnalibro richiede un titolo e un numero di pagina di destinazione.
editTableOfContents.submit=Applica sommario
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -137,7 +137,7 @@ lang.yor=ヨルバ語
addPageNumbers.fontSize=フォントサイズ
addPageNumbers.fontName=フォント名
addPageNumbers.fontColor=Font Colour
addPageNumbers.fontColor=フォントの色
pdfPrompt=PDFを選択
multiPdfPrompt=PDFを選択(2つ以上)
multiPdfDropPrompt=PDFを選択(又はドラッグ&ドロップ)
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=角度は90の倍数にしてください
error.pdfBookmarksNotFound=ドキュメント内にしおり/アウトラインが見つかりません
error.fontLoadingFailed=フォントファイルの処理中にエラーが発生しました
error.fontDirectoryReadFailed=フォントディレクトリの読み取りに失敗しました
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=削除
username=ユーザー名
password=パスワード
@@ -370,36 +371,36 @@ settings.update=利用可能なアップデート
settings.updateAvailable=バージョン {0} がインストールされています。 新しいバージョン ({1}) が利用可能です。
# Update modal and notification strings
update.urgentUpdateAvailable=🚨 Update Available
update.updateAvailable=Update Available
update.modalTitle=Update Available
update.current=Current
update.latest=Latest
update.latestStable=Latest Stable
update.priority=Priority
update.recommendedAction=Recommended Action
update.breakingChangesDetected=⚠️ Breaking Changes Detected
update.breakingChangesMessage=This update contains breaking changes. Please review the migration guides below.
update.migrationGuides=Migration Guides:
update.viewGuide=View Guide
update.loadingDetailedInfo=Loading detailed version information...
update.close=Close
update.viewAllReleases=View All Releases
update.downloadLatest=Download Latest
update.availableUpdates=Available Updates:
update.unableToLoadDetails=Unable to load detailed version information.
update.version=Version
update.urgentUpdateAvailable=🚨 利用可能なアップデート
update.updateAvailable=利用可能なアップデート
update.modalTitle=利用可能なアップデート
update.current=現在
update.latest=最新
update.latestStable=最新の安定版
update.priority=優先度
update.recommendedAction=推奨されるアクション
update.breakingChangesDetected=⚠️ 重大な変更が検出されました
update.breakingChangesMessage=このアップデートには重大な変更が含まれています。以下の移行ガイドをご覧ください。
update.migrationGuides=移行ガイド:
update.viewGuide=ガイドを見る
update.loadingDetailedInfo=詳細なバージョン情報を読み込む...
update.close=閉じる
update.viewAllReleases=すべてのリリースを表示
update.downloadLatest=最新をダウンロード
update.availableUpdates=利用可能なアップデート:
update.unableToLoadDetails=詳細なバージョン情報を読み込めません。
update.version=バージョン
# Update priority levels
update.priority.urgent=URGENT
update.priority.normal=NORMAL
update.priority.minor=MINOR
update.priority.low=LOW
update.priority.urgent=緊急
update.priority.normal=普通
update.priority.minor=マイナー
update.priority.low=低い
# Breaking changes text
update.breakingChanges=Breaking Changes:
update.breakingChangesDefault=This version contains breaking changes
update.migrationGuide=Migration Guide
update.breakingChanges=重大な変更:
update.breakingChangesDefault=このバージョンには重大な変更が含まれています
update.migrationGuide=移行ガイド
settings.appVersion=Appバージョン:
settings.downloadOption.title=ダウンロードオプション(zip以外の単一ファイル):
settings.downloadOption.1=同じウィンドウで開く
@@ -606,20 +607,20 @@ home.imageToPdf.title=画像をPDFに変換
home.imageToPdf.desc=画像 (PNG, JPEG, GIF) をPDFに変換します。
imageToPdf.tags=conversion,img,jpg,picture,photo,psd,photoshop
home.cbzToPdf.title=CBZ to PDF
home.cbzToPdf.desc=Convert CBZ comic book archives to PDF format.
home.cbzToPdf.title=CBZをPDFに変換
home.cbzToPdf.desc=CBZコミックブックアーカイブをPDF形式に変換します。
cbzToPdf.tags=conversion,comic,book,archive,cbz,zip
home.cbrToPdf.title=CBR to PDF
home.cbrToPdf.desc=Convert CBR comic book archives to PDF format.
home.cbrToPdf.title=CBRをPDFに変換
home.cbrToPdf.desc=CBRコミックブックアーカイブをPDF形式に変換します。
cbrToPdf.tags=conversion,comic,book,archive,cbr,rar
home.pdfToCbz.title=PDF to CBZ
home.pdfToCbz.desc=Convert PDF files to CBZ comic book archives.
home.pdfToCbz.title=PDFをCBZに変換
home.pdfToCbz.desc=PDFファイルをCBZコミックブックアーカイブに変換します。
pdfToCbz.tags=conversion,comic,book,archive,cbz,pdf
home.pdfToCbr.title=PDF to CBR
home.pdfToCbr.desc=Convert PDF files to CBR comic book archives.
home.pdfToCbr.title=PDFをCBRに変換
home.pdfToCbr.desc=PDFファイルをCBRコミックブックアーカイブに変換します。
pdfToCbr.tags=conversion,comic,book,archive,cbr,rar
home.pdfToImage.title=PDFを画像に変換
@@ -639,6 +640,10 @@ home.attachments.title=添付ファイルの追加
home.attachments.desc=PDFに埋め込みファイル(添付ファイル)を追加または削除します
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=透かしの追加
home.watermark.desc=PDFに独自の透かしを追加します。
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
@@ -894,12 +899,12 @@ replace-color.selectText.8=黒背景に黄色文字
replace-color.selectText.9=黒背景に緑文字
replace-color.selectText.10=テキストの色を選択
replace-color.selectText.11=背景色を選択
replace-color.selectText.12=Colour Space Conversion (CMYK for Printing)
replace-color.selectText.13=CMYK Colour Space Conversion
replace-color.selectText.14=This option converts the PDF from RGB colour space to CMYK colour space, which is optimized for professional printing. This process:
replace-color.selectText.15=Converts colours to CMYK (Cyan, Magenta, Yellow, Black) colour model used by professional printers
replace-color.selectText.16=Optimizes the PDF for print production with prepress settings
replace-color.selectText.17=May result in slight colour changes as CMYK has a smaller colour gamut than RGB
replace-color.selectText.12=色空間の変換(印刷用CMYK
replace-color.selectText.13=CMYK色空間変換
replace-color.selectText.14=このオプションはPDFをRGB色空間から、プロフェッショナルな印刷用に最適化されたCMYK色空間に変換します。このプロセスは以下のとおりです:
replace-color.selectText.15=カラーをプロのプリンターで使用されるCMYK(シアン、マゼンタ、イエロー、ブラック)カラーモデルに変換します。
replace-color.selectText.16=プリプレス設定を使用して印刷物制作用にPDFを最適化します。
replace-color.selectText.17=CMYKはRGBよりも色域が狭いため、わずかに色が変化する場合があります。
replace-color.submit=置換
@@ -1334,6 +1339,12 @@ attachments.description=PDFに添付ファイルを追加します
attachments.descriptionPlaceholder=添付ファイルの説明を入力してください...
attachments.addButton=添付ファイルの追加
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=結合
merge.header=複数のPDFを結合(2ファイル以上)
@@ -1449,33 +1460,33 @@ imageToPDF.selectText.4=1つのPDFに結合
imageToPDF.selectText.5=個別のPDFに変換
#cbzToPDF
cbzToPDF.title=CBZ to PDF
cbzToPDF.header=CBZ to PDF
cbzToPDF.submit=Convert to PDF
cbzToPDF.selectText=Select CBZ file
cbzToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbzToPDF.title=CBZをPDFに変換
cbzToPDF.header=CBZをPDFに変換
cbzToPDF.submit=PDFに変換
cbzToPDF.selectText=CBZファイルを選択
cbzToPDF.optimizeForEbook=PDFを電子書籍リーダー用に最適化する(Ghostscriptを使用)
#pdfToCBZ
pdfToCBZ.title=PDF to CBZ
pdfToCBZ.header=PDF to CBZ
pdfToCBZ.submit=Convert to CBZ
pdfToCBZ.selectText=Select PDF file
pdfToCBZ.dpi=DPI (Dots Per Inch)
pdfToCBZ.title=PDFをCBZに変換
pdfToCBZ.header=PDFをCBZに変換
pdfToCBZ.submit=CBZに変換
pdfToCBZ.selectText=PDFファイルを選択
pdfToCBZ.dpi=DPI(ドット/インチ)
#cbrToPDF
cbrToPDF.title=CBR to PDF
cbrToPDF.header=CBR to PDF
cbrToPDF.submit=Convert to PDF
cbrToPDF.selectText=Select CBR file
cbrToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbrToPDF.title=CBRをPDFに変換
cbrToPDF.header=CBRをPDFに変換
cbrToPDF.submit=PDFに変換
cbrToPDF.selectText=CBRファイルを選択
cbrToPDF.optimizeForEbook=PDFを電子書籍リーダー用に最適化する(Ghostscriptを使用)
#pdfToCBR
pdfToCBR.title=PDF to CBR
pdfToCBR.header=PDF to CBR
pdfToCBR.submit=Convert to CBR
pdfToCBR.selectText=Select PDF file
pdfToCBR.dpi=DPI (Dots Per Inch)
pdfToCBR.dpiHelp=Higher DPI results in better quality but larger file size.
pdfToCBR.title=PDFをCBRに変換
pdfToCBR.header=PDFをCBRに変換
pdfToCBR.submit=CBRに変換
pdfToCBR.selectText=PDFファイルを選択
pdfToCBR.dpi=DPI(ドット/インチ)
pdfToCBR.dpiHelp=DPIが高いほど品質は向上しますがファイルサイズは大きくなります。
#pdfToImage
pdfToImage.title=PDFを画像に変換
@@ -1488,11 +1499,11 @@ pdfToImage.colorType=カラーモード
pdfToImage.color=カラー
pdfToImage.grey=グレースケール
pdfToImage.blackwhite=白黒(データが失われる可能性があります!)
pdfToImage.dpi=DPI (The server limit is {0} dpi)
pdfToImage.dpi=DPI(サーバーの制限は {0} dpi
pdfToImage.submit=変換
pdfToImage.info=Pythonがインストールされていません。WebPの変換に必要です。
pdfToImage.placeholder=(例:1,2,8、4,7,12-16、2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
pdfToImage.includeAnnotations=注釈(コメント、ハイライトなど)を含める
#addPassword
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=常に有効
cookieBanner.preferencesModal.necessary.description=これらのCookieはウェブサイトが正常に機能するために不可欠です。プライバシー設定、ログイン、フォームへの入力といったコア機能を有効にするため、無効にすることはできません。
cookieBanner.preferencesModal.analytics.title=分析
cookieBanner.preferencesModal.analytics.description=これらのCookieはツールがどのように使用されているかを把握するのに役立ちます。これによりコミュニティが最も重視する機能の開発に集中することができます。ご安心ください。Stirling PDFはお客様が操作するドキュメントの内容を追跡することは決してありません。
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=フェイクスキャン
@@ -1947,13 +1960,30 @@ editTableOfContents.replaceExisting=既存のしおりを置き換える(既
editTableOfContents.editorTitle=しおりエディター
editTableOfContents.editorDesc=以下にしおりを追加して配置します。+をクリックして、子のしおりを追加します。
editTableOfContents.addBookmark=新しいしおりを追加
editTableOfContents.importBookmarksDefault=Import
editTableOfContents.importBookmarksFromJsonFile=Upload JSON file
editTableOfContents.importBookmarksFromClipboard=Paste from clipboard
editTableOfContents.exportBookmarksDefault=Export
editTableOfContents.exportBookmarksAsJson=Download as JSON
editTableOfContents.exportBookmarksAsText=Copy as text
editTableOfContents.importBookmarksDefault=インポート
editTableOfContents.importBookmarksFromJsonFile=JSONファイルをアップロード
editTableOfContents.importBookmarksFromClipboard=クリップボードから貼り付け
editTableOfContents.exportBookmarksDefault=エクスポート
editTableOfContents.exportBookmarksAsJson=JSONとしてダウンロード
editTableOfContents.exportBookmarksAsText=テキストとしてコピー
editTableOfContents.desc.1=このツールを使用すると、PDFドキュメントに目次(しおり)を追加または編集できます。
editTableOfContents.desc.2=親しおりに子しおりを追加することで階層構造を作成できます。
editTableOfContents.desc.3=各しおりにはタイトルと対象のページ番号が必要です。
editTableOfContents.submit=目次を適用
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=삭제
username=사용자 이름
password=비밀번호
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=워터마크 추가
home.watermark.desc=PDF 문서에 사용자 지정 워터마크를 추가합니다.
watermark.tags=텍스트,반복,레이블,소유,저작권,상표,이미지,jpg,사진
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=병합
merge.header=여러 PDF 병합 (2개 이상)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=മായ്ക്കുക
username=ഉപയോക്തൃനാമം
password=പാസ്വേഡ്
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=വാട്ടർമാർക്ക് ചേർക്കുക
home.watermark.desc=നിങ്ങളുടെ PDF പ്രമാണത്തിലേക്ക് ഒരു ഇഷ്ടാനുസൃത വാട്ടർമാർക്ക് ചേർക്കുക.
watermark.tags=ടെക്സ്റ്റ്,ആവർത്തിക്കുന്ന,ലേബൽ,സ്വന്തം,പകർപ്പവകാശം,വ്യാപാരമുദ്ര,img,jpg,ചിത്രം,ഫോട്ടോ
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=ലയിപ്പിക്കുക
merge.header=ഒന്നിലധികം PDF-കൾ ലയിപ്പിക്കുക (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=എപ്പോഴും പ്
cookieBanner.preferencesModal.necessary.description=വെബ്സൈറ്റ് ശരിയായി പ്രവർത്തിക്കാൻ ഈ കുക്കികൾ അത്യാവശ്യമാണ്. നിങ്ങളുടെ സ്വകാര്യതാ മുൻഗണനകൾ സജ്ജമാക്കുക, ലോഗിൻ ചെയ്യുക, ഫോമുകൾ പൂരിപ്പിക്കുക തുടങ്ങിയ പ്രധാന സവിശേഷതകൾ അവ പ്രവർത്തനക്ഷമമാക്കുന്നു—അതുകൊണ്ടാണ് അവ ഓഫാക്കാൻ കഴിയാത്തത്.
cookieBanner.preferencesModal.analytics.title=അനലിറ്റിക്സ്
cookieBanner.preferencesModal.analytics.description=ഞങ്ങളുടെ ടൂളുകൾ എങ്ങനെ ഉപയോഗിക്കുന്നുവെന്ന് മനസ്സിലാക്കാൻ ഈ കുക്കികൾ ഞങ്ങളെ സഹായിക്കുന്നു, അതിനാൽ ഞങ്ങളുടെ കമ്മ്യൂണിറ്റി ഏറ്റവും കൂടുതൽ വിലമതിക്കുന്ന ഫീച്ചറുകൾ നിർമ്മിക്കുന്നതിൽ ഞങ്ങൾക്ക് ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ കഴിയും. ഉറപ്പാക്കുക—സ്റ്റെർലിംഗ് PDF-ന് നിങ്ങൾ പ്രവർത്തിക്കുന്ന പ്രമാണങ്ങളുടെ ഉള്ളടക്കം ട്രാക്ക് ചെയ്യാൻ കഴിയില്ല, ഒരിക്കലും കഴിയില്ല.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Verwijderen
username=Gebruikersnaam
password=Wachtwoord
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Watermerk toevoegen
home.watermark.desc=Voeg een aangepast watermerk toe aan je PDF-document.
watermark.tags=Tekst,herhalend,label,eigen,copyright,handelsmerk,img,jpg,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Samenvoegen
merge.header=Meerdere PDF's samenvoegen (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Slett
username=Brukernavn
password=Passord
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Legg til Vannmerke
home.watermark.desc=Legg til et tilpasset vannmerke i din PDF-dokument.
watermark.tags=tekst,gjentakende,etikett,egen,opphavsrett,varemerke,bilde,jpg,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Slå sammen
merge.header=Slå sammen flere PDF-er (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=usuń
username=nazwa użytkownika
password=hasło
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Dodaj znak wodny
home.watermark.desc=Dodaj niestandardowy znak wodny do dokumentu PDF.
watermark.tags=Tekst,powtarzanie,etykieta,własne,prawa autorskie,znak wodny,img,jpg,obraz,zdjęcie
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Połącz
merge.header=Połącz wiele dokumentów PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Apagar
username=Usuário
password=Senha
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Adicionar Marca d'água
home.watermark.desc=Adicionar uma marca d'água personalizada ao seu PDF.
watermark.tags=Texto,repetindo,rótulo,próprio,direitos autorais,marca registrada,img,jpg,imagem,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Mesclar
merge.header=Mesclar
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Sempre Ativado
cookieBanner.preferencesModal.necessary.description=Estes cookies são essenciais para o bom funcionamento do site. Eles habilitam recursos básicos como definir suas preferências de privacidade, realizar login e preencher formulários e é por isso que não podem ser desativados.
cookieBanner.preferencesModal.analytics.title=Cookies Analíticos
cookieBanner.preferencesModal.analytics.description=Estes cookies nos ajudam a entender como nossas ferramentas estão sendo utilizadas, para que possamos nos concentrar na construção dos recursos que nossa comunidade mais valoriza. Fique tranquilo: o Stirling PDF não pode e nunca rastreará o conteúdo dos documentos com os quais você manipula.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Eliminar
username=Nome de utilizador
password=Palavra-passe
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Adicionar Marca de Água
home.watermark.desc=Adicionar uma marca de água personalizada ao seu documento PDF.
watermark.tags=Texto,repetindo,etiqueta,próprio,copyright,marca registada,img,jpg,imagem,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Juntar
merge.header=Juntar múltiplos PDFs (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Șterge
username=Nume de utilizator
password=Parolă
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Adaugă Filigran
home.watermark.desc=Adaugă un filigran personalizat la documentul PDF.
watermark.tags=Text,repetitiv,etichetă,propriu,drepturi de autor,marcă comercială,img,jpg,poză,fotografie
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Unire
merge.header=Unirea mai multor PDF-uri (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Угол наклона должен быть кра
error.pdfBookmarksNotFound=В PDF-документе не найдены закладки/сноски
error.fontLoadingFailed=Ошибка при обработке файла шрифта
error.fontDirectoryReadFailed=Не удалось прочитать каталог шрифтов
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Удалить
username=Имя пользователя
password=Пароль
@@ -639,6 +640,10 @@ home.attachments.title=Добавлять вложения
home.attachments.desc=Добавление или удаление встроенных файлов (вложений) в PDF-файл или из него
attachments.tags=вставлять,прикреплять,файл,вложение,вложения
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Добавить водяной знак
home.watermark.desc=Добавьте собственный водяной знак в ваш PDF-документ.
watermark.tags=текст,повторяющийся,метка,собственный,авторское право,торговая марка,изображение,jpg,картинка,фото
@@ -1334,6 +1339,12 @@ attachments.description=Позволяет добавлять вложения
attachments.descriptionPlaceholder=Введите описание для вложений...
attachments.addButton=Добавлять вложения
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Объединить
merge.header=Объединение нескольких PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Всегда включены
cookieBanner.preferencesModal.necessary.description=Эти файлы cookie необходимы для корректной работы веб-сайта. Они позволяют выполнять основные функции, такие как настройка параметров конфиденциальности, вход в систему и заполнение форм — именно поэтому их нельзя отключить.
cookieBanner.preferencesModal.analytics.title=Аналитика
cookieBanner.preferencesModal.analytics.description=Эти файлы cookie помогают нам понять, как используются наши инструменты, чтобы мы могли сосредоточиться на создании функций, которые больше всего ценятся нашим сообществом. Будьте уверены — Stirling PDF не может и никогда не будет отслеживать содержание документов, с которыми вы работаете.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Эффект сканирования
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Этот инструмент позволяет ва
editTableOfContents.desc.2=Вы можете создать иерархическую структуру, добавив дочерние закладки к родительским.
editTableOfContents.desc.3=Для каждой закладки требуется название и номер целевой страницы.
editTableOfContents.submit=Применить оглавление
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Vymazať
username=Používateľské meno
password=Heslo
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Pridať vodotlač
home.watermark.desc=Pridať vlastnú vodotlač do vášho PDF dokumentu.
watermark.tags=Text,opakujúci sa,označenie,vlastné,autorské práva,ochranná známka,img,jpg,obrázok,fotografia
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Zlúčiť
merge.header=Zlúčiť viacero PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Izbriši
username=Uporabniško ime
password=Geslo
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Dodaj vodni žig
home.watermark.desc=V dokument PDF dodajte vodni žig po meri.
watermark.tags=Besedilo, ponavljajoče se, oznaka, lastno, avtorske pravice, blagovna znamka, img, jpg, slika, fotografija
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Združi
merge.header=Združi več PDF-jev (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Vrednost ugla mora biti deljiva sa 90
error.pdfBookmarksNotFound=PDF dokument ne sadrži obeleživače/navigacioni sadržaj
error.fontLoadingFailed=Greška prilikom obrade fonta
error.fontDirectoryReadFailed=Greška prilikom pristupa direktorijuma sa fontovima
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Obriši
username=Korisničko ime
password=Lozinka
@@ -639,6 +640,10 @@ home.attachments.title=Dodaj priloge
home.attachments.desc=Dodavanje ili uklanjanje uključenih datoteka (priloga) u/iz PDF-a
attachments.tags=uključi,dodaj,datoteka,prilog,prilozi
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Dodaj vodeni žig
home.watermark.desc=Dodavanje prilagođenog vodenog žiga u PDF dokument
watermark.tags=Tekst,ponavljanje,etiketa,vlastiti,autorsko pravo,kopirajt,logo,img,jpg,slika,foto
@@ -1334,6 +1339,12 @@ attachments.description=Omogućava dodavanje priloga u PDF
attachments.descriptionPlaceholder=Upiši opis za priloge...
attachments.addButton=Dodaj priloge
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Spajanje
merge.header=Spoji više PDF-ova (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Uvek omogućeno
cookieBanner.preferencesModal.necessary.description=Ovi kolačići su neophodni za pravilno funkcionisanje sajta. Omogućavaju osnovne funkcije kao što su podešavanje privatnosti, prijavljivanje i popunjavanje obrazaca — zato ih nije moguće isključiti.
cookieBanner.preferencesModal.analytics.title=Analitika
cookieBanner.preferencesModal.analytics.description=Ovi kolačići nam pomažu da razumemo kako se naši alati koriste, kako bismo mogli da se fokusiramo na razvoj funkcija koje naša zajednica najviše ceni. Budite sigurni — Stirling PDF ne može i nikada neće pratiti sadržaj dokumenata sa kojima radite.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Efekat skenera
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Ovaj alat omogućava dodavanje ili izmenu sadržaja (
editTableOfContents.desc.2=Moguće je kreirati hijerarhijsku strukturu dodavanjem podređenih obeleživača nadređenim obeleživačima.
editTableOfContents.desc.3=Svaki obeleživač zahteva naslov i broj ciljne strane.
editTableOfContents.submit=Potvrdi
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Radera
username=Användarnamn
password=Lösenord
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Lägg till vattenstämpel
home.watermark.desc=Lägg till en anpassad vattenstämpel till ditt PDF-dokument.
watermark.tags=Text,upprepande,etikett,egen,upphovsrätt,varumärke,img,jpg,bild,foto
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Sammanfoga
merge.header=Slå samman flera PDF-filer (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=ลบ
username=ชื่อผู้ใช้
password=รหัสผ่าน
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=เพิ่มลายน้ำ
home.watermark.desc=เพิ่มลายน้ำที่กำหนดเองลงในเอกสาร PDF ของคุณ
watermark.tags=ข้อความ, ซ้ำ, ป้าย, ของคุณเอง, ลิขสิทธิ์, เครื่องหมายการค้า, รูปภาพ, JPG, ภาพ, รูปถ่าย
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=รวม
merge.header=รวม PDF หลายไฟล์ (2 ขึ้นไป)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Açı 90'ın katı olmalıdır
error.pdfBookmarksNotFound=Belgede herhangi bir PDF yer imi / içindekiler bulunamadı
error.fontLoadingFailed=Yazı tipi dosyası işlenirken hata oluştu
error.fontDirectoryReadFailed=Yazı tipi dizini okunamadı
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Sil
username=Kullanıcı Adı
password=Parola
@@ -639,6 +640,10 @@ home.attachments.title=Ekleri Ekle
home.attachments.desc=PDF'ye gömülü dosyalar (ekler) ekle veya kaldır
attachments.tags=gömme,ekle,dosya,ek,ekler
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Filigran Ekle
home.watermark.desc=PDF belgenize özel bir filigran ekleyin.
watermark.tags=Metin,tekrarlayan,etiket,kendi,telif hakkı,marka,img,jpg,fotoğraf,resim
@@ -1334,6 +1339,12 @@ attachments.description=PDF'ye ekler eklemenizi sağlar
attachments.descriptionPlaceholder=Ekler için bir açıklama girin...
attachments.addButton=Ekleri Ekle
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Birleştir
merge.header=Çoklu PDF'leri Birleştir (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Her Zaman Etkin
cookieBanner.preferencesModal.necessary.description=Bu çerezler, web sitesinin düzgün çalışabilmesi için gereklidir. Gizlilik tercihlerinizi ayarlama, giriş yapma ve form doldurma gibi temel işlevleri mümkün kılarlar — bu nedenle devre dışı bırakılamazlar.
cookieBanner.preferencesModal.analytics.title=Analitik
cookieBanner.preferencesModal.analytics.description=Bu çerezler, araçlarımızın nasıl kullanıldığını anlamamıza yardımcı olur, böylece topluluğumuzun en çok değer verdiği özellikleri geliştirmeye odaklanabiliriz. İçiniz rahat olsun — Stirling PDF, belgelerinizin içeriğini asla takip etmez ve etmeyecektir.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Tarayıcı Efekti
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=Bu araç, bir PDF belgesine içindekiler tablosu (yer
editTableOfContents.desc.2=Alt yer işaretleri ekleyerek hiyerarşik bir yapı oluşturabilirsiniz.
editTableOfContents.desc.3=Her yer işareti bir başlık ve hedef sayfa numarası gerektirir.
editTableOfContents.submit=İçindekiler Tablosunu Uygula
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Видалити
username=Ім'я користувача
password=Пароль
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Додати водяний знак
home.watermark.desc=Додайте свій водяний знак до документа PDF.
watermark.tags=текст,повторний,мітка,власний,авторське право,торговельна марка,зображення,jpg,картинка,фото
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Об'єднати
merge.header=Об'єднання кількох PDF-файлів (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=Angle must be a multiple of 90
error.pdfBookmarksNotFound=No PDF bookmarks/outline found in document
error.fontLoadingFailed=Error processing font file
error.fontDirectoryReadFailed=Failed to read font directory
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=Xóa
username=Tên người dùng
password=Mật khẩu
@@ -639,6 +640,10 @@ home.attachments.title=Add Attachments
home.attachments.desc=Add or remove embedded files (attachments) to/from a PDF
attachments.tags=embed,attach,file,attachment,attachments
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=Thêm hình mờ
home.watermark.desc=Thêm hình mờ tùy chỉnh vào tài liệu PDF của bạn.
watermark.tags=Văn bản,lặp lại,nhãn,riêng,bản quyền,thương hiệu,img,jpg,hình ảnh,ảnh
@@ -1334,6 +1339,12 @@ attachments.description=Allows you to add attachments to the PDF
attachments.descriptionPlaceholder=Enter a description for the attachments...
attachments.addButton=Add Attachments
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=Trộn
merge.header=Trộn nhiều PDF (2+)
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=Always Enabled
cookieBanner.preferencesModal.necessary.description=These cookies are essential for the website to function properly. They enable core features like setting your privacy preferences, logging in, and filling out forms—which is why they cant be turned off.
cookieBanner.preferencesModal.analytics.title=Analytics
cookieBanner.preferencesModal.analytics.description=These cookies help us understand how our tools are being used, so we can focus on building the features our community values most. Rest assured—Stirling PDF cannot and will never track the content of the documents you work with.
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=Scanner Effect
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=This tool allows you to add or edit the table of cont
editTableOfContents.desc.2=You can create a hierarchical structure by adding child bookmarks to parent bookmarks.
editTableOfContents.desc.3=Each bookmark requires a title and target page number.
editTableOfContents.submit=Apply Table of Contents
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=角度应当为90°的倍数
error.pdfBookmarksNotFound=文档中没有找到PDF书签/大纲
error.fontLoadingFailed=处理字体文件出错
error.fontDirectoryReadFailed=无法读取字体目录
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=删除
username=用户名
password=密码
@@ -639,6 +640,10 @@ home.attachments.title=添加附件
home.attachments.desc=在 PDF 中添加或删除嵌入文件(附件)
attachments.tags=嵌入、附件、文件、附加
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=添加水印
home.watermark.desc=在 PDF 中添加自定义水印。
watermark.tags=文本、重复、标签、自定义、版权、商标、图像、JPG、图片、照片
@@ -1334,6 +1339,12 @@ attachments.description=允许您向PDF添加附件
attachments.descriptionPlaceholder=为附件输入描述…
attachments.addButton=添加附件
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=合并
merge.header=合并多个 PDF2个以上)。
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=始终启用
cookieBanner.preferencesModal.necessary.description=这些Cookie对网站基础功能至关重要,用于保存隐私偏好、登录状态及表单填写等核心功能,因此无法禁用。
cookieBanner.preferencesModal.analytics.title=分析统计
cookieBanner.preferencesModal.analytics.description=这些Cookie帮助我们分析工具使用情况,以便聚焦开发用户最需要的功能。再次强调:Stirling PDF绝不会追踪您处理的文档内容。
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=模拟扫描
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=此工具可用于在 PDF 文档中添加或编辑目
editTableOfContents.desc.2=您可以通过为父书签添加子书签来构建层级结构
editTableOfContents.desc.3=每个书签需填写标题和目标页码
editTableOfContents.submit=应用目录
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -146,7 +146,7 @@ genericSubmit=送出
uploadLimit=檔案大小上限:
uploadLimitExceededSingular=檔案太大。允許的最大檔案大小為
uploadLimitExceededPlural=檔案太大。允許的最大檔案大小為
processTimeWarning=警告:此過程可能長達一分鐘,具體取決於檔案大小
processTimeWarning=警告:處理時間可能長達一分鐘,檔案大小而定。
pageOrderPrompt=自訂頁面順序(輸入以逗號分隔的頁碼或函式,如 2n+1):
pageSelectionPrompt=自訂頁面選擇(輸入以逗號分隔的頁碼 1、5、6 或 2n+1 等函式的清單):
goToPage=前往
@@ -233,6 +233,7 @@ error.angleNotMultipleOf90=角度必須是 90 的倍數
error.pdfBookmarksNotFound=在文件中找不到 PDF 書籤/大綱
error.fontLoadingFailed=處理字型檔案時發生錯誤
error.fontDirectoryReadFailed=讀取字型目錄失敗
error.noAttachmentsFound=No embedded attachments were found in the provided PDF.
delete=刪除
username=使用者名稱
password=密碼
@@ -606,21 +607,21 @@ home.imageToPdf.title=圖片轉 PDF
home.imageToPdf.desc=將圖片(PNG、JPEG、GIF)轉換為 PDF。
imageToPdf.tags=轉換,img,jpg,圖片,照片
home.cbzToPdf.title=CBZ to PDF
home.cbzToPdf.desc=Convert CBZ comic book archives to PDF format.
cbzToPdf.tags=conversion,comic,book,archive,cbz,zip
home.cbzToPdf.title=CBZ PDF
home.cbzToPdf.desc=將 CBZ 漫畫封存檔轉換為 PDF 格式。
cbzToPdf.tags=轉換,漫畫,書,封存,cbz,zip
home.cbrToPdf.title=CBR to PDF
home.cbrToPdf.desc=Convert CBR comic book archives to PDF format.
cbrToPdf.tags=conversion,comic,book,archive,cbr,rar
home.cbrToPdf.title=CBR PDF
home.cbrToPdf.desc=將 CBR 漫畫封存檔轉換為 PDF 格式。
cbrToPdf.tags=轉換,漫畫,書,封存,cbr,rar
home.pdfToCbz.title=PDF to CBZ
home.pdfToCbz.desc=Convert PDF files to CBZ comic book archives.
pdfToCbz.tags=conversion,comic,book,archive,cbz,pdf
home.pdfToCbz.title=PDF CBZ
home.pdfToCbz.desc=將 PDF 檔案轉換為 CBZ 漫畫封存檔。
pdfToCbz.tags=轉換,漫畫,書,封存,cbz,pdf
home.pdfToCbr.title=PDF to CBR
home.pdfToCbr.desc=Convert PDF files to CBR comic book archives.
pdfToCbr.tags=conversion,comic,book,archive,cbr,rar
home.pdfToCbr.title=PDF CBR
home.pdfToCbr.desc=將 PDF 檔案轉換為 CBR 漫畫封存檔。
pdfToCbr.tags=轉換,漫畫,書,封存,cbr,rar
home.pdfToImage.title=PDF 轉圖片
home.pdfToImage.desc=將 PDF 轉換為圖片(PNG、JPEG、GIF)。
@@ -639,6 +640,10 @@ home.attachments.title=新增附件
home.attachments.desc=將檔案(附件)新增或移除至/從 PDF
attachments.tags=嵌入,附件,檔案,附加,附件管理
home.extractAttachments.title=Extract Attachments
home.extractAttachments.desc=Download embedded files (attachments) from a PDF as a ZIP archive
extractAttachments.tags=attachments,extract,embedded,files,zip
home.watermark.title=新增浮水印
home.watermark.desc=在您的 PDF 檔案中新增自訂浮水印。
watermark.tags=文字,重複,標籤,自有,版權,商標,img,jpg,圖片,照片
@@ -894,12 +899,12 @@ replace-color.selectText.8=黑底黃字
replace-color.selectText.9=黑底綠字
replace-color.selectText.10=選擇文字顏色
replace-color.selectText.11=選擇背景顏色
replace-color.selectText.12=Colour Space Conversion (CMYK for Printing)
replace-color.selectText.13=CMYK Colour Space Conversion
replace-color.selectText.14=This option converts the PDF from RGB colour space to CMYK colour space, which is optimized for professional printing. This process:
replace-color.selectText.15=Converts colours to CMYK (Cyan, Magenta, Yellow, Black) colour model used by professional printers
replace-color.selectText.16=Optimizes the PDF for print production with prepress settings
replace-color.selectText.17=May result in slight colour changes as CMYK has a smaller colour gamut than RGB
replace-color.selectText.12=色彩空間轉換(CMYK 用於印刷)
replace-color.selectText.13=CMYK 色彩空間轉換
replace-color.selectText.14=此選項會將 PDF RGB 色彩空間轉換為 CMYK 色彩空間,以針對專業印刷進行最佳化。此過程會:
replace-color.selectText.15=將顏色轉換為專業印表機使用的 CMYK(青色、洋紅色、黃色、黑色)色彩模型
replace-color.selectText.16=透過印前設定最佳化 PDF 以進行印刷生產
replace-color.selectText.17=可能導致輕微的顏色變化,因為 CMYK 的色域比 RGB
replace-color.submit=取代
@@ -1241,7 +1246,7 @@ sign.previous=上一頁
sign.maintainRatio=切換維持長寬比
sign.undo=復原
sign.redo=重做
sign.colour=Signature Colour
sign.colour=簽章顏色
#repair
repair.title=修復
@@ -1334,6 +1339,12 @@ attachments.description=可將附件新增至 PDF
attachments.descriptionPlaceholder=請輸入附件說明...
attachments.addButton=新增附件
#extractAttachments
extractAttachments.title=Extract Attachments
extractAttachments.header=Extract attachments
extractAttachments.description=Exports all embedded files from the PDF into a ZIP archive.
extractAttachments.downloadButton=Extract Attachments
#merge
merge.title=合併
merge.header=合併多個 PDF
@@ -1449,33 +1460,33 @@ imageToPDF.selectText.4=合併為單一 PDF
imageToPDF.selectText.5=轉換為單獨的 PDF
#cbzToPDF
cbzToPDF.title=CBZ to PDF
cbzToPDF.header=CBZ to PDF
cbzToPDF.submit=Convert to PDF
cbzToPDF.selectText=Select CBZ file
cbzToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbzToPDF.title=CBZ PDF
cbzToPDF.header=CBZ PDF
cbzToPDF.submit=轉換為 PDF
cbzToPDF.selectText=選擇 CBZ 檔案
cbzToPDF.optimizeForEbook=將 PDF 最佳化以適合電子書閱讀器(使用 Ghostscript
#pdfToCBZ
pdfToCBZ.title=PDF to CBZ
pdfToCBZ.header=PDF to CBZ
pdfToCBZ.submit=Convert to CBZ
pdfToCBZ.selectText=Select PDF file
pdfToCBZ.dpi=DPI (Dots Per Inch)
pdfToCBZ.title=PDF CBZ
pdfToCBZ.header=PDF CBZ
pdfToCBZ.submit=轉換為 CBZ
pdfToCBZ.selectText=選擇 PDF 檔案
pdfToCBZ.dpi=DPI
#cbrToPDF
cbrToPDF.title=CBR to PDF
cbrToPDF.header=CBR to PDF
cbrToPDF.submit=Convert to PDF
cbrToPDF.selectText=Select CBR file
cbrToPDF.optimizeForEbook=Optimize PDF for ebook readers (uses Ghostscript)
cbrToPDF.title=CBR PDF
cbrToPDF.header=CBR PDF
cbrToPDF.submit=轉換為 PDF
cbrToPDF.selectText=選擇 CBR 檔案
cbrToPDF.optimizeForEbook=將 PDF 最佳化以適合電子書閱讀器(使用 Ghostscript
#pdfToCBR
pdfToCBR.title=PDF to CBR
pdfToCBR.header=PDF to CBR
pdfToCBR.submit=Convert to CBR
pdfToCBR.selectText=Select PDF file
pdfToCBR.dpi=DPI (Dots Per Inch)
pdfToCBR.dpiHelp=Higher DPI results in better quality but larger file size.
pdfToCBR.title=PDF CBR
pdfToCBR.header=PDF CBR
pdfToCBR.submit=轉換為 CBR
pdfToCBR.selectText=選擇 PDF 檔案
pdfToCBR.dpi=DPI
pdfToCBR.dpiHelp=DPI 越高,品質越好,但檔案大小也越大。
#pdfToImage
pdfToImage.title=PDF 轉圖片
@@ -1898,6 +1909,8 @@ cookieBanner.preferencesModal.necessary.title.2=永遠開啟
cookieBanner.preferencesModal.necessary.description=這些 Cookie 對網站正常運作至關重要。它們讓核心功能,像是隱私設定、登入、填入表格能夠運作——這也是為什麼它們不能被關掉。
cookieBanner.preferencesModal.analytics.title=分析 Cookie
cookieBanner.preferencesModal.analytics.description=這些 Cookie 協助我們分析您如何使用我們的工具,好讓我們能專注在建構社群最重視的功能。儘管放心—— Stirling PDF 不會且永不追蹤您的文件
cookieBanner.preferencesModal.analytics.posthog.label=PostHog Analytics
cookieBanner.preferencesModal.analytics.scarf.label=Scarf Pixel
#scannerEffect
scannerEffect.title=掃描器效果
@@ -1957,3 +1970,20 @@ editTableOfContents.desc.1=此工具可讓您在 PDF 文件中新增或編輯目
editTableOfContents.desc.2=您可以透過將子書籤新增至父書籤來建立階層式結構。
editTableOfContents.desc.3=每個書籤都需要標題和目標頁碼。
editTableOfContents.submit=套用目錄
home.pdfToVector.title=PDF to Vector Image
home.pdfToVector.desc=Convert PDF to vector formats (EPS, PS, PCL, XPS) using Ghostscript
pdfToVector.tags=conversion,vector,eps,ps,postscript,ghostscript,pcl,xps
home.vectorToPdf.title=Vector Image to PDF
home.vectorToPdf.desc=Convert PostScript (PS, EPS, EPSF) files to PDF using Ghostscript
vectorToPdf.tags=conversion,ghostscript,ps,eps,postscript
vectorToPdf.title=Vector Image to PDF
vectorToPdf.header=Vector Image to PDF
vectorToPdf.description=Convert PostScript vector formats (PS, EPS, EPSF) or PDF files to PDF using Ghostscript.
vectorToPdf.prepress=Apply prepress optimizations (/prepress)
vectorToPdf.submit=Convert
pdfToVector.title=PDF to Vector Image
pdfToVector.header=PDF to Vector Image
pdfToVector.description=Convert a PDF into Ghostscript-generated vector formats (EPS, PS, PCL, or XPS).
pdfToVector.outputFormat=Output format
pdfToVector.submit=Convert
@@ -109,7 +109,9 @@ system:
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
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: null # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
enableAnalytics: null # Master toggle for analytics: set to 'true' to enable all analytics, 'false' to disable all analytics, or leave as 'null' to prompt admin on first launch
enablePosthog: null # Enable PostHog analytics (open-source product analytics): set to 'true' to enable, 'false' to disable, or 'null' to enable by default when analytics is enabled
enableScarf: null # Enable Scarf pixel: set to 'true' to enable, 'false' to disable, or 'null' to enable by default when analytics is enabled
enableUrlToPDF: false # Set to 'true' to enable URL to PDF, INTERNAL ONLY, known security issues, should not be used externally
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
maxDPI: 500 # Maximum allowed DPI for PDF to image conversion
@@ -7,6 +7,13 @@
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-classic",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.19",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
@@ -14,6 +21,13 @@
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "ch.qos.logback:logback-core",
"moduleUrl": "http://www.qos.ch",
"moduleVersion": "1.5.19",
"moduleLicense": "GNU Lesser General Public License",
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
},
{
"moduleName": "com.adobe.xmp:xmpcore",
"moduleUrl": "https://www.adobe.com/devnet/xmp/library/eula-xmp-library-java.html",
@@ -151,6 +165,13 @@
"moduleVersion": "1.4.0",
"moduleLicense": "LICENSE-JJ2000.txt, LICENSE-Sun.txt"
},
{
"moduleName": "com.github.junrar:junrar",
"moduleUrl": "https://github.com/junrar/junrar",
"moduleVersion": "7.5.5",
"moduleLicense": "UnRar License",
"moduleLicenseUrl": "https://github.com/junrar/junrar/blob/master/LICENSE"
},
{
"moduleName": "com.github.stephenc.jcip:jcip-annotations",
"moduleUrl": "http://stephenc.github.com/jcip-annotations",
@@ -168,7 +189,7 @@
{
"moduleName": "com.google.code.gson:gson",
"moduleUrl": "https://github.com/google/gson",
"moduleVersion": "2.13.1",
"moduleVersion": "2.13.2",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -179,6 +200,13 @@
"moduleLicense": "Apache 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.errorprone:error_prone_annotations",
"moduleUrl": "https://errorprone.info/error_prone_annotations",
"moduleVersion": "2.41.0",
"moduleLicense": "Apache 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "com.google.guava:failureaccess",
"moduleUrl": "https://github.com/google/guava/",
@@ -263,7 +291,7 @@
{
"moduleName": "com.nimbusds:nimbus-jose-jwt",
"moduleUrl": "https://connect2id.com",
"moduleVersion": "9.37.3",
"moduleVersion": "9.37.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -504,7 +532,7 @@
{
"moduleName": "com.zaxxer:HikariCP",
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
"moduleVersion": "6.3.2",
"moduleVersion": "6.3.3",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -587,35 +615,35 @@
{
"moduleName": "io.micrometer:micrometer-commons",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.15.3",
"moduleVersion": "1.15.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-core",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.15.3",
"moduleVersion": "1.15.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-jakarta9",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.15.3",
"moduleVersion": "1.15.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-observation",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.15.3",
"moduleVersion": "1.15.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "io.micrometer:micrometer-registry-prometheus",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.15.3",
"moduleVersion": "1.15.4",
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -668,6 +696,13 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-annotations-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-annotations",
"moduleVersion": "2.2.38",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-core-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-core",
@@ -675,6 +710,13 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-core-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-core",
"moduleVersion": "2.2.38",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-models-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-models",
@@ -682,10 +724,17 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "io.swagger.core.v3:swagger-models-jakarta",
"moduleUrl": "https://github.com/swagger-api/swagger-core/modules/swagger-models",
"moduleVersion": "2.2.38",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "jakarta.activation:jakarta.activation-api",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "2.1.3",
"moduleVersion": "2.1.4",
"moduleLicense": "GNU General Public License, version 2 with the GNU Classpath Exception",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
@@ -727,14 +776,14 @@
{
"moduleName": "jakarta.mail:jakarta.mail-api",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "2.1.3",
"moduleVersion": "2.1.4",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "jakarta.mail:jakarta.mail-api",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "2.1.4",
"moduleVersion": "2.1.5",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
@@ -886,7 +935,7 @@
{
"moduleName": "org.apache.commons:commons-lang3",
"moduleUrl": "https://commons.apache.org/proper/commons-lang/",
"moduleVersion": "3.18.0",
"moduleVersion": "3.19.0",
"moduleLicense": "Apache-2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -981,7 +1030,7 @@
{
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
"moduleUrl": "https://tomcat.apache.org/",
"moduleVersion": "10.1.44",
"moduleVersion": "10.1.46",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
},
@@ -1029,14 +1078,14 @@
{
"moduleName": "org.bouncycastle:bcpkix-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.81",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
{
"moduleName": "org.bouncycastle:bcprov-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.81",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
@@ -1050,7 +1099,7 @@
{
"moduleName": "org.bouncycastle:bcutil-jdk18on",
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
"moduleVersion": "1.81",
"moduleVersion": "1.82",
"moduleLicense": "Bouncy Castle Licence",
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
},
@@ -1061,15 +1110,22 @@
"moduleLicense": "The MIT License",
"moduleLicenseUrl": "http://opensource.org/licenses/MIT"
},
{
"moduleName": "org.checkerframework:checker-qual",
"moduleUrl": "https://checkerframework.org/",
"moduleVersion": "3.49.5",
"moduleLicense": "The MIT License",
"moduleLicenseUrl": "http://opensource.org/licenses/MIT"
},
{
"moduleName": "org.commonmark:commonmark",
"moduleVersion": "0.25.1",
"moduleVersion": "0.27.0",
"moduleLicense": "BSD-2-Clause",
"moduleLicenseUrl": "https://opensource.org/licenses/BSD-2-Clause"
},
{
"moduleName": "org.commonmark:commonmark-ext-gfm-tables",
"moduleVersion": "0.25.1",
"moduleVersion": "0.27.0",
"moduleLicense": "BSD-2-Clause",
"moduleLicenseUrl": "https://opensource.org/licenses/BSD-2-Clause"
},
@@ -1094,6 +1150,13 @@
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.eclipse.angus:angus-mail",
"moduleUrl": "https://www.eclipse.org",
"moduleVersion": "2.0.5",
"moduleLicense": "GPL2 w/ CPE",
"moduleLicenseUrl": "https://www.gnu.org/software/classpath/license.html"
},
{
"moduleName": "org.eclipse.angus:jakarta.mail",
"moduleUrl": "https://www.eclipse.org",
@@ -1104,182 +1167,182 @@
{
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-common",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-servlet",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-annotations",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-plus",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlet",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlets",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-webapp",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-client",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-common",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-server",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-api",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-common",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-alpn-client",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-client",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-ee",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-http",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-io",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-plus",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-security",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-server",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-session",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-util",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
{
"moduleName": "org.eclipse.jetty:jetty-xml",
"moduleUrl": "https://jetty.org/",
"moduleVersion": "12.0.25",
"moduleVersion": "12.0.27",
"moduleLicense": "Eclipse Public License - Version 2.0",
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
},
@@ -1321,7 +1384,7 @@
{
"moduleName": "org.hibernate.orm:hibernate-core",
"moduleUrl": "https://www.hibernate.org/orm/6.6",
"moduleVersion": "6.6.26.Final",
"moduleVersion": "6.6.29.Final",
"moduleLicense": "GNU Library General Public License v2.1 or later",
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
},
@@ -1497,6 +1560,13 @@
"moduleLicense": "BSD-2-Clause",
"moduleLicenseUrl": "https://jdbc.postgresql.org/about/license.html"
},
{
"moduleName": "org.postgresql:postgresql",
"moduleUrl": "https://jdbc.postgresql.org/",
"moduleVersion": "42.7.8",
"moduleLicense": "BSD-2-Clause",
"moduleLicenseUrl": "https://jdbc.postgresql.org/about/license.html"
},
{
"moduleName": "org.slf4j:jul-to-slf4j",
"moduleUrl": "http://www.slf4j.org",
@@ -1520,229 +1590,229 @@
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-common",
"moduleVersion": "2.8.12",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-webmvc-api",
"moduleVersion": "2.8.12",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.springdoc:springdoc-openapi-starter-webmvc-ui",
"moduleVersion": "2.8.12",
"moduleVersion": "2.8.13",
"moduleLicense": "The Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
},
{
"moduleName": "org.springframework.boot:spring-boot",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-actuator",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-autoconfigure",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-devtools",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-aop",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-cache",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-json",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-logging",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-mail",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-security",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-validation",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.boot:spring-boot-starter-web",
"moduleUrl": "https://spring.io/projects/spring-boot",
"moduleVersion": "3.5.5",
"moduleVersion": "3.5.6",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.data:spring-data-commons",
"moduleUrl": "https://spring.io/projects/spring-data",
"moduleVersion": "3.5.3",
"moduleVersion": "3.5.4",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.data:spring-data-jpa",
"moduleUrl": "https://projects.spring.io/spring-data-jpa",
"moduleVersion": "3.5.3",
"moduleVersion": "3.5.4",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-config",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-core",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-crypto",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-oauth2-client",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-oauth2-core",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-oauth2-jose",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-saml2-service-provider",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework.security:spring-security-web",
"moduleUrl": "https://spring.io/projects/spring-security",
"moduleVersion": "6.5.3",
"moduleVersion": "6.5.5",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
@@ -1756,91 +1826,91 @@
{
"moduleName": "org.springframework:spring-aop",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-aspects",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-beans",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-context",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-context-support",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-core",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-expression",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-jcl",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-jdbc",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-orm",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-tx",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-web",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "org.springframework:spring-webmvc",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.2.10",
"moduleVersion": "6.2.11",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
@@ -1878,7 +1948,7 @@
{
"moduleName": "org.webjars:swagger-ui",
"moduleUrl": "https://www.webjars.org",
"moduleVersion": "5.28.0",
"moduleVersion": "5.28.1",
"moduleLicense": "Apache-2.0"
},
{
@@ -703,14 +703,40 @@ class PdfContainer {
async exportPdf(selected) {
const pdfDoc = await PDFLib.PDFDocument.create();
const pageContainers = this.pagesContainer.querySelectorAll('.page-container'); // Select all .page-container elements
const docPageMap = new Map();
pageContainers.forEach((container, index) => {
if (selected && !window.selectedPages.includes(index + 1)) {
return;
}
const img = container.querySelector('img');
if (!img?.doc) {
return;
}
let entry = docPageMap.get(img.doc);
if (!entry) {
entry = { indices: [], copiedPages: [], cursor: 0 };
docPageMap.set(img.doc, entry);
}
entry.indices.push(img.pageIdx);
});
for (const [doc, entry] of docPageMap.entries()) {
entry.copiedPages = await pdfDoc.copyPages(doc, entry.indices);
}
for (var i = 0; i < pageContainers.length; i++) {
if (!selected || window.selectedPages.includes(i + 1)) {
const img = pageContainers[i].querySelector('img'); // Find the img element within each .page-container
if (!img) continue;
let page;
if (img.doc) {
const pages = await pdfDoc.copyPages(img.doc, [img.pageIdx]);
page = pages[0];
const entry = docPageMap.get(img.doc);
page = entry.copiedPages[entry.cursor++];
pdfDoc.addPage(page);
} else {
page = pdfDoc.addPage([img.naturalWidth, img.naturalHeight]);
@@ -3,6 +3,19 @@ import './cookieconsent.umd.js';
// Enable dark mode
document.documentElement.classList.add('cc--darkmode');
// Build analytics services dynamically based on backend config
const analyticsServices = {};
if (typeof posthogEnabled !== 'undefined' && posthogEnabled) {
analyticsServices.posthog = {
label: cookieBannerPreferencesModalPosthogLabel
};
}
if (typeof scarfEnabled !== 'undefined' && scarfEnabled) {
analyticsServices.scarf = {
label: cookieBannerPreferencesModalScarfLabel
};
}
CookieConsent.run({
guiOptions: {
consentModal: {
@@ -22,7 +35,9 @@ CookieConsent.run({
necessary: {
readOnly: true
},
analytics: {}
analytics: {
services: analyticsServices
}
},
language: {
default: "en",
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html th:data-language="${#locale.toString()}" th:dir="#{language.direction}" th:lang="${#locale.language}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{pdfToVector.title}, header=#{pdfToVector.header})}"></th:block>
</head>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon convert">stroke_full</span>
<span class="tool-header-text" th:text="#{pdfToVector.header}"></span>
</div>
<form enctype="multipart/form-data" method="post" th:action="@{'/api/v1/convert/pdf/vector'}">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<div class="mb-3">
<label for="outputFormat" th:text="#{pdfToVector.outputFormat}"></label>
<select class="form-control" id="outputFormat" name="outputFormat">
<option selected value="eps">EPS (Encapsulated PostScript)</option>
<option value="ps">PS (PostScript)</option>
<option value="pcl">PCL (Printer Command Language)</option>
<option value="xps">XPS (XML Paper Specification)</option>
</select>
</div>
<button class="btn btn-primary" id="submitBtn" th:text="#{pdfToVector.submit}" type="submit"></button>
</form>
<p class="mt-3" th:text="#{pdfToVector.description}"></p>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html th:data-language="${#locale.toString()}" th:dir="#{language.direction}" th:lang="${#locale.language}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{vectorToPdf.title}, header=#{vectorToPdf.header})}"></th:block>
</head>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon convertto">picture_as_pdf</span>
<span class="tool-header-text" th:text="#{vectorToPdf.header}"></span>
</div>
<form enctype="multipart/form-data" method="post" th:action="@{'/api/v1/convert/vector/pdf'}">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='.ps,.eps,.epsf,application/pdf')}">
</div>
<div class="form-check mb-3">
<input id="prepress" name="prepress" type="checkbox" value="true">
<label for="prepress" th:text="#{vectorToPdf.prepress}"></label>
</div>
<button class="btn btn-primary" id="submitBtn" th:text="#{vectorToPdf.submit}" type="submit"></button>
</form>
<p class="mt-3" th:text="#{vectorToPdf.description}"></p>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
@@ -168,14 +168,51 @@
<!-- Bootstrap Icons -->
<link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}">
<!-- Pixel, doesn't collect any PII-->
<img th:if="${!@disablePixel}" referrerpolicy="no-referrer-when-downgrade"
th:src="'https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92'
+ '&machineType=' + ${@machineType}
+ '&appVersion=' + ${@appVersion}
+ '&licenseType=' + ${@license}
+ '&loginEnabled=' + ${@loginEnabled}"
style="position: absolute; visibility: hidden;" />
<!-- Scarf Pixel - loaded dynamically based on cookie consent -->
<script th:inline="javascript">
const posthogEnabled = /*[[${@posthogEnabled}]]*/ false;
const scarfEnabled = /*[[${@scarfEnabled}]]*/ false;
const scarfPixelUrl = /*[['https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92'
+ '&machineType=' + ${@machineType}
+ '&appVersion=' + ${@appVersion}
+ '&licenseType=' + ${@license}
+ '&loginEnabled=' + ${@loginEnabled}]]*/ '';
function loadScarfPixel() {
if (!scarfEnabled || !window.CookieConsent) return;
// Check if scarf service is accepted
if (window.CookieConsent.acceptedService('scarf', 'analytics')) {
// Remove any existing scarf pixel
const existingPixel = document.getElementById('scarf-pixel');
if (existingPixel) existingPixel.remove();
// Create and inject the pixel
const img = document.createElement('img');
img.id = 'scarf-pixel';
img.src = scarfPixelUrl;
img.referrerPolicy = 'no-referrer-when-downgrade';
img.style.position = 'absolute';
img.style.visibility = 'hidden';
document.body.appendChild(img);
} else {
// Remove pixel if user rejected
const existingPixel = document.getElementById('scarf-pixel');
if (existingPixel) existingPixel.remove();
}
}
// Load pixel on consent events
window.addEventListener('cc:onConsent', loadScarfPixel);
window.addEventListener('cc:onChange', loadScarfPixel);
// Try to load on page load if consent already given
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadScarfPixel);
} else {
loadScarfPixel();
}
</script>
<!-- Custom -->
<link rel="stylesheet" th:href="@{'/css/general.css'}">
@@ -221,7 +258,7 @@
return;
}
window.CookieConsent.acceptedCategory('analytics')?
window.CookieConsent.acceptedService('posthog', 'analytics')?
posthog.opt_in_capturing() : posthog.opt_out_capturing();
}
const stirlingPDFLabel = /*[[${@StirlingPDFLabel}]]*/ '';
@@ -248,6 +285,8 @@
const cookieBannerPreferencesModalNecessaryDescription = /*[[#{cookieBanner.preferencesModal.necessary.description}]]*/ "";
const cookieBannerPreferencesModalAnalyticsTitle = /*[[#{cookieBanner.preferencesModal.analytics.title}]]*/ "";
const cookieBannerPreferencesModalAnalyticsDescription = /*[[#{cookieBanner.preferencesModal.analytics.description}]]*/ "";
const cookieBannerPreferencesModalPosthogLabel = /*[[#{cookieBanner.preferencesModal.analytics.posthog.label}]]*/ "";
const cookieBannerPreferencesModalScarfLabel = /*[[#{cookieBanner.preferencesModal.analytics.scarf.label}]]*/ "";
if (analyticsEnabled) {
!function (t, e) {
@@ -68,6 +68,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('eml-to-pdf', 'email', 'home.EMLToPDF.title', 'home.EMLToPDF.desc', 'EMLToPDF.tags', 'convertto')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('vector-to-pdf', 'picture_as_pdf', 'home.vectorToPdf.title', 'home.vectorToPdf.desc', 'vectorToPdf.tags', 'convertto')}">
</div>
</div>
</div>
<div id="groupConvertFrom" class="feature-group">
@@ -107,6 +110,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-markdown', 'markdown_copy', 'home.PDFToMarkdown.title', 'home.PDFToMarkdown.desc', 'PDFToMarkdown.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-vector', 'stroke_full', 'home.pdfToVector.title', 'home.pdfToVector.desc', 'pdfToVector.tags', 'convert')}">
</div>
</div>
</div>
@@ -135,6 +141,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('markdown-to-pdf', 'markdown', 'home.MarkdownToPDF.title', 'home.MarkdownToPDF.desc', 'MarkdownToPDF.tags', 'convertto')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('vector-to-pdf', 'picture_as_pdf', 'home.vectorToPdf.title', 'home.vectorToPdf.desc', 'vectorToPdf.tags', 'convertto')}">
</div>
</div>
<div th:replace="~{fragments/featureGroupHeader :: featureGroupHeader(groupTitle=#{navbar.sections.convertFrom})}">
</div>
@@ -163,6 +172,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-csv', 'csv', 'home.tableExtraxt.title', 'home.tableExtraxt.desc', 'tableExtraxt.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-vector', 'stroke_full', 'home.pdfToVector.title', 'home.pdfToVector.desc', 'pdfToVector.tags', 'convert')}">
</div>
</div>
</div>
<div id="groupSecurity" class="feature-group">
@@ -258,6 +270,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('add-attachments', 'attachment', 'home.attachments.title', 'home.attachments.desc', 'attachments.tags', 'other')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('extract-attachments', 'folder_zip', 'home.extractAttachments.title', 'home.extractAttachments.desc', 'extractAttachments.tags', 'other')}">
</div>
</div>
</div>
<div id="groupAdvanced" class="feature-group">
@@ -293,6 +293,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('add-attachments', 'attachment', 'home.attachments.title', 'home.attachments.desc', 'attachments.tags', 'other')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('extract-attachments', 'folder_zip', 'home.extractAttachments.title', 'home.extractAttachments.desc', 'extractAttachments.tags', 'other')}">
</div>
</div>
</div>
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}"
th:dir="#{language.direction}"
th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{extractAttachments.title}, header=#{extractAttachments.header})}">
</th:block>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon other">folder_zip</span>
<span class="tool-header-text"
th:text="#{extractAttachments.header}"></span>
</div>
<p class="tool-description"
th:text="#{extractAttachments.description}"></p>
<form action="#"
th:action="@{/api/v1/misc/extract-attachments}"
method="post"
enctype="multipart/form-data">
<!-- PDF file selector -->
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', disableMultipleFiles=true, multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<!-- Submit button -->
<button type="submit"
id="submitBtn"
class="btn btn-primary"
th:text="#{extractAttachments.downloadButton}">Extract Attachments</button>
</form>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
@@ -24,7 +24,20 @@
<div class="form-check ms-3">
<input id="flattenOnlyForms" name="flattenOnlyForms" type="checkbox">
<label for="flattenOnlyForms" th:text="#{flatten.flattenOnlyForms}" ></label>
</div>
</div>
<div class="form-group ms-3 mt-2">
<label class="form-label" for="renderDpi" th:text="#{flatten.renderDpi}"></label>
<input
class="form-control"
id="renderDpi"
min="72"
name="renderDpi"
step="1"
th:attr="aria-describedby=${'renderDpiHelp'}"
type="number"
>
<small class="form-text text-muted" id="renderDpiHelp" th:text="#{flatten.renderDpi.help}"></small>
</div>
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{flatten.submit}"></button>
</form>
@@ -81,6 +81,29 @@
</div>
</div>
<!-- Technical Details section -->
<div class="mt-4 mb-3">
<h6 id="summary-technical-heading">Technical Details</h6>
<div class="row">
<div class="col-md-6">
<ul class="list-unstyled">
<li><strong>Images:</strong> <span id="summary-images">-</span></li>
<li><strong>Fonts:</strong> <span id="summary-fonts">-</span></li>
<li><strong>Form Fields:</strong> <span id="summary-form-fields">-</span></li>
<li><strong>Embedded Files:</strong> <span id="summary-embedded-files">-</span></li>
</ul>
</div>
<div class="col-md-6">
<ul class="list-unstyled">
<li><strong>JavaScript:</strong> <span id="summary-javascript">-</span></li>
<li><strong>Layers:</strong> <span id="summary-layers">-</span></li>
<li><strong>Bookmarks:</strong> <span id="summary-bookmarks">-</span></li>
<li><strong>Multimedia:</strong> <span id="summary-multimedia">-</span></li>
</ul>
</div>
</div>
</div>
<!-- Detailed alerts -->
<div id="summary-alerts" class="mt-3">
<!-- Will be populated with detailed alerts for encryption, permissions, etc. -->
@@ -121,6 +144,7 @@
const getPdfInfoSummaryAllPermissionsAlert = /*[[#{getPdfInfo.summary.all.permissions.alert}]]*/ "All Permissions Allowed";
const getPdfInfoSummaryComplianceAlert = /*[[#{getPdfInfo.summary.compliance.alert}]]*/ "{0} Compliant";
const getPdfInfoSummaryNoComplianceAlert = /*[[#{getPdfInfo.summary.no.compliance.alert}]]*/ "No Compliance Standards";
const getPdfInfoSummaryTechnicalSection = /*[[#{getPdfInfo.summary.technical.section}]]*/ "Technical Details";
// Update the summary headings
document.addEventListener('DOMContentLoaded', function() {
@@ -128,6 +152,7 @@
document.getElementById('summary-basic-info-heading').textContent = getPdfInfoSummaryBasicInfo;
document.getElementById('summary-doc-info-heading').textContent = getPdfInfoSummaryDocInfo;
document.getElementById('summary-security-heading').textContent = getPdfInfoSummarySecuritySection;
document.getElementById('summary-technical-heading').textContent = getPdfInfoSummaryTechnicalSection;
});
// Pre-load section descriptions
@@ -141,6 +166,16 @@
const getPdfInfoSectionFormFields = /*[[#{getPdfInfo.section.FormFields}]]*/ "Interactive form fields present in the document";
const getPdfInfoSectionPerPageInfo = /*[[#{getPdfInfo.section.PerPageInfo}]]*/ "Detailed information about each page in the document";
/**
* Form submission handler for PDF info extraction.
*
* Process:
* 1. Submit PDF to backend endpoint
* 2. Receive JSON with sections: Metadata, BasicInfo, DocumentInfo, etc.
* 3. Populate summary section from the detailed data
* 4. Display all sections in collapsible cards
* 5. Provide JSON download option
*/
document.getElementById("pdfInfoForm").addEventListener("submit", function(event) {
event.preventDefault();
@@ -154,14 +189,29 @@
fetchWithCsrf('api/v1/security/get-info-on-pdf', {
method: 'POST',
body: formData
}).then(response => response.json()).then(data => {
}).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}).then(data => {
// Check if response contains an error
if (data && data.error) {
console.error('Server error:', data.error);
alert('Error: ' + data.error);
return;
}
// Populate and display the enhanced PDF summary
populateSummarySection(data);
displayJsonData(data);
setDownloadLink(data);
document.getElementById("downloadJson").style.display = "block";
}).catch(error => console.error('Error:', error));
}).catch(error => {
console.error('Error:', error);
alert('An error occurred while processing the PDF. Please try again.');
});
// Function to reset all summary elements to default state
function resetSummaryElements() {
@@ -177,6 +227,16 @@
document.getElementById('summary-created').textContent = '-';
document.getElementById('summary-modified').textContent = '-';
// Reset technical details fields
document.getElementById('summary-images').textContent = '-';
document.getElementById('summary-fonts').textContent = '-';
document.getElementById('summary-form-fields').textContent = '-';
document.getElementById('summary-embedded-files').textContent = '-';
document.getElementById('summary-javascript').textContent = '-';
document.getElementById('summary-layers').textContent = '-';
document.getElementById('summary-bookmarks').textContent = '-';
document.getElementById('summary-multimedia').textContent = '-';
// Reset security status cards
const cards = ['encryption-status', 'permissions-status', 'compliance-status'];
cards.forEach(id => {
@@ -208,12 +268,12 @@
resetSummaryElements();
// Get basic information
if (data.BasicInfo) {
if (data && data.BasicInfo) {
document.getElementById('summary-pages').textContent = data.BasicInfo["Number of pages"] || "-";
// Format file size nicely
let fileSize = data.BasicInfo["FileSizeInBytes"];
if (fileSize) {
if (fileSize && fileSize > 0) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(fileSize) / Math.log(1024));
fileSize = (fileSize / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
@@ -224,18 +284,113 @@
}
// Get document information
if (data.DocumentInfo) {
if (data && data.DocumentInfo) {
document.getElementById('summary-version').textContent = data.DocumentInfo["PDF version"] || "-";
}
// Get metadata
if (data.Metadata) {
if (data && data.Metadata) {
document.getElementById('summary-title').textContent = data.Metadata["Title"] || "-";
document.getElementById('summary-author').textContent = data.Metadata["Author"] || "-";
document.getElementById('summary-created').textContent = data.Metadata["CreationDate"] || "-";
document.getElementById('summary-modified').textContent = data.Metadata["ModificationDate"] || "-";
}
// Populate technical details
if (data && data.BasicInfo) {
// Images
const totalImages = data.BasicInfo.TotalImages || 0;
const uniqueImages = data.BasicInfo.UniqueImages || 0;
if (totalImages > 0) {
document.getElementById('summary-images').textContent = `${totalImages} total (${uniqueImages} unique)`;
} else {
document.getElementById('summary-images').textContent = 'None';
}
}
// Count fonts from PerPageInfo
if (data && data.PerPageInfo) {
let totalFonts = 0;
let embeddedFonts = 0;
const fontSet = new Set();
for (const pageKey in data.PerPageInfo) {
const pageData = data.PerPageInfo[pageKey];
// Count fonts
if (pageData.Fonts && Array.isArray(pageData.Fonts)) {
pageData.Fonts.forEach(font => {
const fontKey = JSON.stringify([font.Name, font.Subtype]);
fontSet.add(fontKey);
if (font.IsEmbedded) {
embeddedFonts++;
}
});
}
}
// Display fonts
totalFonts = fontSet.size;
if (totalFonts > 0) {
document.getElementById('summary-fonts').textContent = `${totalFonts} (${embeddedFonts} embedded)`;
} else {
document.getElementById('summary-fonts').textContent = 'None';
}
}
// Form fields
if (data && data.FormFields) {
const formFieldCount = Object.keys(data.FormFields).length;
document.getElementById('summary-form-fields').textContent = formFieldCount > 0 ? formFieldCount : 'None';
}
// Other section data
if (data && data.Other) {
// Embedded files
const embeddedFiles = data.Other.EmbeddedFiles;
if (embeddedFiles && Array.isArray(embeddedFiles)) {
document.getElementById('summary-embedded-files').textContent = embeddedFiles.length > 0 ? embeddedFiles.length : 'None';
} else {
document.getElementById('summary-embedded-files').textContent = 'None';
}
// JavaScript
const javascript = data.Other.JavaScript;
if (javascript && Array.isArray(javascript)) {
document.getElementById('summary-javascript').textContent = javascript.length > 0 ? `Yes (${javascript.length} scripts)` : 'None';
} else {
document.getElementById('summary-javascript').textContent = 'None';
}
// Layers
const layers = data.Other.Layers;
if (layers && Array.isArray(layers)) {
document.getElementById('summary-layers').textContent = layers.length > 0 ? layers.length : 'None';
} else {
document.getElementById('summary-layers').textContent = 'None';
}
// Bookmarks
const bookmarks = data.Other["Bookmarks/Outline/TOC"];
if (bookmarks && Array.isArray(bookmarks)) {
document.getElementById('summary-bookmarks').textContent = bookmarks.length > 0 ? bookmarks.length : 'None';
} else {
document.getElementById('summary-bookmarks').textContent = 'None';
}
}
// Count multimedia from pages
if (data && data.PerPageInfo) {
let multimediaCount = 0;
for (const pageKey in data.PerPageInfo) {
const pageData = data.PerPageInfo[pageKey];
if (pageData.Multimedia && Array.isArray(pageData.Multimedia)) {
multimediaCount += pageData.Multimedia.length;
}
}
document.getElementById('summary-multimedia').textContent = multimediaCount > 0 ? multimediaCount : 'None';
}
// Update security status cards
// Encryption status
@@ -257,7 +412,7 @@
const permissionsText = document.getElementById('permissions-text');
let restrictedPermissions = [];
if (data.Permissions) {
if (data && data.Permissions) {
for (const [permission, state] of Object.entries(data.Permissions)) {
if (state === "Not Allowed") {
restrictedPermissions.push(permission);
@@ -282,7 +437,7 @@
let hasCompliance = false;
let compliantStandards = [];
if (data.Compliancy) {
if (data && data.Compliancy) {
for (const [standard, compliant] of Object.entries(data.Compliancy)) {
if (compliant === true) {
hasCompliance = true;
@@ -311,7 +466,7 @@
let hasSummaryInfo = false;
// Create a consolidated security details card if there are security details worth highlighting
if ((data.Encryption && data.Encryption.IsEncrypted) ||
if ((data && data.Encryption && data.Encryption.IsEncrypted) ||
restrictedPermissions.length > 0 ||
hasCompliance) {
@@ -407,22 +562,22 @@
const summaryTextElement = document.getElementById('summary-text');
// Create a general summary for the document
let generalSummary = `This is a ${data.BasicInfo["Number of pages"] || "multi"}-page PDF`;
let generalSummary = `This is a ${(data && data.BasicInfo && data.BasicInfo["Number of pages"]) ? data.BasicInfo["Number of pages"] : "multi"}-page PDF`;
if (data.Metadata && data.Metadata["Title"]) {
if (data && data.Metadata && data.Metadata["Title"]) {
generalSummary += ` titled "${data.Metadata["Title"]}"`;
}
if (data.Metadata && data.Metadata["Author"]) {
if (data && data.Metadata && data.Metadata["Author"]) {
generalSummary += ` created by ${data.Metadata["Author"]}`;
}
if (data.DocumentInfo && data.DocumentInfo["PDF version"]) {
if (data && data.DocumentInfo && data.DocumentInfo["PDF version"]) {
generalSummary += ` (PDF version ${data.DocumentInfo["PDF version"]})`;
}
// Add security information to the general summary if relevant
if (data.Encryption && data.Encryption.IsEncrypted) {
if (data && data.Encryption && data.Encryption.IsEncrypted) {
generalSummary += '. The document is password protected';
if (data.Encryption.EncryptionAlgorithm) {
@@ -443,42 +598,40 @@
generalSummary += `. This document complies with the ${compliantStandards.join(', ')} PDF standard${compliantStandards.length > 1 ? 's' : ''}`;
}
generalSummary += '.';
// Add interesting technical details
const technicalFeatures = [];
// Remove SummaryData from JSON to avoid duplication
if (data.SummaryData) {
delete data.SummaryData;
// Check for JavaScript
if (data && data.Other && data.Other.JavaScript && Array.isArray(data.Other.JavaScript) && data.Other.JavaScript.length > 0) {
technicalFeatures.push(`${data.Other.JavaScript.length} JavaScript script${data.Other.JavaScript.length > 1 ? 's' : ''}`);
}
// Check for embedded files
if (data && data.Other && data.Other.EmbeddedFiles && Array.isArray(data.Other.EmbeddedFiles) && data.Other.EmbeddedFiles.length > 0) {
technicalFeatures.push(`${data.Other.EmbeddedFiles.length} embedded file${data.Other.EmbeddedFiles.length > 1 ? 's' : ''}`);
}
// Check for layers
if (data && data.Other && data.Other.Layers && Array.isArray(data.Other.Layers) && data.Other.Layers.length > 0) {
technicalFeatures.push(`${data.Other.Layers.length} layer${data.Other.Layers.length > 1 ? 's' : ''}`);
}
// Check for form fields
if (data && data.FormFields && Object.keys(data.FormFields).length > 0) {
technicalFeatures.push(`${Object.keys(data.FormFields).length} form field${Object.keys(data.FormFields).length > 1 ? 's' : ''}`);
}
if (technicalFeatures.length > 0) {
generalSummary += `. The PDF contains ${technicalFeatures.join(', ')}`;
}
generalSummary += '.';
summaryTextElement.innerHTML = generalSummary;
// Display the summary section
document.getElementById('pdf-summary').style.display = 'block';
}
function generateSummaryFromData(summaryData) {
let summary = [];
// Handle encryption information
if (summaryData.encrypted) {
summary.push(getPdfInfoSummaryEncrypted);
}
// Handle permissions information
if (summaryData.restrictedPermissions && summaryData.restrictedPermissions.length > 0) {
const formattedPermissionsText = getPdfInfoSummaryPermissions.replace('{0}', summaryData.restrictedPermissionsCount);
summary.push(formattedPermissionsText);
}
// Handle standard compliance information
if (summaryData.standardCompliance) {
const formattedComplianceText = getPdfInfoSummaryCompliance
.replace('{0}', summaryData.standardCompliance);
summary.push(formattedComplianceText);
}
return summary.join(' ');
}
});
function displayJsonData(jsonData) {
@@ -1,7 +1,6 @@
package stirling.software.SPDF.controller.api;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.io.ByteArrayOutputStream;
@@ -1,8 +1,6 @@
package stirling.software.SPDF.controller.api;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;
import java.io.IOException;
@@ -3,14 +3,19 @@ package stirling.software.SPDF.controller.api.converters;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
@@ -51,18 +56,18 @@ public class ConvertWebsiteToPdfTest {
void setUp() throws Exception {
mocks = MockitoAnnotations.openMocks(this);
// Feature einschalten (ggf. Struktur an dein Projekt anpassen)
// Enable feature (adjust structure for your project if necessary)
applicationProperties = new ApplicationProperties();
applicationProperties.getSystem().setEnableUrlToPDF(true);
// Stubs, falls der Code weiterlaufen sollte
// Stubs in case the code continues to run
when(runtimePathConfig.getWeasyPrintPath()).thenReturn("/usr/bin/weasyprint");
when(pdfDocumentFactory.load(any(File.class))).thenReturn(new PDDocument());
// SUT bauen
// Build SUT
sut = new ConvertWebsiteToPDF(pdfDocumentFactory, runtimePathConfig, applicationProperties);
// RequestContext für ServletUriComponentsBuilder bereitstellen
// Provide RequestContext for ServletUriComponentsBuilder
MockHttpServletRequest req = new MockHttpServletRequest();
req.setScheme("http");
req.setServerName("localhost");
@@ -94,7 +99,7 @@ public class ConvertWebsiteToPdfTest {
@Test
void redirect_with_error_when_url_is_not_reachable() throws Exception {
UrlToPdfRequest request = new UrlToPdfRequest();
// .invalid ist per RFC reserviert und nicht auflösbar
// .invalid is reserved by RFC and not resolvable
request.setUrlInput("https://nonexistent.invalid/");
ResponseEntity<?> resp = sut.urlToPdf(request);
@@ -109,7 +114,7 @@ public class ConvertWebsiteToPdfTest {
@Test
void redirect_with_error_when_endpoint_disabled() throws Exception {
// Feature deaktivieren
// Disable feature
applicationProperties.getSystem().setEnableUrlToPDF(false);
UrlToPdfRequest request = new UrlToPdfRequest();
@@ -135,9 +140,9 @@ public class ConvertWebsiteToPdfTest {
String out = (String) m.invoke(sut, in);
assertTrue(out.endsWith(".pdf"));
// Nur AZ, az, 09, Unterstrich und Punkt erlaubt
// Only AZ, az, 09, underscore and dot allowed
assertTrue(out.matches("[A-Za-z0-9_]+\\.pdf"));
// keine Truncation hier (Quelle ist nicht so lang)
// no truncation here (source not that long)
assertTrue(out.length() <= 54);
}
@@ -147,14 +152,14 @@ public class ConvertWebsiteToPdfTest {
ConvertWebsiteToPDF.class.getDeclaredMethod("convertURLToFileName", String.class);
m.setAccessible(true);
// Sehr lange URL löst Truncation aus
// Very long URL -> triggers truncation
String longUrl =
"https://very-very-long-domain.example.com/some/really/long/path/with?many=params&and=chars";
String out = (String) m.invoke(sut, longUrl);
assertTrue(out.endsWith(".pdf"));
assertTrue(out.matches("[A-Za-z0-9_]+\\.pdf"));
// safeName ist auf 50 begrenzt total max 54 inkl. ".pdf"
// safeName limited to 50 -> total max 54 including '.pdf'
assertTrue(out.length() <= 54, "Filename should be truncated to 50 + '.pdf'");
}
@@ -165,25 +170,26 @@ public class ConvertWebsiteToPdfTest {
try (MockedStatic<ProcessExecutor> pe = Mockito.mockStatic(ProcessExecutor.class);
MockedStatic<WebResponseUtils> wr = Mockito.mockStatic(WebResponseUtils.class);
MockedStatic<GeneralUtils> gu = Mockito.mockStatic(GeneralUtils.class)) {
MockedStatic<GeneralUtils> gu = Mockito.mockStatic(GeneralUtils.class);
MockedStatic<HttpClient> httpClient = mockHttpClientReturning("<html></html>")) {
// URL-Checks positiv erzwingen
// Force URL checks to be positive
gu.when(() -> GeneralUtils.isValidURL("https://example.com")).thenReturn(true);
gu.when(() -> GeneralUtils.isURLReachable("https://example.com")).thenReturn(true);
// richtiger ProcessExecutor!
// correct ProcessExecutor!
ProcessExecutor mockExec = Mockito.mock(ProcessExecutor.class);
pe.when(() -> ProcessExecutor.getInstance(Processes.WEASYPRINT)).thenReturn(mockExec);
@SuppressWarnings("unchecked")
ArgumentCaptor<List<String>> cmdCaptor = ArgumentCaptor.forClass(List.class);
// Rückgabewert typgerecht
// Return value of correct type
ProcessExecutorResult dummyResult = Mockito.mock(ProcessExecutorResult.class);
when(mockExec.runCommandWithOutputHandling(cmdCaptor.capture()))
.thenReturn(dummyResult);
// WebResponseUtils mocken
// Mock WebResponseUtils
ResponseEntity<byte[]> fakeResponse = ResponseEntity.ok(new byte[0]);
wr.when(() -> WebResponseUtils.pdfDocToWebResponse(any(PDDocument.class), anyString()))
.thenReturn(fakeResponse);
@@ -194,20 +200,23 @@ public class ConvertWebsiteToPdfTest {
// Assert Response OK
assertEquals(HttpStatus.OK, resp.getStatusCode());
// Assert WeasyPrint-Kommando korrekt
// Assert WeasyPrint command correct
List<String> cmd = cmdCaptor.getValue();
assertNotNull(cmd);
assertEquals("/usr/bin/weasyprint", cmd.get(0));
assertEquals("https://example.com", cmd.get(1));
assertEquals("--pdf-forms", cmd.get(2));
assertTrue(cmd.size() >= 4, "WeasyPrint sollte einen Output-Pfad erhalten");
String outPathStr = cmd.get(3);
assertTrue(cmd.size() >= 6, "WeasyPrint should receive HTML input and output path");
String htmlPathStr = cmd.get(1);
assertEquals("--base-url", cmd.get(2));
assertEquals("https://example.com", cmd.get(3));
assertEquals("--pdf-forms", cmd.get(4));
String outPathStr = cmd.get(5);
assertNotNull(outPathStr);
// Temp-Datei muss im finally gelöscht sein
// Temp file must be deleted in finally
Path outPath = Path.of(outPathStr);
assertFalse(
Files.exists(outPath), "Temp-Output-Datei sollte nach dem Call gelöscht sein");
Files.exists(Path.of(htmlPathStr)),
"Temp HTML file should be deleted after the call");
}
}
@@ -218,21 +227,32 @@ public class ConvertWebsiteToPdfTest {
request.setUrlInput("https://example.com");
Path preCreatedTemp = java.nio.file.Files.createTempFile("test_output_", ".pdf");
Path htmlTemp = java.nio.file.Files.createTempFile("test_input_", ".html");
try (MockedStatic<GeneralUtils> gu = Mockito.mockStatic(GeneralUtils.class);
MockedStatic<ProcessExecutor> pe = Mockito.mockStatic(ProcessExecutor.class);
MockedStatic<WebResponseUtils> wr = Mockito.mockStatic(WebResponseUtils.class);
MockedStatic<Files> files = Mockito.mockStatic(Files.class)) {
MockedStatic<Files> files = Mockito.mockStatic(Files.class);
MockedStatic<HttpClient> httpClient = mockHttpClientReturning("<html></html>")) {
// URL-Checks positiv
// Force URL checks to be positive
gu.when(() -> GeneralUtils.isValidURL("https://example.com")).thenReturn(true);
gu.when(() -> GeneralUtils.isURLReachable("https://example.com")).thenReturn(true);
// Temp-Datei erzwingen + Delete-Fehler provozieren
// Force temp files + provoke delete error
files.when(() -> Files.createTempFile("url_input_", ".html")).thenReturn(htmlTemp);
files.when(() -> Files.createTempFile("output_", ".pdf")).thenReturn(preCreatedTemp);
files.when(
() ->
Files.writeString(
eq(htmlTemp),
anyString(),
eq(java.nio.charset.StandardCharsets.UTF_8)))
.thenReturn(htmlTemp);
files.when(() -> Files.deleteIfExists(htmlTemp)).thenReturn(true);
files.when(() -> Files.deleteIfExists(preCreatedTemp))
.thenThrow(new IOException("fail delete"));
files.when(() -> Files.exists(preCreatedTemp)).thenReturn(true); // für den Assert
files.when(() -> Files.exists(preCreatedTemp)).thenReturn(true); // for the assert
// ProcessExecutor
ProcessExecutor mockExec = Mockito.mock(ProcessExecutor.class);
@@ -245,7 +265,7 @@ public class ConvertWebsiteToPdfTest {
wr.when(() -> WebResponseUtils.pdfDocToWebResponse(any(PDDocument.class), anyString()))
.thenReturn(fakeResponse);
// Act: darf keine Exception werfen und soll eine Response liefern
// Act: should not throw and should return a Response
ResponseEntity<?> resp = assertDoesNotThrow(() -> sut.urlToPdf(request));
// Assert
@@ -253,12 +273,56 @@ public class ConvertWebsiteToPdfTest {
assertEquals(HttpStatus.OK, resp.getStatusCode());
assertTrue(
java.nio.file.Files.exists(preCreatedTemp),
"Temp-Datei sollte trotz Lösch-IOException noch existieren");
"Temp file should still exist despite delete IOException");
} finally {
try {
java.nio.file.Files.deleteIfExists(preCreatedTemp);
java.nio.file.Files.deleteIfExists(htmlTemp);
} catch (IOException ignore) {
}
}
}
@Test
void redirect_with_error_when_disallowed_content_detected() throws Exception {
UrlToPdfRequest request = new UrlToPdfRequest();
request.setUrlInput("https://example.com");
try (MockedStatic<GeneralUtils> gu = Mockito.mockStatic(GeneralUtils.class);
MockedStatic<HttpClient> httpClient =
mockHttpClientReturning(
"<link rel=\"attachment\" href=\"file:///etc/passwd\">"); ) {
gu.when(() -> GeneralUtils.isValidURL("https://example.com")).thenReturn(true);
gu.when(() -> GeneralUtils.isURLReachable("https://example.com")).thenReturn(true);
ResponseEntity<?> resp = sut.urlToPdf(request);
assertEquals(HttpStatus.SEE_OTHER, resp.getStatusCode());
URI location = resp.getHeaders().getLocation();
assertNotNull(location, "Location header expected");
assertTrue(
location.getQuery() != null
&& location.getQuery().contains("error=error.disallowedUrlContent"));
}
}
private MockedStatic<HttpClient> mockHttpClientReturning(String body) throws Exception {
MockedStatic<HttpClient> httpClientStatic = Mockito.mockStatic(HttpClient.class);
HttpClient.Builder builder = Mockito.mock(HttpClient.Builder.class);
HttpClient client = Mockito.mock(HttpClient.class);
HttpResponse<String> response = Mockito.mock(HttpResponse.class);
httpClientStatic.when(HttpClient::newBuilder).thenReturn(builder);
when(builder.followRedirects(HttpClient.Redirect.NORMAL)).thenReturn(builder);
when(builder.connectTimeout(any(Duration.class))).thenReturn(builder);
when(builder.build()).thenReturn(client);
when(client.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class)))
.thenReturn(response);
when(response.statusCode()).thenReturn(200);
when(response.body()).thenReturn(body);
return httpClientStatic;
}
}
@@ -0,0 +1,146 @@
package stirling.software.SPDF.controller.api.converters;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import stirling.software.SPDF.config.EndpointConfiguration;
import stirling.software.SPDF.model.api.converters.PdfVectorExportRequest;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.TempFileManager;
@ExtendWith(MockitoExtension.class)
class PdfVectorExportControllerTest {
private final List<Path> tempPaths = new ArrayList<>();
@Mock private TempFileManager tempFileManager;
@Mock private EndpointConfiguration endpointConfiguration;
@Mock private ProcessExecutor ghostscriptExecutor;
@InjectMocks private PdfVectorExportController controller;
private Map<ProcessExecutor.Processes, ProcessExecutor> originalExecutors;
@BeforeEach
void setup() throws Exception {
when(tempFileManager.createTempFile(any()))
.thenAnswer(
invocation -> {
String suffix = invocation.<String>getArgument(0);
Path path =
Files.createTempFile(
"vector_test", suffix == null ? "" : suffix);
tempPaths.add(path);
return path.toFile();
});
Field instancesField = ProcessExecutor.class.getDeclaredField("instances");
instancesField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<ProcessExecutor.Processes, ProcessExecutor> instances =
(Map<ProcessExecutor.Processes, ProcessExecutor>) instancesField.get(null);
originalExecutors = Map.copyOf(instances);
instances.clear();
instances.put(ProcessExecutor.Processes.GHOSTSCRIPT, ghostscriptExecutor);
}
@AfterEach
void tearDown() throws Exception {
Field instancesField = ProcessExecutor.class.getDeclaredField("instances");
instancesField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<ProcessExecutor.Processes, ProcessExecutor> instances =
(Map<ProcessExecutor.Processes, ProcessExecutor>) instancesField.get(null);
instances.clear();
if (originalExecutors != null) {
instances.putAll(originalExecutors);
}
reset(ghostscriptExecutor, tempFileManager, endpointConfiguration);
for (Path path : tempPaths) {
Files.deleteIfExists(path);
}
tempPaths.clear();
}
private ProcessExecutorResult mockResult(int rc) {
ProcessExecutorResult result = mock(ProcessExecutorResult.class);
lenient().when(result.getRc()).thenReturn(rc);
lenient().when(result.getMessages()).thenReturn("");
return result;
}
@Test
void convertGhostscript_psToPdf_success() throws Exception {
when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(true);
ProcessExecutorResult result = mockResult(0);
when(ghostscriptExecutor.runCommandWithOutputHandling(any())).thenReturn(result);
MockMultipartFile file =
new MockMultipartFile(
"fileInput",
"sample.ps",
MediaType.APPLICATION_OCTET_STREAM_VALUE,
new byte[] {1});
PdfVectorExportRequest request = new PdfVectorExportRequest();
request.setFileInput(file);
ResponseEntity<byte[]> response = controller.convertGhostscriptInputsToPdf(request);
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
}
@Test
void convertGhostscript_pdfPassThrough_success() throws Exception {
when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false);
byte[] content = new byte[] {1};
MockMultipartFile file =
new MockMultipartFile(
"fileInput", "input.pdf", MediaType.APPLICATION_PDF_VALUE, content);
PdfVectorExportRequest request = new PdfVectorExportRequest();
request.setFileInput(file);
ResponseEntity<byte[]> response = controller.convertGhostscriptInputsToPdf(request);
assertThat(response.getStatusCode()).isEqualTo(org.springframework.http.HttpStatus.OK);
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_PDF);
assertThat(response.getBody()).contains(content);
}
@Test
void convertGhostscript_unsupportedFormatThrows() throws Exception {
when(endpointConfiguration.isGroupEnabled("Ghostscript")).thenReturn(false);
MockMultipartFile file =
new MockMultipartFile(
"fileInput", "vector.svg", MediaType.APPLICATION_XML_VALUE, new byte[] {1});
PdfVectorExportRequest request = new PdfVectorExportRequest();
request.setFileInput(file);
assertThrows(
IllegalArgumentException.class,
() -> controller.convertGhostscriptInputsToPdf(request));
}
}
@@ -1,7 +1,6 @@
package stirling.software.SPDF.controller.api.misc;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.io.IOException;
@@ -2,7 +2,6 @@ package stirling.software.SPDF.controller.api.pipeline;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.util.List;
@@ -1,7 +1,6 @@
package stirling.software.SPDF.controller.api.security;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import java.awt.Color;
@@ -0,0 +1,47 @@
package stirling.software.SPDF.model.api.converters;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Set;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
public class PdfVectorExportRequestTest {
private static Validator validator;
@BeforeAll
static void setUpValidator() {
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
validator = factory.getValidator();
}
}
@Test
void whenOutputFormatValid_thenNoViolations() {
PdfVectorExportRequest request = new PdfVectorExportRequest();
request.setOutputFormat("EPS");
Set<ConstraintViolation<PdfVectorExportRequest>> violations = validator.validate(request);
assertThat(violations).isEmpty();
}
@Test
void whenOutputFormatInvalid_thenConstraintViolation() {
PdfVectorExportRequest request = new PdfVectorExportRequest();
request.setOutputFormat("svg");
Set<ConstraintViolation<PdfVectorExportRequest>> violations = validator.validate(request);
assertThat(violations).hasSize(1);
assertThat(violations.iterator().next().getPropertyPath().toString())
.isEqualTo("outputFormat");
}
}
@@ -7,11 +7,15 @@ import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
class AttachmentServiceTest {
@@ -105,4 +109,86 @@ class AttachmentServiceTest {
assertNotNull(result.getDocumentCatalog().getNames());
}
}
@Test
void extractAttachments_SanitizesFilenamesAndExtractsData() throws IOException {
attachmentService = new AttachmentService(1024 * 1024, 5 * 1024 * 1024);
try (var document = new PDDocument()) {
var maliciousAttachment =
new MockMultipartFile(
"file",
"..\\evil/../../tricky.txt",
MediaType.TEXT_PLAIN_VALUE,
"danger".getBytes());
attachmentService.addAttachment(document, List.of(maliciousAttachment));
Optional<byte[]> extracted = attachmentService.extractAttachments(document);
assertTrue(extracted.isPresent());
try (var zipInputStream =
new ZipInputStream(new ByteArrayInputStream(extracted.get()))) {
ZipEntry entry = zipInputStream.getNextEntry();
assertNotNull(entry);
String sanitizedName = entry.getName();
assertFalse(sanitizedName.contains(".."));
assertFalse(sanitizedName.contains("/"));
assertFalse(sanitizedName.contains("\\"));
byte[] data = zipInputStream.readAllBytes();
assertArrayEquals("danger".getBytes(), data);
assertNull(zipInputStream.getNextEntry());
}
}
}
@Test
void extractAttachments_SkipsAttachmentsExceedingSizeLimit() throws IOException {
attachmentService = new AttachmentService(4, 10);
try (var document = new PDDocument()) {
var oversizedAttachment =
new MockMultipartFile(
"file",
"large.bin",
MediaType.APPLICATION_OCTET_STREAM_VALUE,
"too big".getBytes());
attachmentService.addAttachment(document, List.of(oversizedAttachment));
Optional<byte[]> extracted = attachmentService.extractAttachments(document);
assertTrue(extracted.isEmpty());
}
}
@Test
void extractAttachments_EnforcesTotalSizeLimit() throws IOException {
attachmentService = new AttachmentService(10, 9);
try (var document = new PDDocument()) {
var first =
new MockMultipartFile(
"file", "first.txt", MediaType.TEXT_PLAIN_VALUE, "12345".getBytes());
var second =
new MockMultipartFile(
"file", "second.txt", MediaType.TEXT_PLAIN_VALUE, "67890".getBytes());
attachmentService.addAttachment(document, List.of(first, second));
Optional<byte[]> extracted = attachmentService.extractAttachments(document);
assertTrue(extracted.isPresent());
try (var zipInputStream =
new ZipInputStream(new ByteArrayInputStream(extracted.get()))) {
ZipEntry firstEntry = zipInputStream.getNextEntry();
assertNotNull(firstEntry);
assertEquals("first.txt", firstEntry.getName());
byte[] firstData = zipInputStream.readNBytes(5);
assertArrayEquals("12345".getBytes(), firstData);
assertNull(zipInputStream.getNextEntry());
}
}
}
}
@@ -1,6 +1,5 @@
package stirling.software.SPDF.service;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import java.io.IOException;
@@ -1,7 +1,6 @@
package stirling.software.common.controller;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import java.util.Map;
@@ -2,7 +2,6 @@ package stirling.software.proprietary.security.filter;
import static stirling.software.common.util.RequestUriUtils.isStaticResource;
import static stirling.software.proprietary.security.model.AuthenticationType.*;
import static stirling.software.proprietary.security.model.AuthenticationType.SAML2;
import java.io.IOException;
import java.sql.SQLException;
@@ -1,8 +1,6 @@
package stirling.software.proprietary.security.service;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import java.sql.SQLException;
+3 -3
View File
@@ -6,7 +6,7 @@ plugins {
id "org.springdoc.openapi-gradle-plugin" version "1.9.0"
id "io.swagger.swaggerhub" version "1.3.2"
id "edu.sc.seis.launch4j" version "4.0.0"
id "com.diffplug.spotless" version "7.2.1"
id "com.diffplug.spotless" version "8.0.0"
id "com.github.jk1.dependency-license-report" version "2.9"
//id "nebula.lint" version "19.0.3"
id "org.panteleyev.jpackageplugin" version "1.7.5"
@@ -28,7 +28,7 @@ ext {
bouncycastleVersion = "1.82"
springSecuritySamlVersion = "6.5.5"
openSamlVersion = "4.3.2"
commonmarkVersion = "0.26.0"
commonmarkVersion = "0.27.0"
googleJavaFormatVersion = "1.28.0"
junitPlatformVersion = "1.12.2"
tempJrePath = null
@@ -65,7 +65,7 @@ repositories {
allprojects {
group = 'stirling.software'
version = '1.4.0'
version = '1.5.0'
configurations.configureEach {
exclude group: 'commons-logging', module: 'commons-logging'
+5
View File
@@ -29,6 +29,11 @@ if /I not "%confirm%"=="Y" (
echo Starting generation...
echo Generating .github\scripts\requirements_dev.txt
pip-compile --allow-unsafe --generate-hashes --upgrade --strip-extras ^
--output-file=".github\scripts\requirements_dev.txt" ^
".github\scripts\requirements_dev.in"
echo Generating .github\scripts\requirements_pre_commit.txt
pip-compile --generate-hashes --upgrade --strip-extras ^
--output-file=".github\scripts\requirements_pre_commit.txt" ^
+3 -3
View File
@@ -8,9 +8,9 @@ behave==1.3.3 \
--hash=sha256:2b8f4b64ed2ea756a5a2a73e23defc1c4631e9e724c499e46661778453ebaf51 \
--hash=sha256:89bdb62af8fb9f147ce245736a5de69f025e5edfb66f1fbe16c5007493f842c0
# via -r testing/cucumber/requirements.in
certifi==2025.8.3 \
--hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \
--hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5
certifi==2025.10.5 \
--hash=sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de \
--hash=sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43
# via requests
charset-normalizer==3.4.3 \
--hash=sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91 \