Compare commits

...

10 Commits

Author SHA1 Message Date
Ludy
fa8df329df
Merge branch 'main' into session_2025_03_22 2025-04-16 05:02:27 +00:00
stirlingbot[bot]
6906344178
🌐 Sync Translations + Update README Progress Table (#3359)
### 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-04-15 17:10:44 +01:00
thiagoor-cpu
4bbbbdfafc
Update messages_pt_BR.properties (#3356)
Up-to-date 0.45.5 PT-BR

# Description of Changes

Up-to-date 0.45.5 PT-BR

- 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
2025-04-15 15:17:56 +01:00
Anthony Stirling
def0552f24
fix pipelines via changing to service (#3358)
# 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
2025-04-15 15:15:08 +01:00
stirlingbot[bot]
de9e3edf5c
🌐 Sync Translations + Update README Progress Table (#3352)
### 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-04-15 10:45:00 +01:00
stirlingbot[bot]
1e0e942d93
Update 3rd Party Licenses (#3354)
Auto-generated by StirlingBot

Signed-off-by: stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>
Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com>
2025-04-15 10:44:42 +01:00
Reece Browne
6da84338dc
Bug/498/signature slow firefox mobile (#3322)
# Description of Changes

Please provide a summary of the changes, including:

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

Closes #(498)

---

## 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.

---------

Co-authored-by: Reece Browne <reece@stirling.pdf>
2025-04-15 10:44:21 +01:00
dependabot[bot]
1c27944329
Bump io.micrometer:micrometer-core from 1.14.5 to 1.14.6 (#3353)
Bumps
[io.micrometer:micrometer-core](https://github.com/micrometer-metrics/micrometer)
from 1.14.5 to 1.14.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/micrometer-metrics/micrometer/releases">io.micrometer:micrometer-core's
releases</a>.</em></p>
<blockquote>
<h2>1.14.6</h2>
<h2>🐞 Bug Fixes</h2>
<ul>
<li>Gauge double registration warning for Kafka metrics <a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/5757">#5757</a></li>
<li>Log warning about &quot;function&quot; meter re-registration <a
href="https://redirect.github.com/micrometer-metrics/micrometer/pull/6070">#6070</a></li>
</ul>
<h2>❤️ Contributors</h2>
<p>Thank you to all the contributors who worked on this release:</p>
<p><a href="https://github.com/izeye"><code>@​izeye</code></a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c3f3a80926"><code>c3f3a80</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="fa523b1549"><code>fa523b1</code></a>
Bump io.micrometer:context-propagation from 1.1.2 to 1.1.3 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6115">#6115</a>)</li>
<li><a
href="d5f3d348ef"><code>d5f3d34</code></a>
Bump org.junit:junit-bom from 5.12.1 to 5.12.2 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6111">#6111</a>)</li>
<li><a
href="9ebcde1932"><code>9ebcde1</code></a>
Bump com.netflix.spectator:spectator-reg-atlas from 1.8.9 to 1.8.10 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6112">#6112</a>)</li>
<li><a
href="0ae9b47ecc"><code>0ae9b47</code></a>
Bump org.junit:junit-bom from 5.12.1 to 5.12.2 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6107">#6107</a>)</li>
<li><a
href="d0e70fc69d"><code>d0e70fc</code></a>
Merge branch '1.13.x' into 1.14.x</li>
<li><a
href="3b2270c885"><code>3b2270c</code></a>
Bump uk.org.webcompere:system-stubs-jupiter from 2.1.7 to 2.1.8 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6096">#6096</a>)</li>
<li><a
href="f62f2eeea6"><code>f62f2ee</code></a>
Bump uk.org.webcompere:system-stubs-jupiter from 2.1.7 to 2.1.8 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6094">#6094</a>)</li>
<li><a
href="53b9a3511a"><code>53b9a35</code></a>
Replace deprecated Project.task() (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6092">#6092</a>)</li>
<li><a
href="0ebdd7d5bb"><code>0ebdd7d</code></a>
Bump com.netflix.spectator:spectator-reg-atlas from 1.8.8 to 1.8.9 (<a
href="https://redirect.github.com/micrometer-metrics/micrometer/issues/6091">#6091</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/micrometer-metrics/micrometer/compare/v1.14.5...v1.14.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=io.micrometer:micrometer-core&package-manager=gradle&previous-version=1.14.5&new-version=1.14.6)](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-04-15 10:34:29 +01:00
ConnorYoh
5a0567cf6a
Error reductions found via analytics (#3351)
# 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
2025-04-14 23:33:40 +01:00
albanobattistella
63a9e40aa9
Update messages_it_IT.properties (#3350)
# 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/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/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/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/DeveloperGuide.md#6-testing)
for more details.
2025-04-14 22:37:51 +01:00
21 changed files with 167 additions and 166 deletions

View File

@ -134,14 +134,14 @@ Stirling-PDF currently supports 39 languages!
| Hungarian (Magyar) (hu_HU) | ![89%](https://geps.dev/progress/89) | | Hungarian (Magyar) (hu_HU) | ![89%](https://geps.dev/progress/89) |
| Indonesian (Bahasa Indonesia) (id_ID) | ![81%](https://geps.dev/progress/81) | | Indonesian (Bahasa Indonesia) (id_ID) | ![81%](https://geps.dev/progress/81) |
| Irish (Gaeilge) (ga_IE) | ![92%](https://geps.dev/progress/92) | | Irish (Gaeilge) (ga_IE) | ![92%](https://geps.dev/progress/92) |
| Italian (Italiano) (it_IT) | ![98%](https://geps.dev/progress/98) | | Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) |
| Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) | | Japanese (日本語) (ja_JP) | ![89%](https://geps.dev/progress/89) |
| Korean (한국어) (ko_KR) | ![92%](https://geps.dev/progress/92) | | Korean (한국어) (ko_KR) | ![92%](https://geps.dev/progress/92) |
| Norwegian (Norsk) (no_NB) | ![86%](https://geps.dev/progress/86) | | Norwegian (Norsk) (no_NB) | ![86%](https://geps.dev/progress/86) |
| Persian (فارسی) (fa_IR) | ![88%](https://geps.dev/progress/88) | | Persian (فارسی) (fa_IR) | ![88%](https://geps.dev/progress/88) |
| Polish (Polski) (pl_PL) | ![96%](https://geps.dev/progress/96) | | Polish (Polski) (pl_PL) | ![96%](https://geps.dev/progress/96) |
| Portuguese (Português) (pt_PT) | ![91%](https://geps.dev/progress/91) | | Portuguese (Português) (pt_PT) | ![91%](https://geps.dev/progress/91) |
| Portuguese Brazilian (Português) (pt_BR) | ![94%](https://geps.dev/progress/94) | | Portuguese Brazilian (Português) (pt_BR) | ![98%](https://geps.dev/progress/98) |
| Romanian (Română) (ro_RO) | ![75%](https://geps.dev/progress/75) | | Romanian (Română) (ro_RO) | ![75%](https://geps.dev/progress/75) |
| Russian (Русский) (ru_RU) | ![94%](https://geps.dev/progress/94) | | Russian (Русский) (ru_RU) | ![94%](https://geps.dev/progress/94) |
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![60%](https://geps.dev/progress/60) | | Serbian Latin alphabet (Srpski) (sr_LATN_RS) | ![60%](https://geps.dev/progress/60) |

View File

@ -29,7 +29,7 @@ ext {
} }
group = "stirling.software" group = "stirling.software"
version = "0.45.5" version = "0.45.6"
java { java {
// 17 is lowest but we support and recommend 21 // 17 is lowest but we support and recommend 21
@ -518,7 +518,7 @@ dependencies {
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion" implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion" implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
implementation "io.micrometer:micrometer-core:1.14.5" implementation "io.micrometer:micrometer-core:1.14.6"
implementation group: "com.google.zxing", name: "core", version: "3.5.3" implementation group: "com.google.zxing", name: "core", version: "3.5.3"
// https://mvnrepository.com/artifact/org.commonmark/commonmark // https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark:0.24.0" implementation "org.commonmark:commonmark:0.24.0"

View File

@ -109,33 +109,6 @@ public class AppConfig {
return (rateLimit != null) ? Boolean.valueOf(rateLimit) : false; return (rateLimit != null) ? Boolean.valueOf(rateLimit) : false;
} }
@Bean(name = "uploadLimit")
public long uploadLimit() {
String maxUploadSize =
applicationProperties.getSystem().getFileUploadLimit() != null
? applicationProperties.getSystem().getFileUploadLimit()
: "";
if (maxUploadSize.isEmpty()) {
return 0;
} else if (!new Regex("^[1-9][0-9]{0,2}[KMGkmg][Bb]$").matches(maxUploadSize)) {
log.error(
"Invalid maxUploadSize format. Expected format: [1-9][0-9]{0,2}[KMGkmg][Bb], but got: {}",
maxUploadSize);
return 0;
} else {
String unit = maxUploadSize.replaceAll("[1-9][0-9]{0,2}", "").toUpperCase();
String number = maxUploadSize.replaceAll("[KMGkmg][Bb]", "");
long size = Long.parseLong(number);
return switch (unit) {
case "KB" -> size * 1024;
case "MB" -> size * 1024 * 1024;
case "GB" -> size * 1024 * 1024 * 1024;
default -> 0;
};
}
}
@Bean(name = "RunningInDocker") @Bean(name = "RunningInDocker")
public boolean runningInDocker() { public boolean runningInDocker() {
return Files.exists(Paths.get("/.dockerenv")); return Files.exists(Paths.get("/.dockerenv"));

View File

@ -1,30 +0,0 @@
package stirling.software.SPDF.controller.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
@Component
@ControllerAdvice
public class GlobalUploadLimitWebController {
@Autowired() private long uploadLimit;
@ModelAttribute("uploadLimit")
public long populateUploadLimit() {
return uploadLimit;
}
@ModelAttribute("uploadLimitReadable")
public String populateReadableLimit() {
return humanReadableByteCount(uploadLimit);
}
private String humanReadableByteCount(long bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String pre = "KMGTPE".charAt(exp - 1) + "B";
return String.format("%.1f %s", bytes / Math.pow(1024, exp), pre);
}
}

View File

@ -0,0 +1,55 @@
package stirling.software.SPDF.controller.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import java.util.regex.Pattern;
@Service
@Slf4j
public class UploadLimitService {
@Autowired
private ApplicationProperties applicationProperties;
public long getUploadLimit() {
String maxUploadSize =
applicationProperties.getSystem().getFileUploadLimit() != null
? applicationProperties.getSystem().getFileUploadLimit()
: "";
if (maxUploadSize.isEmpty()) {
return 0;
} else if (!Pattern.compile("^[1-9][0-9]{0,2}[KMGkmg][Bb]$").matcher(maxUploadSize).matches()) {
log.error(
"Invalid maxUploadSize format. Expected format: [1-9][0-9]{0,2}[KMGkmg][Bb], but got: {}",
maxUploadSize);
return 0;
} else {
String unit = maxUploadSize.replaceAll("[1-9][0-9]{0,2}", "").toUpperCase();
String number = maxUploadSize.replaceAll("[KMGkmg][Bb]", "");
long size = Long.parseLong(number);
return switch (unit) {
case "KB" -> size * 1024;
case "MB" -> size * 1024 * 1024;
case "GB" -> size * 1024 * 1024 * 1024;
default -> 0;
};
}
}
//TODO: why do this server side not client?
public String getReadableUploadLimit() {
return humanReadableByteCount(getUploadLimit());
}
private String humanReadableByteCount(long bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String pre = "KMGTPE".charAt(exp - 1) + "B";
return String.format("%.1f %s", bytes / Math.pow(1024, exp), pre);
}
}

View File

@ -10,9 +10,9 @@ multiPdfPrompt=Scegli 2 o più PDF
multiPdfDropPrompt=Scegli (o trascina e rilascia) uno o più PDF multiPdfDropPrompt=Scegli (o trascina e rilascia) uno o più PDF
imgPrompt=Scegli immagine/i imgPrompt=Scegli immagine/i
genericSubmit=Invia genericSubmit=Invia
uploadLimit=Maximum file size: uploadLimit=Dimensione massima del file:
uploadLimitExceededSingular=is too large. Maximum allowed size is uploadLimitExceededSingular=è troppo grande. La dimensione massima consentita è
uploadLimitExceededPlural=are too large. Maximum allowed size is uploadLimitExceededPlural=sono troppo grandi. La dimensione massima consentita è
processTimeWarning=Nota: Questo processo potrebbe richiedere fino a un minuto in base alla dimensione dei file processTimeWarning=Nota: Questo processo potrebbe richiedere fino a un minuto in base alla dimensione dei file
pageOrderPrompt=Ordine delle pagine (inserisci una lista di numeri separati da virgola): pageOrderPrompt=Ordine delle pagine (inserisci una lista di numeri separati da virgola):
pageSelectionPrompt=Selezione pagina personalizzata (inserisci un elenco separato da virgole di numeri di pagina 1,5,6 o funzioni come 2n+1) : pageSelectionPrompt=Selezione pagina personalizzata (inserisci un elenco separato da virgole di numeri di pagina 1,5,6 o funzioni come 2n+1) :
@ -93,7 +93,7 @@ legal.terms=Termini e Condizioni
legal.accessibility=Accessibilità legal.accessibility=Accessibilità
legal.cookie=Informativa sui cookie legal.cookie=Informativa sui cookie
legal.impressum=Informazioni legali legal.impressum=Informazioni legali
legal.showCookieBanner=Cookie Preferences legal.showCookieBanner=Preferenze sui cookie
############### ###############
# Pipeline # # Pipeline #

View File

@ -10,9 +10,9 @@ multiPdfPrompt=Selecione os PDFs (2+)
multiPdfDropPrompt=Selecione (ou arraste e solte) todos os PDFs desejados: multiPdfDropPrompt=Selecione (ou arraste e solte) todos os PDFs desejados:
imgPrompt=Selecione a(s) Imagem(ns) imgPrompt=Selecione a(s) Imagem(ns)
genericSubmit=Enviar genericSubmit=Enviar
uploadLimit=Maximum file size: uploadLimit=Tamanho máximo do arquivo:
uploadLimitExceededSingular=is too large. Maximum allowed size is uploadLimitExceededSingular=está acima do limite. Tamanho máximo permitido é
uploadLimitExceededPlural=are too large. Maximum allowed size is uploadLimitExceededPlural=estão acima do limite. Tamanho máximo permitido é
processTimeWarning=Aviso: Este processo pode levar até um minuto, dependendo do tamanho do arquivo processTimeWarning=Aviso: Este processo pode levar até um minuto, dependendo do tamanho do arquivo
pageOrderPrompt=Ordem de Página Personalizada (Digite uma lista de números de páginas, separadas por vírgula ou funções como 2n+1): pageOrderPrompt=Ordem de Página Personalizada (Digite uma lista de números de páginas, separadas por vírgula ou funções como 2n+1):
pageSelectionPrompt=Seleção de Página Personalizada (Digite uma lista de números de páginas, separadas por vírgula como 1,5,6 ou funções como 2n+1): pageSelectionPrompt=Seleção de Página Personalizada (Digite uma lista de números de páginas, separadas por vírgula como 1,5,6 ou funções como 2n+1):
@ -86,14 +86,14 @@ loading=Carregando...
addToDoc=Adicionar ao Documento addToDoc=Adicionar ao Documento
reset=Reiniciar reset=Reiniciar
apply=Aplicar apply=Aplicar
noFileSelected=No file selected. Please upload one. noFileSelected=Nenhum arquivo selecionado. Por favo, envie um arquivo.
legal.privacy=Política de Privacidade legal.privacy=Política de Privacidade
legal.terms=Termos e Condições legal.terms=Termos e Condições
legal.accessibility=Acessibilidade legal.accessibility=Acessibilidade
legal.cookie=Política de Cookies legal.cookie=Política de Cookies
legal.impressum=Informações legais legal.impressum=Informações legais
legal.showCookieBanner=Cookie Preferences legal.showCookieBanner=Preferências de Cookies
############### ###############
# Pipeline # # Pipeline #
@ -237,31 +237,31 @@ adminUserSettings.activeUsers=Usuários Ativos:
adminUserSettings.disabledUsers=Usuários Desabilitados: adminUserSettings.disabledUsers=Usuários Desabilitados:
adminUserSettings.totalUsers=Total de Usuários: adminUserSettings.totalUsers=Total de Usuários:
adminUserSettings.lastRequest=Última solicitação adminUserSettings.lastRequest=Última solicitação
adminUserSettings.usage=View Usage adminUserSettings.usage=Ver Utilização
endpointStatistics.title=Endpoint Statistics endpointStatistics.title=Estatísticas de Endpoints
endpointStatistics.header=Endpoint Statistics endpointStatistics.header=Estatísticas de Endpoints
endpointStatistics.top10=Top 10 endpointStatistics.top10=Top 10
endpointStatistics.top20=Top 20 endpointStatistics.top20=Top 20
endpointStatistics.all=All endpointStatistics.all=Todos
endpointStatistics.refresh=Refresh endpointStatistics.refresh=Atualizar
endpointStatistics.includeHomepage=Include Homepage ('/') endpointStatistics.includeHomepage=Incluir Página Inicial ('/')
endpointStatistics.includeLoginPage=Include Login Page ('/login') endpointStatistics.includeLoginPage=Incluir Página de Login ('/login')
endpointStatistics.totalEndpoints=Total Endpoints endpointStatistics.totalEndpoints=Total de Endpoints
endpointStatistics.totalVisits=Total Visits endpointStatistics.totalVisits=Total de Visitas
endpointStatistics.showing=Showing endpointStatistics.showing=Mostrando
endpointStatistics.selectedVisits=Selected Visits endpointStatistics.selectedVisits=Visitas Selecionadas
endpointStatistics.endpoint=Endpoint endpointStatistics.endpoint=Endpoint
endpointStatistics.visits=Visits endpointStatistics.visits=Visitas
endpointStatistics.percentage=Percentage endpointStatistics.percentage=Percentagem
endpointStatistics.loading=Loading... endpointStatistics.loading=Carregando...
endpointStatistics.failedToLoad=Failed to load endpoint data. Please try refreshing. endpointStatistics.failedToLoad=Falha ao carregar dados do Endpoint. Por favor, tente atualizar.
endpointStatistics.home=Home endpointStatistics.home=Home
endpointStatistics.login=Login endpointStatistics.login=Login
endpointStatistics.top=Top endpointStatistics.top=Top
endpointStatistics.numberOfVisits=Number of Visits endpointStatistics.numberOfVisits=Número de Visitas
endpointStatistics.visitsTooltip=Visits: {0} ({1}% of total) endpointStatistics.visitsTooltip=Visitas: {0} ({1}% do total)
endpointStatistics.retry=Retry endpointStatistics.retry=Tentar novamente
database.title=Importar/Exportar banco de dados database.title=Importar/Exportar banco de dados
database.header=Importar/Exportar banco de dados database.header=Importar/Exportar banco de dados
@ -739,10 +739,10 @@ sanitizePDF.title=Higienizar
sanitizePDF.header=Higienizar sanitizePDF.header=Higienizar
sanitizePDF.selectText.1=Remover scripts de JavaScript. sanitizePDF.selectText.1=Remover scripts de JavaScript.
sanitizePDF.selectText.2=Remover arquivos embutidos. sanitizePDF.selectText.2=Remover arquivos embutidos.
sanitizePDF.selectText.3=Remove XMP metadata sanitizePDF.selectText.3=Remover metadados XMP.
sanitizePDF.selectText.4=Remover links. sanitizePDF.selectText.4=Remover links.
sanitizePDF.selectText.5=Remover fontes. sanitizePDF.selectText.5=Remover fontes.
sanitizePDF.selectText.6=Remove Document Info Metadata sanitizePDF.selectText.6=Remover metadados de informações do documento.
sanitizePDF.submit=Higienizar PDF sanitizePDF.submit=Higienizar PDF
@ -1408,25 +1408,25 @@ validateSignature.cert.bits=bits
#################### ####################
# Cookie banner # # Cookie banner #
#################### ####################
cookieBanner.popUp.title=How we use Cookies cookieBanner.popUp.title=Como nós utilizamos Cookies:
cookieBanner.popUp.description.1=We use cookies and other technologies to make Stirling PDF work better for you—helping us improve our tools and keep building features you'll love. cookieBanner.popUp.description.1=Nós utilizamos cookies e outras tecnologias para melhorar o Stirling PDF, ajude-nos para que possamos desenvolver novas funcionalidades que você irá amar.
cookieBanner.popUp.description.2=If youd rather not, clicking 'No Thanks' will only enable the essential cookies needed to keep things running smoothly. cookieBanner.popUp.description.2=Se você não tiver interesse, clicando em "Não, Obrigado" será habilitado apenas cookies essenciais, para o site funcionar sem problemas.
cookieBanner.popUp.acceptAllBtn=Okay cookieBanner.popUp.acceptAllBtn=Aceito
cookieBanner.popUp.acceptNecessaryBtn=No Thanks cookieBanner.popUp.acceptNecessaryBtn=Não, Obrigado
cookieBanner.popUp.showPreferencesBtn=Manage preferences cookieBanner.popUp.showPreferencesBtn=Gerenciar Preferências
cookieBanner.preferencesModal.title=Consent Preferences Center cookieBanner.preferencesModal.title=Central de Preferências de Consentimento
cookieBanner.preferencesModal.acceptAllBtn=Accept all cookieBanner.preferencesModal.acceptAllBtn=Aceitar tudo
cookieBanner.preferencesModal.acceptNecessaryBtn=Reject all cookieBanner.preferencesModal.acceptNecessaryBtn=Rejeitar tudo
cookieBanner.preferencesModal.savePreferencesBtn=Save preferences cookieBanner.preferencesModal.savePreferencesBtn=Salvar preferências
cookieBanner.preferencesModal.closeIconLabel=Close modal cookieBanner.preferencesModal.closeIconLabel=Fechar janela
cookieBanner.preferencesModal.serviceCounterLabel=Service|Services cookieBanner.preferencesModal.serviceCounterLabel=Serviço|Serviços
cookieBanner.preferencesModal.subtitle=Cookie Usage cookieBanner.preferencesModal.subtitle=Uso de Cookies
cookieBanner.preferencesModal.description.1=Stirling PDF uses cookies and similar technologies to enhance your experience and understand how our tools are used. This helps us improve performance, develop the features you care about, and provide ongoing support to our users. cookieBanner.preferencesModal.description.1=Stirling PDF utiliza cookies e tecnologias semelhantes para aprimorar sua experiência e entender como nossas ferramentas são utilizadas. Isso nos ajuda a melhorar o desempenho, desenvolver os recursos de seu interesse e fornecer suporte contínuo aos nossos usuários.
cookieBanner.preferencesModal.description.2=Stirling PDF cannot—and will never—track or access the content of the documents you use. cookieBanner.preferencesModal.description.2=O Stirling PDF não pode e nunca irá rastrear ou acessar o conteúdo dos documentos que você manipula.
cookieBanner.preferencesModal.description.3=Your privacy and trust are at the core of what we do. cookieBanner.preferencesModal.description.3=Sua privacidade e confiança são prioridades para nós.
cookieBanner.preferencesModal.necessary.title.1=Strictly Necessary Cookies cookieBanner.preferencesModal.necessary.title.1=Cookies Estritamente Necessários
cookieBanner.preferencesModal.necessary.title.2=Always Enabled cookieBanner.preferencesModal.necessary.title.2=Sempre Ativado
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.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=Analytics cookieBanner.preferencesModal.analytics.title=Cookies Analíticos
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.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.

View File

@ -553,7 +553,7 @@
{ {
"moduleName": "io.micrometer:micrometer-core", "moduleName": "io.micrometer:micrometer-core",
"moduleUrl": "https://github.com/micrometer-metrics/micrometer", "moduleUrl": "https://github.com/micrometer-metrics/micrometer",
"moduleVersion": "1.14.5", "moduleVersion": "1.14.6",
"moduleLicense": "The Apache Software License, Version 2.0", "moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt" "moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}, },

View File

@ -132,7 +132,9 @@
} }
} catch (error) { } catch (error) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
showGameBtn.style.display = 'none'; if(showGameBtn){
showGameBtn.style.display = 'none';
}
submitButton.textContent = originalButtonText; submitButton.textContent = originalButtonText;
submitButton.disabled = false; submitButton.disabled = false;
handleDownloadError(error); handleDownloadError(error);

View File

@ -170,7 +170,7 @@ function setupFileInput(chooser) {
inputContainer.querySelector('#fileInputText').innerHTML = window.fileInput.loading; inputContainer.querySelector('#fileInputText').innerHTML = window.fileInput.loading;
async function checkZipFile() { async function checkZipFile() {
const hasZipFiles = allFiles.some(file => zipTypes.includes(file.type)); const hasZipFiles = allFiles.some(file => file.type && zipTypes.includes(file.type));
// Only change to extractPDF message if we actually have zip files // Only change to extractPDF message if we actually have zip files
if (hasZipFiles) { if (hasZipFiles) {

View File

@ -255,5 +255,12 @@ document.addEventListener('DOMContentLoaded', function () {
}); });
}, 500); }, 500);
Array.from(document.querySelectorAll('.feature-group-header')).forEach((header) => {
const parent = header.parentNode;
header.onclick = () => {
expandCollapseToggle(parent);
};
});
showFavoritesOnly(); showFavoritesOnly();
}); });

View File

@ -241,10 +241,5 @@ document.addEventListener('DOMContentLoaded', async function () {
console.error('Material Symbols Rounded font failed to load.'); console.error('Material Symbols Rounded font failed to load.');
}); });
Array.from(document.querySelectorAll('.feature-group-header')).forEach((header) => {
const parent = header.parentNode;
header.onclick = () => {
expandCollapseToggle(parent);
};
});
}); });

View File

@ -57,11 +57,15 @@ function initLanguageSettings() {
function sortLanguageDropdown() { function sortLanguageDropdown() {
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
const dropdownMenu = document.querySelector('.dropdown-menu .dropdown-item.lang_dropdown-item').parentElement; const dropdownMenu = document.getElementById('languageSelection');
if (dropdownMenu) { if (dropdownMenu) {
const items = Array.from(dropdownMenu.children).filter((child) => child.matches('a')); const items = Array.from(dropdownMenu.children).filter((child) => child.querySelector('a'));
items items
.sort((a, b) => a.dataset.bsLanguageCode.localeCompare(b.dataset.bsLanguageCode)) .sort((wrapperA, wrapperB) => {
const a = wrapperA.querySelector('a');
const b = wrapperB.querySelector('a');
return a.dataset.bsLanguageCode.localeCompare(b.dataset.bsLanguageCode);
})
.forEach((node) => dropdownMenu.appendChild(node)); .forEach((node) => dropdownMenu.appendChild(node));
} }
}); });

View File

@ -21,12 +21,10 @@ export class DeletePageCommand extends Command {
this.pagesContainer.removeChild(this.element); this.pagesContainer.removeChild(this.element);
if (this.pagesContainer.childElementCount === 0) { if (this.pagesContainer.childElementCount === 0) {
const filenameInput = document.getElementById("filename-input"); const filenameInput = document.getElementById("filename-input");
const filenameParagraph = document.getElementById("filename");
const downloadBtn = document.getElementById("export-button"); const downloadBtn = document.getElementById("export-button");
filenameInput.disabled = true; filenameInput.disabled = true;
filenameInput.value = ""; filenameInput.value = "";
filenameParagraph.innerText = "";
downloadBtn.disabled = true; downloadBtn.disabled = true;
} }
@ -43,13 +41,10 @@ export class DeletePageCommand extends Command {
} }
const filenameInput = document.getElementById("filename-input"); const filenameInput = document.getElementById("filename-input");
const filenameParagraph = document.getElementById("filename");
const downloadBtn = document.getElementById("export-button"); const downloadBtn = document.getElementById("export-button");
filenameInput.disabled = false; filenameInput.disabled = false;
filenameInput.value = this.filenameInputValue; filenameInput.value = this.filenameInputValue;
if (this.filenameParagraph)
filenameParagraph.innerText = this.filenameParagraphText;
downloadBtn.disabled = false; downloadBtn.disabled = false;
} }
@ -63,12 +58,10 @@ export class DeletePageCommand extends Command {
this.pagesContainer.removeChild(this.element); this.pagesContainer.removeChild(this.element);
if (this.pagesContainer.childElementCount === 0) { if (this.pagesContainer.childElementCount === 0) {
const filenameInput = document.getElementById("filename-input"); const filenameInput = document.getElementById("filename-input");
const filenameParagraph = document.getElementById("filename");
const downloadBtn = document.getElementById("export-button"); const downloadBtn = document.getElementById("export-button");
filenameInput.disabled = true; filenameInput.disabled = true;
filenameInput.value = ""; filenameInput.value = "";
filenameParagraph.innerText = "";
downloadBtn.disabled = true; downloadBtn.disabled = true;
} }

View File

@ -112,10 +112,10 @@ function setAsDefault(value) {
function adjustVisibleElements() { function adjustVisibleElements() {
const container = document.querySelector('.recent-features'); const container = document.querySelector('.recent-features');
if(!container) return;
const subElements = Array.from(container.children); const subElements = Array.from(container.children);
let totalWidth = 0; let totalWidth = 0;
const containerWidth = container.offsetWidth;
subElements.forEach((element) => { subElements.forEach((element) => {
totalWidth += 12 * parseFloat(getComputedStyle(document.documentElement).fontSize); totalWidth += 12 * parseFloat(getComputedStyle(document.documentElement).fontSize);

View File

@ -26,7 +26,6 @@ window.addEventListener("keydown", (event) => {
function undoDraw() { function undoDraw() {
const data = signaturePad.toData(); const data = signaturePad.toData();
if (data && data.length > 0) { if (data && data.length > 0) {
const removed = data.pop(); const removed = data.pop();
undoData.push(removed); undoData.push(removed);
@ -35,7 +34,6 @@ function undoDraw() {
} }
function redoDraw() { function redoDraw() {
if (undoData.length > 0) { if (undoData.length > 0) {
const data = signaturePad.toData(); const data = signaturePad.toData();
data.push(undoData.pop()); data.push(undoData.pop());
@ -52,24 +50,18 @@ function addDraggableFromPad() {
} }
function getCroppedCanvasDataUrl(canvas) { function getCroppedCanvasDataUrl(canvas) {
let originalCtx = canvas.getContext('2d'); let originalCtx = canvas.getContext('2d', { willReadFrequently: true });
let originalWidth = canvas.width; let originalWidth = canvas.width;
let originalHeight = canvas.height; let originalHeight = canvas.height;
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight); let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
let minX = originalWidth + 1, let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1;
maxX = -1,
minY = originalHeight + 1,
maxY = -1,
x = 0,
y = 0,
currentPixelColorValueIndex;
for (y = 0; y < originalHeight; y++) { for (let y = 0; y < originalHeight; y++) {
for (x = 0; x < originalWidth; x++) { for (let x = 0; x < originalWidth; x++) {
currentPixelColorValueIndex = (y * originalWidth + x) * 4; let idx = (y * originalWidth + x) * 4;
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3]; let alpha = imageData.data[idx + 3];
if (currentPixelAlphaValue > 0) { if (alpha > 0) {
if (minX > x) minX = x; if (minX > x) minX = x;
if (maxX < x) maxX = x; if (maxX < x) maxX = x;
if (minY > y) minY = y; if (minY > y) minY = y;
@ -81,14 +73,14 @@ function getCroppedCanvasDataUrl(canvas) {
let croppedWidth = maxX - minX; let croppedWidth = maxX - minX;
let croppedHeight = maxY - minY; let croppedHeight = maxY - minY;
if (croppedWidth < 0 || croppedHeight < 0) return null; if (croppedWidth < 0 || croppedHeight < 0) return null;
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight); let cutImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
let croppedCanvas = document.createElement('canvas'), let croppedCanvas = document.createElement('canvas');
croppedCtx = croppedCanvas.getContext('2d'); let croppedCtx = croppedCanvas.getContext('2d');
croppedCanvas.width = croppedWidth; croppedCanvas.width = croppedWidth;
croppedCanvas.height = croppedHeight; croppedCanvas.height = croppedHeight;
croppedCtx.putImageData(cuttedImageData, 0, 0); croppedCtx.putImageData(cutImageData, 0, 0);
return croppedCanvas.toDataURL(); return croppedCanvas.toDataURL();
} }
@ -114,10 +106,20 @@ function resizeCanvas() {
signaturePad.clear(); signaturePad.clear();
} }
new IntersectionObserver((entries, observer) => { const debounce = (fn, delay = 100) => {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
const debouncedResize = debounce(resizeCanvas, 200);
new IntersectionObserver((entries) => {
if (entries.some((entry) => entry.intersectionRatio > 0)) { if (entries.some((entry) => entry.intersectionRatio > 0)) {
resizeCanvas(); debouncedResize();
} }
}).observe(signaturePadCanvas); }).observe(signaturePadCanvas);
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas); new ResizeObserver(debouncedResize).observe(signaturePadCanvas);

View File

@ -240,8 +240,8 @@
window.stirlingPDF.sessionExpired = /*[[#{session.expired}]]*/ ''; window.stirlingPDF.sessionExpired = /*[[#{session.expired}]]*/ '';
window.stirlingPDF.refreshPage = /*[[#{session.refreshPage}]]*/ 'Refresh Page'; window.stirlingPDF.refreshPage = /*[[#{session.refreshPage}]]*/ 'Refresh Page';
window.stirlingPDF.error = /*[[#{error}]]*/ "Error"; window.stirlingPDF.error = /*[[#{error}]]*/ "Error";
window.stirlingPDF.uploadLimit = /*[[${uploadLimit}]]*/ 0; window.stirlingPDF.uploadLimitReadable = /*[[${@uploadLimitService.getReadableUploadLimit()}]]*/ 'Unlimited';
window.stirlingPDF.uploadLimitReadable = /*[[${uploadLimitReadable}]]*/ 'Unlimited'; window.stirlingPDF.uploadLimit = /*[[${@uploadLimitService.getUploadLimit()}]]*/ 0;
window.stirlingPDF.uploadLimitExceededSingular = /*[[#{uploadLimitExceededSingular}]]*/ 'is too large. Maximum allowed size is'; window.stirlingPDF.uploadLimitExceededSingular = /*[[#{uploadLimitExceededSingular}]]*/ 'is too large. Maximum allowed size is';
window.stirlingPDF.uploadLimitExceededPlural = /*[[#{uploadLimitExceededPlural}]]*/ 'are too large. Maximum allowed size is'; window.stirlingPDF.uploadLimitExceededPlural = /*[[#{uploadLimitExceededPlural}]]*/ 'are too large. Maximum allowed size is';
})(); })();
@ -292,10 +292,10 @@
</div> </div>
</div> </div>
<div class="selected-files flex-wrap"></div> <div class="selected-files flex-wrap"></div>
<div class="text-muted small mt-0 text-end w-100" th:if="${uploadLimit != 0}"> <div class="text-muted small mt-0 text-end w-100" th:if="${@uploadLimitService.getUploadLimit() != 0}">
<span th:text="#{uploadLimit}">Maximum file size: </span> <span th:text="#{uploadLimit}">Maximum file size: </span>
<span th:text="${uploadLimitReadable}"></span> <span th:text="${@uploadLimitService.getReadableUploadLimit()}"></span>
</div> </div>
</div> </div>
<div class="progressBarContainer" style="display: none; position: relative;"> <div class="progressBarContainer" style="display: none; position: relative;">
<div class="progress" style="height: 1rem;"> <div class="progress" style="height: 1rem;">

View File

@ -143,7 +143,7 @@
</a> </a>
<div class="dropdown-menu dropdown-menu-tp" aria-labelledby="languageDropdown"> <div class="dropdown-menu dropdown-menu-tp" aria-labelledby="languageDropdown">
<div class="dropdown-menu-wrapper px-xl-2 px-2"> <div class="dropdown-menu-wrapper px-xl-2 px-2">
<div class="scrollable-y lang_dropdown-mw scalable-languages-container"> <div id="languageSelection" class="scrollable-y lang_dropdown-mw scalable-languages-container">
<th:block th:insert="~{fragments/languages :: langs}"></th:block> <th:block th:insert="~{fragments/languages :: langs}"></th:block>
</div> </div>
</div> </div>

View File

@ -143,7 +143,7 @@
</button> </button>
<div class="dropdown-menu" aria-labelledby="languageDropdown"> <div class="dropdown-menu" aria-labelledby="languageDropdown">
<!-- Here's where the fragment will be included --> <!-- Here's where the fragment will be included -->
<div class="scrollable-y"> <div id="languageSelection" class="scrollable-y" >
<th:block th:replace="~{fragments/languages :: langs}"></th:block> <th:block th:replace="~{fragments/languages :: langs}"></th:block>
</div> </div>
</div> </div>

View File

@ -27,7 +27,7 @@
</div> </div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script> <script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<script type="module" th:src="@{'/js/pages/add-image.js'}"></script> <script type="module" th:src="@{'/js/pages/add-image.js'}"></script>
<div class="tab-group show-on-file-selected"> <div class="show-on-file-selected">
<div <div
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"> th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
</div> </div>

View File

@ -43,13 +43,13 @@
</div> </div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script> <script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<div class="tab-group show-on-file-selected"> <div class="tab-group show-on-file-selected">
<div class="tab-container" th:title="#{sign.upload}" th:data-title="#{sign.upload}"> <div class="tab-container"th:data-title="#{sign.upload}">
<div <div
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"> th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
</div> </div>
</div> </div>
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}" th:data-title="#{sign.draw}"> <div class="tab-container drawing-pad-container" th:data-title="#{sign.draw}">
<canvas id="drawing-pad-canvas"></canvas> <canvas id="drawing-pad-canvas"></canvas>
<br> <br>
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" <button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
@ -62,7 +62,7 @@
onclick="redoDraw()"></button> onclick="redoDraw()"></button>
</div> </div>
<div class="tab-container" th:title="#{sign.saved}" th:data-title="#{sign.saved}"> <div class="tab-container" th:data-title="#{sign.saved}">
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}"> <div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
<!-- Preview Modal --> <!-- Preview Modal -->
@ -134,7 +134,7 @@
</div> </div>
</div> </div>
<div class="tab-container" th:title="#{sign.text}" th:data-title="#{sign.text}"> <div class="tab-container" th:data-title="#{sign.text}">
<label class="form-check-label" for="sigText" th:text="#{text}"></label> <label class="form-check-label" for="sigText" th:text="#{text}"></label>
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea> <textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
<label th:text="#{font}"></label> <label th:text="#{font}"></label>