mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-09-12 17:52:13 +02:00
Merge branch 'main' into session_2025_03_22
This commit is contained in:
commit
d923e65b94
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@ -24,4 +24,4 @@ jobs:
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: "Dependency Review"
|
||||
uses: actions/dependency-review-action@ce3cf9537a52e8119d91fd484ab5b8a807627bf8 # v4.6.0
|
||||
uses: actions/dependency-review-action@38ecb5b593bf0eb19e335c03f97670f792489a8b # v4.7.0
|
||||
|
@ -541,7 +541,7 @@ This would generate n entries of tr for each person in exampleData
|
||||
|
||||
```html
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" th:href="@{/new-feature}">New Feature</a>
|
||||
<a class="nav-link" th:href="@{'/new-feature'}">New Feature</a>
|
||||
</li>
|
||||
```
|
||||
|
||||
|
@ -112,7 +112,7 @@ Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.sti
|
||||
|
||||
## Supported Languages
|
||||
|
||||
Stirling-PDF currently supports 39 languages!
|
||||
Stirling-PDF currently supports 40 languages!
|
||||
|
||||
| Language | Progress |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
@ -127,7 +127,7 @@ Stirling-PDF currently supports 39 languages!
|
||||
| Dutch (Nederlands) (nl_NL) |  |
|
||||
| English (English) (en_GB) |  |
|
||||
| English (US) (en_US) |  |
|
||||
| French (Français) (fr_FR) |  |
|
||||
| French (Français) (fr_FR) |  |
|
||||
| German (Deutsch) (de_DE) |  |
|
||||
| Greek (Ελληνικά) (el_GR) |  |
|
||||
| Hindi (हिंदी) (hi_IN) |  |
|
||||
@ -156,12 +156,12 @@ Stirling-PDF currently supports 39 languages!
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||
|
||||
| Malayalam (മലയാളം) (ml_ML) |  |
|
||||
|
||||
## Stirling PDF Enterprise
|
||||
|
||||
Stirling PDF offers an Enterprise edition of its software. This is the same great software but with added features, support and comforts.
|
||||
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Enterprise%20Edition)
|
||||
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Pro)
|
||||
|
||||
|
||||
## 🤝 Looking to contribute?
|
||||
|
@ -29,7 +29,7 @@ ext {
|
||||
}
|
||||
|
||||
group = "stirling.software"
|
||||
version = "0.46.0"
|
||||
version = "0.46.1"
|
||||
|
||||
java {
|
||||
// 17 is lowest but we support and recommend 21
|
||||
@ -481,7 +481,7 @@ dependencies {
|
||||
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
||||
|
||||
// Batik
|
||||
implementation "org.apache.xmlgraphics:batik-all:1.18"
|
||||
implementation "org.apache.xmlgraphics:batik-all:1.19"
|
||||
|
||||
// TwelveMonkeys
|
||||
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
|
||||
@ -529,7 +529,7 @@ dependencies {
|
||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||
implementation "io.micrometer:micrometer-core:1.14.6"
|
||||
implementation "io.micrometer:micrometer-core:1.14.7"
|
||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||
implementation "org.commonmark:commonmark:0.24.0"
|
||||
|
@ -34,6 +34,11 @@ public class EEAppConfig {
|
||||
return licenseKeyChecker.getPremiumLicenseEnabledResult() != License.NORMAL;
|
||||
}
|
||||
|
||||
@Bean(name = "license")
|
||||
public String licenseType() {
|
||||
return licenseKeyChecker.getPremiumLicenseEnabledResult().name();
|
||||
}
|
||||
|
||||
@Bean(name = "runningEE")
|
||||
public boolean runningEnterprise() {
|
||||
return licenseKeyChecker.getPremiumLicenseEnabledResult() == License.ENTERPRISE;
|
||||
|
@ -5,6 +5,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -15,6 +16,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
@ -33,6 +35,8 @@ public class AppConfig {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
|
||||
private final Environment env;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
||||
public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) {
|
||||
@ -193,4 +197,37 @@ public class AppConfig {
|
||||
public String uuid() {
|
||||
return applicationProperties.getAutomaticallyGenerated().getUUID();
|
||||
}
|
||||
|
||||
@Bean(name = "disablePixel")
|
||||
public boolean disablePixel() {
|
||||
return Boolean.getBoolean(env.getProperty("DISABLE_PIXEL"));
|
||||
}
|
||||
|
||||
@Bean(name = "machineType")
|
||||
public String determineMachineType() {
|
||||
try {
|
||||
boolean isDocker = runningInDocker();
|
||||
boolean isKubernetes = System.getenv("KUBERNETES_SERVICE_HOST") != null;
|
||||
boolean isBrowserOpen = "true".equalsIgnoreCase(env.getProperty("BROWSER_OPEN"));
|
||||
|
||||
if (isKubernetes) {
|
||||
return "Kubernetes";
|
||||
} else if (isDocker) {
|
||||
return "Docker";
|
||||
} else if (isBrowserOpen) {
|
||||
String os = System.getProperty("os.name").toLowerCase(Locale.ROOT);
|
||||
if (os.contains("win")) {
|
||||
return "Client-windows";
|
||||
} else if (os.contains("mac")) {
|
||||
return "Client-mac";
|
||||
} else {
|
||||
return "Client-unix";
|
||||
}
|
||||
} else {
|
||||
return "Server-jar";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class InitialSetup {
|
||||
// Initialize Terms and Conditions
|
||||
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
|
||||
if (StringUtils.isEmpty(termsUrl)) {
|
||||
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
|
||||
String defaultTermsUrl = "https://www.stirlingpdf.com/terms";
|
||||
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
|
||||
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ public class MetricsConfig {
|
||||
return new MeterFilter() {
|
||||
@Override
|
||||
public MeterFilterReply accept(Meter.Id id) {
|
||||
if (id.getName().equals("http.requests")) {
|
||||
if ("http.requests".equals(id.getName())) {
|
||||
return MeterFilterReply.NEUTRAL;
|
||||
}
|
||||
return MeterFilterReply.DENY;
|
||||
|
@ -5,7 +5,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
|
||||
@ -31,14 +33,25 @@ public class OpenApiConfig {
|
||||
// default version if all else fails
|
||||
version = "1.0.0";
|
||||
}
|
||||
Info info =
|
||||
new Info()
|
||||
.title(DEFAULT_TITLE)
|
||||
.version(version)
|
||||
.license(
|
||||
new License()
|
||||
.name("MIT")
|
||||
.url(
|
||||
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
|
||||
.identifier("MIT"))
|
||||
.termsOfService("https://www.stirlingpdf.com/terms")
|
||||
.contact(
|
||||
new Contact()
|
||||
.name("Stirling Software")
|
||||
.url("https://www.stirlingpdf.com")
|
||||
.email("contact@stirlingpdf.com"))
|
||||
.description(DEFAULT_DESCRIPTION);
|
||||
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
||||
return new OpenAPI()
|
||||
.components(new Components())
|
||||
.info(
|
||||
new Info()
|
||||
.title(DEFAULT_TITLE)
|
||||
.version(version)
|
||||
.description(DEFAULT_DESCRIPTION));
|
||||
return new OpenAPI().components(new Components()).info(info);
|
||||
} else {
|
||||
SecurityScheme apiKeyScheme =
|
||||
new SecurityScheme()
|
||||
@ -47,11 +60,7 @@ public class OpenApiConfig {
|
||||
.name("X-API-KEY");
|
||||
return new OpenAPI()
|
||||
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||
.info(
|
||||
new Info()
|
||||
.title(DEFAULT_TITLE)
|
||||
.version(version)
|
||||
.description(DEFAULT_DESCRIPTION))
|
||||
.info(info)
|
||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||
}
|
||||
}
|
||||
|
@ -180,14 +180,15 @@ public class AnalysisController {
|
||||
|
||||
// Get permissions
|
||||
Map<String, Boolean> permissions = new HashMap<>();
|
||||
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint());
|
||||
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
|
||||
permissions.put("preventPrinting", !document.getCurrentAccessPermission().canPrint());
|
||||
permissions.put(
|
||||
"canExtractContent",
|
||||
document.getCurrentAccessPermission().canExtractContent());
|
||||
"preventModify", !document.getCurrentAccessPermission().canModify());
|
||||
permissions.put(
|
||||
"canModifyAnnotations",
|
||||
document.getCurrentAccessPermission().canModifyAnnotations());
|
||||
"preventExtractContent",
|
||||
!document.getCurrentAccessPermission().canExtractContent());
|
||||
permissions.put(
|
||||
"preventModifyAnnotations",
|
||||
!document.getCurrentAccessPermission().canModifyAnnotations());
|
||||
|
||||
securityInfo.put("permissions", permissions);
|
||||
} else {
|
||||
|
@ -626,25 +626,32 @@ public class CompressController {
|
||||
|
||||
// Scale factors for different optimization levels
|
||||
private double getScaleFactorForLevel(int optimizeLevel) {
|
||||
return switch (optimizeLevel) {
|
||||
case 4 -> 0.9; // 90% - lite compression
|
||||
case 5 -> 0.8; // 80% - lite compression
|
||||
case 6 -> 0.7; // 70% - lite compression
|
||||
case 7 -> 0.6; // 60% - intense compression
|
||||
case 8 -> 0.5; // 50% - intense compression
|
||||
case 9, 10 -> 0.4; // 40% - intense compression
|
||||
default -> 1.0; // No scaling for levels 1-3
|
||||
};
|
||||
return switch (optimizeLevel) {
|
||||
case 3 -> 0.85;
|
||||
case 4 -> 0.75;
|
||||
case 5 -> 0.65;
|
||||
case 6 -> 0.55;
|
||||
case 7 -> 0.45;
|
||||
case 8 -> 0.35;
|
||||
case 9 -> 0.25;
|
||||
case 10 -> 0.15;
|
||||
default -> 1.0;
|
||||
};
|
||||
}
|
||||
|
||||
// JPEG quality for different optimization levels
|
||||
private float getJpegQualityForLevel(int optimizeLevel) {
|
||||
return switch (optimizeLevel) {
|
||||
case 7 -> 0.8f; // 80% quality
|
||||
case 8 -> 0.6f; // 60% quality
|
||||
case 9, 10 -> 0.4f; // 40% quality
|
||||
default -> 0.7f; // 70% quality for levels 1-6
|
||||
};
|
||||
return switch (optimizeLevel) {
|
||||
case 3 -> 0.85f;
|
||||
case 4 -> 0.80f;
|
||||
case 5 -> 0.75f;
|
||||
case 6 -> 0.70f;
|
||||
case 7 -> 0.60f;
|
||||
case 8 -> 0.50f;
|
||||
case 9 -> 0.35f;
|
||||
case 10 -> 0.2f;
|
||||
default -> 0.7f;
|
||||
};
|
||||
}
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/compress-pdf")
|
||||
@ -698,7 +705,7 @@ public class CompressController {
|
||||
|
||||
while (!sizeMet && optimizeLevel <= 9) {
|
||||
// Apply image compression for levels 4-9
|
||||
if ((optimizeLevel >= 4 || Boolean.TRUE.equals(convertToGrayscale))
|
||||
if ((optimizeLevel >= 3 || Boolean.TRUE.equals(convertToGrayscale))
|
||||
&& !imageCompressionApplied) {
|
||||
double scaleFactor = getScaleFactorForLevel(optimizeLevel);
|
||||
float jpegQuality = getJpegQualityForLevel(optimizeLevel);
|
||||
@ -790,10 +797,14 @@ public class CompressController {
|
||||
log.info("Pre-QPDF file size: {}", GeneralUtils.formatBytes(preQpdfSize));
|
||||
|
||||
// Map optimization levels to QPDF compression levels
|
||||
int qpdfCompressionLevel =
|
||||
optimizeLevel <= 3
|
||||
? optimizeLevel * 3 // Level 1->3, 2->6, 3->9
|
||||
: 9; // Max compression for levels 4-9
|
||||
int qpdfCompressionLevel;
|
||||
if (optimizeLevel == 1) {
|
||||
qpdfCompressionLevel = 5;
|
||||
} else if (optimizeLevel == 2) {
|
||||
qpdfCompressionLevel = 9;
|
||||
} else {
|
||||
qpdfCompressionLevel = 9;
|
||||
}
|
||||
|
||||
// Create output file for QPDF
|
||||
Path qpdfOutputFile = Files.createTempFile("qpdf_output_", ".pdf");
|
||||
|
@ -622,8 +622,8 @@ public class GetInfoOnPDF {
|
||||
permissionsNode.put("Document Assembly", getPermissionState(ap.canAssembleDocument()));
|
||||
permissionsNode.put("Extracting Content", getPermissionState(ap.canExtractContent()));
|
||||
permissionsNode.put(
|
||||
"Extracting for accessibility",
|
||||
getPermissionState(ap.canExtractForAccessibility()));
|
||||
"Extracting for accessibility",
|
||||
getPermissionState(ap.canExtractForAccessibility()));
|
||||
permissionsNode.put("Form Filling", getPermissionState(ap.canFillInForm()));
|
||||
permissionsNode.put("Modifying", getPermissionState(ap.canModify()));
|
||||
permissionsNode.put("Modifying annotations", getPermissionState(ap.canModifyAnnotations()));
|
||||
|
@ -63,25 +63,25 @@ public class PasswordController {
|
||||
String ownerPassword = request.getOwnerPassword();
|
||||
String password = request.getPassword();
|
||||
int keyLength = request.getKeyLength();
|
||||
boolean canAssembleDocument = request.isCanAssembleDocument();
|
||||
boolean canExtractContent = request.isCanExtractContent();
|
||||
boolean canExtractForAccessibility = request.isCanExtractForAccessibility();
|
||||
boolean canFillInForm = request.isCanFillInForm();
|
||||
boolean canModify = request.isCanModify();
|
||||
boolean canModifyAnnotations = request.isCanModifyAnnotations();
|
||||
boolean canPrint = request.isCanPrint();
|
||||
boolean canPrintFaithful = request.isCanPrintFaithful();
|
||||
boolean preventAssembly = request.isPreventAssembly();
|
||||
boolean preventExtractContent = request.isPreventExtractContent();
|
||||
boolean preventExtractForAccessibility = request.isPreventExtractForAccessibility();
|
||||
boolean preventFillInForm = request.isPreventFillInForm();
|
||||
boolean preventModify = request.isPreventModify();
|
||||
boolean preventModifyAnnotations = request.isPreventModifyAnnotations();
|
||||
boolean preventPrinting = request.isPreventPrinting();
|
||||
boolean preventPrintingFaithful = request.isPreventPrintingFaithful();
|
||||
|
||||
PDDocument document = pdfDocumentFactory.load(fileInput);
|
||||
AccessPermission ap = new AccessPermission();
|
||||
ap.setCanAssembleDocument(!canAssembleDocument);
|
||||
ap.setCanExtractContent(!canExtractContent);
|
||||
ap.setCanExtractForAccessibility(!canExtractForAccessibility);
|
||||
ap.setCanFillInForm(!canFillInForm);
|
||||
ap.setCanModify(!canModify);
|
||||
ap.setCanModifyAnnotations(!canModifyAnnotations);
|
||||
ap.setCanPrint(!canPrint);
|
||||
ap.setCanPrintFaithful(!canPrintFaithful);
|
||||
ap.setCanAssembleDocument(!preventAssembly);
|
||||
ap.setCanExtractContent(!preventExtractContent);
|
||||
ap.setCanExtractForAccessibility(!preventExtractForAccessibility);
|
||||
ap.setCanFillInForm(!preventFillInForm);
|
||||
ap.setCanModify(!preventModify);
|
||||
ap.setCanModifyAnnotations(!preventModifyAnnotations);
|
||||
ap.setCanPrint(!preventPrinting);
|
||||
ap.setCanPrintFaithful(!preventPrintingFaithful);
|
||||
StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, password, ap);
|
||||
|
||||
if (!"".equals(ownerPassword) || !"".equals(password)) {
|
||||
|
@ -170,16 +170,17 @@ public class RedactController {
|
||||
}
|
||||
|
||||
private Color decodeOrDefault(String hex, Color defaultColor) {
|
||||
Color color = null;
|
||||
try {
|
||||
color = Color.decode(hex);
|
||||
if (hex != null && !hex.startsWith("#")) {
|
||||
hex = "#" + hex;
|
||||
}
|
||||
return Color.decode(hex);
|
||||
} catch (Exception e) {
|
||||
color = defaultColor;
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
private List<Integer> getPageNumbers(ManualRedactPdfRequest request, int pagesCount) {
|
||||
String pageNumbersInput = request.getPageNumbers();
|
||||
String[] parsedPageNumbers =
|
||||
|
@ -29,31 +29,29 @@ public class AddPasswordRequest extends PDFFile {
|
||||
defaultValue = "256")
|
||||
private int keyLength = 256;
|
||||
|
||||
@Schema(description = "Whether the document assembly is allowed", example = "false")
|
||||
private boolean canAssembleDocument;
|
||||
@Schema(description = "Whether document assembly is prevented", example = "false")
|
||||
private boolean preventAssembly;
|
||||
|
||||
@Schema(description = "Whether content extraction is prevented", example = "false")
|
||||
private boolean preventExtractContent;
|
||||
|
||||
@Schema(
|
||||
description = "Whether content extraction for accessibility is allowed",
|
||||
description = "Whether content extraction for accessibility is prevented",
|
||||
example = "false")
|
||||
private boolean canExtractContent;
|
||||
private boolean preventExtractForAccessibility;
|
||||
|
||||
@Schema(
|
||||
description = "Whether content extraction for accessibility is allowed",
|
||||
example = "false")
|
||||
private boolean canExtractForAccessibility;
|
||||
@Schema(description = "Whether form filling is prevented", example = "false")
|
||||
private boolean preventFillInForm;
|
||||
|
||||
@Schema(description = "Whether form filling is allowed", example = "false")
|
||||
private boolean canFillInForm;
|
||||
@Schema(description = "Whether document modification is prevented", example = "false")
|
||||
private boolean preventModify;
|
||||
|
||||
@Schema(description = "Whether the document modification is allowed", example = "false")
|
||||
private boolean canModify;
|
||||
@Schema(description = "Whether modification of annotations is prevented", example = "false")
|
||||
private boolean preventModifyAnnotations;
|
||||
|
||||
@Schema(description = "Whether modification of annotations is allowed", example = "false")
|
||||
private boolean canModifyAnnotations;
|
||||
@Schema(description = "Whether printing of the document is prevented", example = "false")
|
||||
private boolean preventPrinting;
|
||||
|
||||
@Schema(description = "Whether printing of the document is allowed", example = "false")
|
||||
private boolean canPrint;
|
||||
|
||||
@Schema(description = "Whether faithful printing is allowed", example = "false")
|
||||
private boolean canPrintFaithful;
|
||||
@Schema(description = "Whether faithful printing is prevented", example = "false")
|
||||
private boolean preventPrintingFaithful;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class RedactPdfRequest extends PDFFile {
|
||||
@Schema(description = "Whether to use whole word search", defaultValue = "false")
|
||||
private boolean wholeWordSearch;
|
||||
|
||||
@Schema(description = "The color for redaction", defaultValue = "#000000")
|
||||
@Schema(description = "Hexadecimal color code for redaction, e.g. #FF0000 or 000000", defaultValue = "#000000")
|
||||
private String redactColor = "#000000";
|
||||
|
||||
@Schema(description = "Custom padding for redaction", type = "number")
|
||||
|
@ -517,13 +517,13 @@ home.showJS.title=Afficher le JavaScript
|
||||
home.showJS.desc=Recherche et affiche tout JavaScript injecté dans un PDF.
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Censure automatique
|
||||
home.autoRedact.desc=Censurer automatiquement les informations sensibles d'un PDF.
|
||||
autoRedact.tags=caviarder,rédiger,censurer,redact,auto
|
||||
home.autoRedact.title=Caviardage automatique
|
||||
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
||||
autoRedact.tags=caviarder,redact,auto,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
|
||||
|
||||
home.redact.title=Censure manuelle
|
||||
home.redact.desc=Censurer un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual,caviarder,rédiger,censurer
|
||||
home.redact.title=Caviardage manuel
|
||||
home.redact.desc=Caviarder un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
||||
redact.tags=Caviarder,Redact,Masquer,noircir,noir,marqueur,caché,rédiger,censurer
|
||||
|
||||
home.tableExtraxt.title=PDF en CSV
|
||||
home.tableExtraxt.desc=Extrait les tableaux d'un PDF et les transforme en CSV.
|
||||
@ -624,31 +624,31 @@ autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour s
|
||||
autoRedact.submitButton=Caviarder
|
||||
|
||||
#redact
|
||||
redact.title=Rédaction manuelle
|
||||
redact.header=Rédaction manuelle
|
||||
redact.submit=Rédiger
|
||||
redact.textBasedRedaction=Rédaction en fonction de texte
|
||||
redact.pageBasedRedaction=Rédaction en fonction de pages
|
||||
redact.title=Caviardage manuel
|
||||
redact.header=Caviardage manuel
|
||||
redact.submit=Caviarder
|
||||
redact.textBasedRedaction=Caviarder du texte
|
||||
redact.pageBasedRedaction=Caviarder des pages
|
||||
redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle)
|
||||
redact.pageRedactionNumbers.title=Pages
|
||||
redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)
|
||||
redact.redactionColor.title=Couleur
|
||||
redact.export=Exporter
|
||||
redact.upload=Téléverser
|
||||
redact.boxRedaction=Dessiner le rectangle à rédiger
|
||||
redact.boxRedaction=Tracer le rectangle à caviarder
|
||||
redact.zoom=Zoom
|
||||
redact.zoomIn=Zoom avant
|
||||
redact.zoomOut=Zoom arrière
|
||||
redact.nextPage=Page suivante
|
||||
redact.previousPage=Page précédente
|
||||
redact.toggleSidebar=Toggle Sidebar
|
||||
redact.toggleSidebar=Montrer la barre latérale
|
||||
redact.showThumbnails=Afficher les miniatures
|
||||
redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments)
|
||||
redact.showAttatchments=Montrer les éléments attachés
|
||||
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
||||
redact.colourPicker=Sélection de couleur
|
||||
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
||||
redact.applyChanges=Apply Changes
|
||||
redact.applyChanges=Appliquer les changements
|
||||
|
||||
#showJS
|
||||
showJS.title=Afficher le JavaScript
|
||||
|
1439
src/main/resources/messages_ml_ML.properties
Normal file
1439
src/main/resources/messages_ml_ML.properties
Normal file
File diff suppressed because it is too large
Load Diff
@ -77,7 +77,7 @@ premium:
|
||||
appId: ''
|
||||
|
||||
mail:
|
||||
enabled: true # set to 'true' to enable sending emails
|
||||
enabled: false # set to 'true' to enable sending emails
|
||||
host: smtp.example.com # SMTP server hostname
|
||||
port: 587 # SMTP server port
|
||||
username: '' # SMTP server username
|
||||
@ -85,7 +85,7 @@ mail:
|
||||
from: '' # sender email address
|
||||
|
||||
legal:
|
||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||
@ -113,11 +113,11 @@ system:
|
||||
name: postgres # set the name of your database. Should match the name of the database you create
|
||||
customPaths:
|
||||
pipeline:
|
||||
watchedFoldersDir: '' #Defaults to /pipeline/watchedFolders
|
||||
finishedFoldersDir: '' #Defaults to /pipeline/finishedFolders
|
||||
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
|
||||
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
|
||||
operations:
|
||||
weasyprint: '' #Defaults to /opt/venv/bin/weasyprint
|
||||
unoconvert: '' #Defaults to /opt/venv/bin/unoconvert
|
||||
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
|
||||
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
|
||||
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
||||
|
||||
ui:
|
||||
|
@ -1,7 +1,8 @@
|
||||
#page-container {
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: clip;
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
|
@ -162,6 +162,7 @@ html[dir="rtl"] .lang-dropdown-item-wrapper {
|
||||
text-wrap: wrap;
|
||||
word-break: break-word;
|
||||
width: 80%;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
@ -476,6 +477,9 @@ html[dir="rtl"] .dropdown-menu[data-bs-popper] {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
justify-content: center;
|
||||
width: 140%;
|
||||
position: relative;
|
||||
left: -20%;
|
||||
}
|
||||
|
||||
.feature-group {
|
||||
|
@ -4,10 +4,21 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (window.analyticsPromptBoolean) {
|
||||
const analyticsModal = new bootstrap.Modal(document.getElementById('analyticsModal'));
|
||||
analyticsModal.show();
|
||||
|
||||
let retryCount = 0;
|
||||
function hideCookieBanner() {
|
||||
const cookieBanner = document.querySelector('#cc-main');
|
||||
if (cookieBanner && cookieBanner.offsetHeight > 0) {
|
||||
cookieBanner.style.display = "none";
|
||||
} else if (retryCount < 20) {
|
||||
retryCount++;
|
||||
setTimeout(hideCookieBanner, 100);
|
||||
}
|
||||
}
|
||||
hideCookieBanner();
|
||||
}
|
||||
});
|
||||
/*]]>*/
|
||||
function setAnalytics(enabled) {
|
||||
/*]]>*/function setAnalytics(enabled) {
|
||||
fetchWithCsrf('api/v1/settings/update-enable-analytics', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -19,6 +30,15 @@ function setAnalytics(enabled) {
|
||||
if (response.status === 200) {
|
||||
console.log('Analytics setting updated successfully');
|
||||
bootstrap.Modal.getInstance(document.getElementById('analyticsModal')).hide();
|
||||
|
||||
if (typeof CookieConsent !== "undefined") {
|
||||
if (enabled) {
|
||||
CookieConsent.acceptCategory(['analytics']);
|
||||
} else {
|
||||
CookieConsent.acceptCategory([]);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (response.status === 208) {
|
||||
console.log('Analytics setting has already been set. Please edit /config/settings.yml to change it.', response);
|
||||
alert('Analytics setting has already been set. Please edit /config/settings.yml to change it.');
|
||||
|
@ -299,21 +299,42 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
|
||||
}
|
||||
}
|
||||
|
||||
listItem.innerHTML = `
|
||||
<div class="d-flex justify-content-between align-items-center w-100">
|
||||
<div class="operationName">${selectedOperation}</div>
|
||||
<div class="arrows d-flex">
|
||||
<button class="btn btn-secondary move-up ms-1"><span class="material-symbols-rounded">arrow_upward</span></button>
|
||||
<button class="btn btn-secondary move-down ms-1"><span class="material-symbols-rounded">arrow_downward</span></button>
|
||||
<button class="btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1" ${
|
||||
hasSettings ? "" : "disabled"
|
||||
}>
|
||||
<span class="material-symbols-rounded">settings</span>
|
||||
</button>
|
||||
<button class="btn btn-danger remove ms-1"><span class="material-symbols-rounded">close</span></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
let containerDiv = document.createElement("div");
|
||||
containerDiv.className = "d-flex justify-content-between align-items-center w-100";
|
||||
|
||||
let operationNameDiv = document.createElement("div");
|
||||
operationNameDiv.className = "operationName";
|
||||
operationNameDiv.textContent = selectedOperation;
|
||||
containerDiv.appendChild(operationNameDiv);
|
||||
|
||||
let arrowsDiv = document.createElement("div");
|
||||
arrowsDiv.className = "arrows d-flex";
|
||||
|
||||
let moveUpButton = document.createElement("button");
|
||||
moveUpButton.className = "btn btn-secondary move-up ms-1";
|
||||
moveUpButton.innerHTML = '<span class="material-symbols-rounded">arrow_upward</span>';
|
||||
arrowsDiv.appendChild(moveUpButton);
|
||||
|
||||
let moveDownButton = document.createElement("button");
|
||||
moveDownButton.className = "btn btn-secondary move-down ms-1";
|
||||
moveDownButton.innerHTML = '<span class="material-symbols-rounded">arrow_downward</span>';
|
||||
arrowsDiv.appendChild(moveDownButton);
|
||||
|
||||
let settingsButton = document.createElement("button");
|
||||
settingsButton.className = `btn ${hasSettings ? "btn-warning" : "btn-secondary"} pipelineSettings ms-1`;
|
||||
if (!hasSettings) {
|
||||
settingsButton.disabled = true;
|
||||
}
|
||||
settingsButton.innerHTML = '<span class="material-symbols-rounded">settings</span>';
|
||||
arrowsDiv.appendChild(settingsButton);
|
||||
|
||||
let removeButton = document.createElement("button");
|
||||
removeButton.className = "btn btn-danger remove ms-1";
|
||||
removeButton.innerHTML = '<span class="material-symbols-rounded">close</span>';
|
||||
arrowsDiv.appendChild(removeButton);
|
||||
|
||||
containerDiv.appendChild(arrowsDiv);
|
||||
listItem.appendChild(containerDiv);
|
||||
|
||||
pipelineList.appendChild(listItem);
|
||||
|
||||
|
@ -9,7 +9,7 @@ TabContainer = {
|
||||
tabList.classList.add('tab-buttons');
|
||||
tabTitles.forEach((title) => {
|
||||
const tabButton = document.createElement('button');
|
||||
tabButton.innerHTML = title;
|
||||
tabButton.textContent = title;
|
||||
tabButton.onclick = (e) => {
|
||||
this.setActiveTab(e.target);
|
||||
};
|
||||
|
@ -34,16 +34,32 @@
|
||||
<span class="tool-header-text" th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
||||
</div>
|
||||
|
||||
<!-- User Settings Title -->
|
||||
<div
|
||||
style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
||||
<a href="#" th:data-bs-toggle="${totalUsers >= maxPaidUsers} ? null : 'modal'"
|
||||
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
||||
th:class="${totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'"
|
||||
th:title="${totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
||||
<span class="material-symbols-rounded">person_add</span>
|
||||
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
||||
</a>
|
||||
<!-- User Settings Title -->
|
||||
<div style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
||||
<a href="#"
|
||||
th:data-bs-toggle="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : 'modal'"
|
||||
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
||||
th:class="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'"
|
||||
th:title="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
||||
<span class="material-symbols-rounded">person_add</span>
|
||||
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
||||
</a>
|
||||
|
||||
<a href="#"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#changeUserRoleModal"
|
||||
class="btn btn-outline-success"
|
||||
th:title="#{adminUserSettings.changeUserRole}">
|
||||
<span class="material-symbols-rounded">edit</span>
|
||||
<span th:text="#{adminUserSettings.changeUserRole}">Change User's Role</span>
|
||||
</a>
|
||||
|
||||
<a th:href="@{'/usage'}" th:if="${@runningEE}"
|
||||
class="btn btn-outline-success"
|
||||
th:title="#{adminUserSettings.usage}">
|
||||
<span class="material-symbols-rounded">analytics</span>
|
||||
<span th:text="#{adminUserSettings.usage}">Usage Statistics</span>
|
||||
</a>
|
||||
|
||||
<a href="#" data-bs-toggle="modal" data-bs-target="#changeUserRoleModal" class="btn btn-outline-success"
|
||||
th:title="#{adminUserSettings.changeUserRole}">
|
||||
@ -400,10 +416,8 @@
|
||||
checkboxContainer.slideDown('fast');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</script>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -41,8 +41,14 @@
|
||||
<link rel="stylesheet" th:href="@{'/css/bootstrap-icons.min.css'}">
|
||||
|
||||
<!-- Pixel, doesn't collect any PII-->
|
||||
<img referrerpolicy="no-referrer-when-downgrade" src="https://pixel.stirlingpdf.com/a.png?x-pxid=4f5fa02f-a065-4efb-bb2c-24509a4b6b92" style="position: absolute; visibility: hidden;"/>
|
||||
|
||||
<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;" />
|
||||
|
||||
<!-- Custom -->
|
||||
<link rel="stylesheet" th:href="@{'/css/general.css'}">
|
||||
<link rel="stylesheet" th:href="@{'/css/theme/theme.css'}">
|
||||
|
@ -1,43 +1,44 @@
|
||||
<th:block th:fragment="langs">
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('bg_BG', 'Български')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ar_AR', 'العربية')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ca_CA', 'Català')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_CN', '简体中文')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_TW', '繁體中文')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_BO', 'བོད་ཡིག')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('az_AZ', 'Azərbaycan Dili')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('da_DK', 'Dansk')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('de_DE', 'Deutsch')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_GB', 'English (GB)')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_US', 'English (US)')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('eu_ES', 'Euskara')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('es_ES', 'Español')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fr_FR', 'Français')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('id_ID', 'Bahasa Indonesia')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ga_IE', 'Gaeilge')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('it_IT', 'Italiano')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('nl_NL', 'Nederlands')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fa_IR', 'پارسی')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_BR', 'Português (BR)')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_PT', 'Português (PT)')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ro_RO', 'Română')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sk_SK', 'Slovenčina')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sl_SI', 'Slovenščina')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sv_SE', 'Svenska')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('tr_TR', 'Türkçe')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ru_RU', 'Русский')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ko_KR', '한국어')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ja_JP', '日本語')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('el_GR', 'Ελληνικά')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hu_HU', 'Magyar')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hi_IN', 'हिन्दी')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sr_LATN_RS', 'Srpski')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('uk_UA', 'Українська')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('cs_CZ', 'Česky')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hr_HR', 'Hrvatski')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('no_NB', 'Norsk')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('th_TH', 'ไทย')}" ></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('bg_BG', 'Български')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ar_AR', 'العربية')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ca_CA', 'Català')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_CN', '简体中文')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_TW', '繁體中文')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('zh_BO', 'བོད་ཡིག')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('az_AZ', 'Azərbaycan Dili')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('da_DK', 'Dansk')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('de_DE', 'Deutsch')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_GB', 'English (GB)')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('en_US', 'English (US)')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('eu_ES', 'Euskara')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('es_ES', 'Español')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fr_FR', 'Français')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('id_ID', 'Bahasa Indonesia')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ga_IE', 'Gaeilge')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('it_IT', 'Italiano')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('nl_NL', 'Nederlands')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('fa_IR', 'پارسی')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_BR', 'Português (BR)')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pt_PT', 'Português (PT)')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ro_RO', 'Română')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sk_SK', 'Slovenčina')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sl_SI', 'Slovenščina')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sv_SE', 'Svenska')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('tr_TR', 'Türkçe')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ru_RU', 'Русский')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ko_KR', '한국어')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ja_JP', '日本語')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('el_GR', 'Ελληνικά')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hu_HU', 'Magyar')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hi_IN', 'हिन्दी')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('sr_LATN_RS', 'Srpski')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('uk_UA', 'Українська')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('cs_CZ', 'Česky')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('hr_HR', 'Hrvatski')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('no_NB', 'Norsk')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('th_TH', 'ไทย')}"></div>
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('vi_VN', 'Tiếng Việt')}"></div>
|
||||
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('ml_IN', 'മലയാളം')}"></div>
|
||||
|
||||
</th:block>
|
@ -1,4 +1,4 @@
|
||||
<div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000">
|
||||
<div th:fragment="navbar" class="mx-auto" style="position: sticky; top:0; z-index:10000; width:100%">
|
||||
<script th:src="@{'/js/languageSelection.js'}"></script>
|
||||
<script th:src="@{'/js/navbar.js'}"></script>
|
||||
<script th:src="@{'/js/additionalLanguageCode.js'}"></script>
|
||||
|
@ -7,20 +7,18 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||
|
||||
|
||||
|
||||
<div id="page-container">
|
||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||
<div style="transform-origin: top;"
|
||||
id="scale-wrap">
|
||||
<br class="d-md-none">
|
||||
<!-- Features -->
|
||||
<script th:src="@{'/js/homecard.js'}"></script>
|
||||
<div style="
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;">
|
||||
|
||||
flex-direction: column;"
|
||||
>
|
||||
<div>
|
||||
<br>
|
||||
<div style="justify-content: center; display: flex;">
|
||||
@ -45,7 +43,7 @@
|
||||
th:insert="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
|
||||
</div>
|
||||
<div class="newfeature"
|
||||
th:insert="~{fragments/navbarEntry :: navbarEntry('validate-signature', 'verified', 'home.validateSignature.title', 'home.validateSignature.desc', 'validateSignature.tags', 'security')}">
|
||||
th:insert="~{fragments/navbarEntry :: navbarEntry('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPDFs.tags', 'advance')}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -123,9 +121,10 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
|
||||
|
||||
@ -222,7 +221,21 @@
|
||||
window.showSurvey = /*[[${showSurveyFromDocker}]]*/ true
|
||||
</script>
|
||||
<script th:src="@{'/js/pages/home.js'}" th:inline="javascript"></script>
|
||||
|
||||
<script>
|
||||
function applyScale() {
|
||||
const baseWidth = 1440;
|
||||
const baseHeight = 1000;
|
||||
const scaleX = window.innerWidth / baseWidth;
|
||||
const scaleY = window.innerHeight / baseHeight;
|
||||
const scale = Math.max(0.9, Math.min(scaleX, scaleY)); // keep aspect ratio, honor minScale
|
||||
const ui = document.getElementById('scale-wrap');
|
||||
ui.style.transform = `scale(${scale*0.75})`;
|
||||
}
|
||||
|
||||
window.addEventListener('resize', applyScale);
|
||||
window.addEventListener('load', applyScale);
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -41,36 +41,36 @@
|
||||
<div class="mb-3">
|
||||
<label class="mb-2" th:text="#{addPassword.selectText.5}"></label>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
||||
<label for="canAssembleDocument" th:text="#{addPassword.selectText.6}"></label>
|
||||
<input type="checkbox" id="preventAssembly" name="preventAssembly">
|
||||
<label for="preventAssembly" th:text="#{addPassword.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canExtractContent" name="canExtractContent">
|
||||
<label for="canExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
||||
<input type="checkbox" id="preventExtractContent" name="preventExtractContent">
|
||||
<label for="preventExtractContent" th:text="#{addPassword.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
||||
<label for="canExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
||||
<input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
|
||||
<label for="preventExtractForAccessibility" th:text="#{addPassword.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canFillInForm" name="canFillInForm">
|
||||
<label for="canFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
||||
<input type="checkbox" id="preventFillInForm" name="preventFillInForm">
|
||||
<label for="preventFillInForm" th:text="#{addPassword.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canModify" name="canModify">
|
||||
<label for="canModify" th:text="#{addPassword.selectText.10}"></label>
|
||||
<input type="checkbox" id="preventModify" name="preventModify">
|
||||
<label for="preventModify" th:text="#{addPassword.selectText.10}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
||||
<label for="canModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
||||
<input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
|
||||
<label for="preventModifyAnnotations" th:text="#{addPassword.selectText.11}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canPrint" name="canPrint">
|
||||
<label for="canPrint" th:text="#{addPassword.selectText.12}"></label>
|
||||
<input type="checkbox" id="preventPrinting" name="preventPrinting">
|
||||
<label for="preventPrinting" th:text="#{addPassword.selectText.12}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
||||
<label for="canPrintFaithful" th:text="#{addPassword.selectText.13}"></label>
|
||||
<input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
|
||||
<label for="preventPrintingFaithful" th:text="#{addPassword.selectText.13}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
@ -25,36 +25,36 @@
|
||||
<div class="mb-3">
|
||||
<label class="mb-2" th:text="#{permissions.selectText.2}"></label>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canAssembleDocument" name="canAssembleDocument">
|
||||
<label for="canAssembleDocument" th:text="#{permissions.selectText.3}"></label>
|
||||
<input type="checkbox" id="preventAssembly" name="preventAssembly">
|
||||
<label for="preventAssembly" th:text="#{permissions.selectText.3}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canExtractContent" name="canExtractContent">
|
||||
<label for="canExtractContent" th:text="#{permissions.selectText.4}"></label>
|
||||
<input type="checkbox" id="preventExtractContent" name="preventExtractContent">
|
||||
<label for="preventExtractContent" th:text="#{permissions.selectText.4}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canExtractForAccessibility" name="canExtractForAccessibility">
|
||||
<label for="canExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
||||
<input type="checkbox" id="preventExtractForAccessibility" name="preventExtractForAccessibility">
|
||||
<label for="preventExtractForAccessibility" th:text="#{permissions.selectText.5}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canFillInForm" name="canFillInForm">
|
||||
<label for="canFillInForm" th:text="#{permissions.selectText.6}"></label>
|
||||
<input type="checkbox" id="preventFillInForm" name="preventFillInForm">
|
||||
<label for="preventFillInForm" th:text="#{permissions.selectText.6}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canModify" name="canModify">
|
||||
<label for="canModify" th:text="#{permissions.selectText.7}"></label>
|
||||
<input type="checkbox" id="preventModify" name="preventModify">
|
||||
<label for="preventModify" th:text="#{permissions.selectText.7}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canModifyAnnotations" name="canModifyAnnotations">
|
||||
<label for="canModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
||||
<input type="checkbox" id="preventModifyAnnotations" name="preventModifyAnnotations">
|
||||
<label for="preventModifyAnnotations" th:text="#{permissions.selectText.8}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canPrint" name="canPrint">
|
||||
<label for="canPrint" th:text="#{permissions.selectText.9}"></label>
|
||||
<input type="checkbox" id="preventPrinting" name="preventPrinting">
|
||||
<label for="preventPrinting" th:text="#{permissions.selectText.9}"></label>
|
||||
</div>
|
||||
<div class="form-check ms-3">
|
||||
<input type="checkbox" id="canPrintFaithful" name="canPrintFaithful">
|
||||
<label for="canPrintFaithful" th:text="#{permissions.selectText.10}"></label>
|
||||
<input type="checkbox" id="preventPrintingFaithful" name="preventPrintingFaithful">
|
||||
<label for="preventPrintingFaithful" th:text="#{permissions.selectText.10}"></label>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
<link rel="stylesheet" th:href="@{'/pdfjs-legacy/css/viewer-redact.css'}">
|
||||
<script th:src="@{'/pdfjs-legacy/js/viewer.mjs'}" type="module"></script>
|
||||
<script src='./js/redact.js' type="module"></script>
|
||||
<script th:src="@{'/js/redact.js'}" type="module"></script>
|
||||
<link rel="stylesheet" th:href="@{'/css/redact.css'}">
|
||||
|
||||
</head>
|
||||
@ -695,4 +695,4 @@
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
@ -11,7 +11,6 @@
|
||||
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
|
||||
#############################################################################################################
|
||||
|
||||
|
||||
security:
|
||||
enableLogin: false # set to 'true' to enable login
|
||||
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
||||
@ -62,18 +61,32 @@ security:
|
||||
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
||||
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
||||
|
||||
enterpriseEdition:
|
||||
enabled: false # set to 'true' to enable enterprise edition
|
||||
premium:
|
||||
key: 00000000-0000-0000-0000-000000000000
|
||||
SSOAutoLogin: false # Enable to auto login to first provided SSO
|
||||
CustomMetadata:
|
||||
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
||||
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
||||
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
||||
enabled: false # Enable license key checks for pro/enterprise features
|
||||
proFeatures:
|
||||
SSOAutoLogin: false
|
||||
CustomMetadata:
|
||||
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
||||
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
||||
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
||||
googleDrive:
|
||||
enabled: false
|
||||
clientId: ''
|
||||
apiKey: ''
|
||||
appId: ''
|
||||
|
||||
mail:
|
||||
enabled: false # set to 'true' to enable sending emails
|
||||
host: smtp.example.com # SMTP server hostname
|
||||
port: 587 # SMTP server port
|
||||
username: '' # SMTP server username
|
||||
password: '' # SMTP server password
|
||||
from: '' # sender email address
|
||||
|
||||
legal:
|
||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||
@ -88,6 +101,7 @@ system:
|
||||
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: true # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
||||
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)
|
||||
datasource:
|
||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
||||
@ -100,13 +114,12 @@ system:
|
||||
name: postgres # set the name of your database. Should match the name of the database you create
|
||||
customPaths:
|
||||
pipeline:
|
||||
watchedFoldersDir: "" #Defaults to /pipeline/watchedFolders
|
||||
finishedFoldersDir: "" #Defaults to /pipeline/finishedFolders
|
||||
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
|
||||
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
|
||||
operations:
|
||||
weasyprint: "" #Defaults to /opt/venv/bin/weasyprint
|
||||
unoconvert: "" #Defaults to /opt/venv/bin/unoconvert
|
||||
|
||||
|
||||
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
|
||||
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
|
||||
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
||||
|
||||
ui:
|
||||
appName: '' # application's visible name
|
||||
|
Loading…
Reference in New Issue
Block a user