1
0
mirror of https://github.com/Stirling-Tools/Stirling-PDF.git synced 2024-11-23 15:21:25 +01:00

Frooodle/license (#1994)

This commit is contained in:
Anthony Stirling 2024-10-14 22:34:41 +01:00 committed by GitHub
parent ceeecc37ab
commit c85463bc18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
124 changed files with 4323 additions and 501 deletions

1
.gitignore vendored
View File

@ -110,7 +110,6 @@ watchedFolders/
*.war *.war
*.nar *.nar
*.ear *.ear
*.zip
*.tar.gz *.tar.gz
*.rar *.rar
*.db *.db

View File

@ -22,7 +22,7 @@ ext {
} }
group = "stirling.software" group = "stirling.software"
version = "0.29.0" version = "0.30.0"
java { java {
// 17 is lowest but we support and recommend 21 // 17 is lowest but we support and recommend 21
@ -32,6 +32,12 @@ java {
repositories { repositories {
mavenCentral() mavenCentral()
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
maven {
url "https://build.shibboleth.net/nexus/content/repositories/releases/"
}
maven {
url "https://build.shibboleth.net/maven/releases/"
}
} }
licenseReport { licenseReport {
@ -127,6 +133,9 @@ dependencies {
implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-jetty:$springBootVersion"
implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion"
implementation 'com.posthog.java:posthog:1.1.1'
implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1'
if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") {
implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion"
@ -134,6 +143,8 @@ dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion" implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
implementation 'org.springframework.security:spring-security-saml2-service-provider:6.3.3'
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
//2.2.x requires rebuild of DB file.. need migration path //2.2.x requires rebuild of DB file.. need migration path
runtimeOnly "com.h2database:h2:2.1.214" runtimeOnly "com.h2database:h2:2.1.214"
// implementation "com.h2database:h2:2.2.224" // implementation "com.h2database:h2:2.2.224"

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>

View File

@ -0,0 +1,16 @@
header
============
Header2
------------
text
text2
## **PDF Features**
### **Page Operations**
- View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts)
- Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.
- Merge multiple PDFs together into a single resultant file.

Binary file not shown.

View File

@ -123,7 +123,7 @@ Feature: API Validation
| odt | .odt | | odt | .odt |
| doc | .doc | | doc | .doc |
@ocr @ocr @pdfa1
Scenario: PDFA Scenario: PDFA
Given I use an example file at "exampleFiles/pdfa2.pdf" as parameter "fileInput" Given I use an example file at "exampleFiles/pdfa2.pdf" as parameter "fileInput"
And the request data includes And the request data includes
@ -134,7 +134,7 @@ Feature: API Validation
And the response file should have extension ".pdf" And the response file should have extension ".pdf"
And the response file should have size greater than 100 And the response file should have size greater than 100
@ocr @ocr @pdfa2
Scenario: PDFA1 Scenario: PDFA1
Given I use an example file at "exampleFiles/pdfa1.pdf" as parameter "fileInput" Given I use an example file at "exampleFiles/pdfa1.pdf" as parameter "fileInput"
And the request data includes And the request data includes
@ -219,5 +219,27 @@ Feature: API Validation
| .pptx | | .pptx |
| .rtf | | .rtf |
@calibre @positive @htmltopdf
Scenario: Convert HTML to PDF
Given I use an example file at "exampleFiles/example.html" as parameter "fileInput"
When I send the API request to the endpoint "/api/v1/convert/html/pdf"
Then the response status code should be 200
And the response file should have size greater than 100
And the response file should have extension ".pdf"
@calibre @positive @zippedhtmltopdf
Scenario: Convert zipped HTML to PDF
Given I use an example file at "exampleFiles/example_html.zip" as parameter "fileInput"
When I send the API request to the endpoint "/api/v1/convert/html/pdf"
Then the response status code should be 200
And the response file should have size greater than 100
And the response file should have extension ".pdf"
@calibre @positive @markdowntopdf
Scenario: Convert Markdown to PDF
Given I use an example file at "exampleFiles/example.md" as parameter "fileInput"
When I send the API request to the endpoint "/api/v1/convert/markdown/pdf"
Then the response status code should be 200
And the response file should have size greater than 100
And the response file should have extension ".pdf"

View File

@ -7,7 +7,7 @@ services:
limits: limits:
memory: 4G memory: 4G
healthcheck: healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"] test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"]
interval: 5s interval: 5s
timeout: 10s timeout: 10s
retries: 16 retries: 16
@ -19,7 +19,7 @@ services:
- /stirling/latest/logs:/logs:rw - /stirling/latest/logs:/logs:rw
environment: environment:
DOCKER_ENABLE_SECURITY: "true" DOCKER_ENABLE_SECURITY: "true"
SECURITY_ENABLELOGIN: "true" SECURITY_ENABLELOGIN: "false"
PUID: 1002 PUID: 1002
PGID: 1002 PGID: 1002
UMASK: "022" UMASK: "022"

View File

@ -17,9 +17,10 @@ public class EEAppConfig {
@Autowired ApplicationProperties applicationProperties; @Autowired ApplicationProperties applicationProperties;
@Bean(name = "RunningEE") @Autowired private LicenseKeyChecker licenseKeyChecker;
@Bean(name = "runningEE")
public boolean runningEnterpriseEdition() { public boolean runningEnterpriseEdition() {
// TODO: Implement EE detection return licenseKeyChecker.getEnterpriseEnabledResult();
return false;
} }
} }

View File

@ -0,0 +1,204 @@
package stirling.software.SPDF.EE;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.posthog.java.shaded.org.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.utils.GeneralUtils;
@Service
@Slf4j
public class KeygenLicenseVerifier {
private static final String ACCOUNT_ID = "e5430f69-e834-4ae4-befd-b602aae5f372";
private static final String BASE_URL = "https://api.keygen.sh/v1/accounts";
private static final ObjectMapper objectMapper = new ObjectMapper();
private final ApplicationProperties applicationProperties;
@Autowired
public KeygenLicenseVerifier(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public boolean verifyLicense(String licenseKey) {
try {
log.info("Checking license key");
String machineFingerprint = generateMachineFingerprint();
// First, try to validate the license
JsonNode validationResponse = validateLicense(licenseKey, machineFingerprint);
if (validationResponse != null) {
boolean isValid = validationResponse.path("meta").path("valid").asBoolean();
String licenseId = validationResponse.path("data").path("id").asText();
if (!isValid) {
String code = validationResponse.path("meta").path("code").asText();
log.debug(code);
if ("NO_MACHINE".equals(code)
|| "NO_MACHINES".equals(code)
|| "FINGERPRINT_SCOPE_MISMATCH".equals(code)) {
log.info(
"License not activated for this machine. Attempting to activate...");
boolean activated =
activateMachine(licenseKey, licenseId, machineFingerprint);
if (activated) {
// Revalidate after activation
validationResponse = validateLicense(licenseKey, machineFingerprint);
isValid =
validationResponse != null
&& validationResponse
.path("meta")
.path("valid")
.asBoolean();
}
}
}
return isValid;
}
return false;
} catch (Exception e) {
log.error("Error verifying license: " + e.getMessage());
return false;
}
}
private JsonNode validateLicense(String licenseKey, String machineFingerprint)
throws Exception {
HttpClient client = HttpClient.newHttpClient();
String requestBody =
String.format(
"{\"meta\":{\"key\":\"%s\",\"scope\":{\"fingerprint\":\"%s\"}}}",
licenseKey, machineFingerprint);
HttpRequest request =
HttpRequest.newBuilder()
.uri(
URI.create(
BASE_URL
+ "/"
+ ACCOUNT_ID
+ "/licenses/actions/validate-key"))
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
// .header("Authorization", "License " + licenseKey)
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
log.info(" validateLicenseResponse body: " + response.body());
JsonNode jsonResponse = objectMapper.readTree(response.body());
if (response.statusCode() == 200) {
JsonNode metaNode = jsonResponse.path("meta");
boolean isValid = metaNode.path("valid").asBoolean();
String detail = metaNode.path("detail").asText();
String code = metaNode.path("code").asText();
log.debug("License validity: " + isValid);
log.debug("Validation detail: " + detail);
log.debug("Validation code: " + code);
int users =
jsonResponse
.path("data")
.path("attributes")
.path("metadata")
.path("users")
.asInt(0);
applicationProperties.getEnterpriseEdition().setMaxUsers(users);
log.info(applicationProperties.toString());
} else {
log.error("Error validating license. Status code: " + response.statusCode());
}
return jsonResponse;
}
private boolean activateMachine(String licenseKey, String licenseId, String machineFingerprint)
throws Exception {
HttpClient client = HttpClient.newHttpClient();
String hostname;
try {
hostname = java.net.InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
hostname = "Unknown";
}
JSONObject body =
new JSONObject()
.put(
"data",
new JSONObject()
.put("type", "machines")
.put(
"attributes",
new JSONObject()
.put("fingerprint", machineFingerprint)
.put(
"platform",
System.getProperty(
"os.name")) // Added
// platform
// parameter
.put(
"name",
hostname)) // Added name parameter
.put(
"relationships",
new JSONObject()
.put(
"license",
new JSONObject()
.put(
"data",
new JSONObject()
.put(
"type",
"licenses")
.put(
"id",
licenseId)))));
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/" + ACCOUNT_ID + "/machines"))
.header("Content-Type", "application/vnd.api+json")
.header("Accept", "application/vnd.api+json")
.header(
"Authorization",
"License " + licenseKey) // Keep the license key authentication
.POST(
HttpRequest.BodyPublishers.ofString(
body.toString())) // Send the JSON body
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("activateMachine Response body: " + response.body());
if (response.statusCode() == 201) {
log.info("Machine activated successfully");
return true;
} else {
log.error(
"Error activating machine. Status code: {}, error: {}",
response.statusCode(),
response.body());
return false;
}
}
private String generateMachineFingerprint() {
return GeneralUtils.generateMachineFingerprint();
}
}

View File

@ -0,0 +1,59 @@
package stirling.software.SPDF.EE;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.utils.GeneralUtils;
@Component
@Slf4j
public class LicenseKeyChecker {
private final KeygenLicenseVerifier licenseService;
private final ApplicationProperties applicationProperties;
private boolean enterpriseEnbaledResult = false;
@Autowired
public LicenseKeyChecker(
KeygenLicenseVerifier licenseService, ApplicationProperties applicationProperties) {
this.licenseService = licenseService;
this.applicationProperties = applicationProperties;
}
@Scheduled(fixedRate = 604800000, initialDelay = 1000) // 7 days in milliseconds
public void checkLicensePeriodically() {
checkLicense();
}
private void checkLicense() {
if (!applicationProperties.getEnterpriseEdition().isEnabled()) {
enterpriseEnbaledResult = false;
} else {
enterpriseEnbaledResult =
licenseService.verifyLicense(
applicationProperties.getEnterpriseEdition().getKey());
if (enterpriseEnbaledResult) {
log.info("License key is valid.");
} else {
log.info("License key is invalid.");
}
}
}
public void updateLicenseKey(String newKey) throws IOException {
applicationProperties.getEnterpriseEdition().setKey(newKey);
GeneralUtils.saveKeyToConfig("EnterpriseEdition.key", newKey, false);
checkLicense();
}
public boolean getEnterpriseEnabledResult() {
return enterpriseEnbaledResult;
}
}

View File

@ -11,6 +11,9 @@ import org.slf4j.LoggerFactory;
import io.github.pixee.security.SystemCommand; import io.github.pixee.security.SystemCommand;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LibreOfficeListener { public class LibreOfficeListener {
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeListener.class); private static final Logger logger = LoggerFactory.getLogger(LibreOfficeListener.class);
@ -31,7 +34,7 @@ public class LibreOfficeListener {
private LibreOfficeListener() {} private LibreOfficeListener() {}
private boolean isListenerRunning() { private boolean isListenerRunning() {
System.out.println("waiting for listener to start"); log.info("waiting for listener to start");
try (Socket socket = new Socket()) { try (Socket socket = new Socket()) {
socket.connect( socket.connect(
new InetSocketAddress("localhost", 2002), 1000); // Timeout after 1 second new InetSocketAddress("localhost", 2002), 1000); // Timeout after 1 second

View File

@ -160,4 +160,27 @@ public class AppConfig {
public String accessibilityStatement() { public String accessibilityStatement() {
return applicationProperties.getLegal().getAccessibilityStatement(); return applicationProperties.getLegal().getAccessibilityStatement();
} }
@Bean(name = "analyticsPrompt")
public boolean analyticsPrompt() {
return applicationProperties.getSystem().getEnableAnalytics() == null
|| "undefined".equals(applicationProperties.getSystem().getEnableAnalytics());
}
@Bean(name = "analyticsEnabled")
public boolean analyticsEnabled() {
if (applicationProperties.getEnterpriseEdition().isEnabled()) return true;
return applicationProperties.getSystem().getEnableAnalytics() != null
&& Boolean.parseBoolean(applicationProperties.getSystem().getEnableAnalytics());
}
@Bean(name = "StirlingPDFLabel")
public String stirlingPDFLabel() {
return "Stirling-PDF" + " v" + appVersion();
}
@Bean(name = "UUID")
public String uuid() {
return applicationProperties.getAutomaticallyGenerated().getUUID();
}
} }

View File

@ -5,6 +5,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import stirling.software.SPDF.config.interfaces.ShowAdminInterface;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
@Service @Service

View File

@ -0,0 +1,42 @@
package stirling.software.SPDF.config;
import java.io.IOException;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.utils.GeneralUtils;
@Component
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public class InitialSetup {
@Autowired private ApplicationProperties applicationProperties;
@PostConstruct
public void initUUIDKey() throws IOException {
String uuid = applicationProperties.getAutomaticallyGenerated().getUUID();
if (!GeneralUtils.isValidUUID(uuid)) {
uuid = UUID.randomUUID().toString(); // Generating a random UUID as the secret key
GeneralUtils.saveKeyToConfig("AutomaticallyGenerated.UUID", uuid);
applicationProperties.getAutomaticallyGenerated().setUUID(uuid);
}
}
@PostConstruct
public void initSecretKey() throws IOException {
String secretKey = applicationProperties.getAutomaticallyGenerated().getKey();
if (!GeneralUtils.isValidUUID(secretKey)) {
secretKey = UUID.randomUUID().toString(); // Generating a random UUID as the secret key
GeneralUtils.saveKeyToConfig("AutomaticallyGenerated.key", secretKey);
applicationProperties.getAutomaticallyGenerated().setKey(secretKey);
}
}
}

View File

@ -14,7 +14,7 @@ import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
@Configuration @Configuration
public class Beans implements WebMvcConfigurer { public class LocaleConfiguration implements WebMvcConfigurer {
@Autowired ApplicationProperties applicationProperties; @Autowired ApplicationProperties applicationProperties;

View File

@ -13,6 +13,7 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import stirling.software.SPDF.utils.RequestUriUtils; import stirling.software.SPDF.utils.RequestUriUtils;
@Component @Component
@ -32,10 +33,11 @@ public class MetricsFilter extends OncePerRequestFilter {
String uri = request.getRequestURI(); String uri = request.getRequestURI();
if (RequestUriUtils.isTrackableResource(request.getContextPath(), uri)) { if (RequestUriUtils.isTrackableResource(request.getContextPath(), uri)) {
HttpSession session = request.getSession(false);
String sessionId = (session != null) ? session.getId() : "no-session";
Counter counter = Counter counter =
Counter.builder("http.requests") Counter.builder("http.requests")
.tag("session", request.getSession().getId()) .tag("session", sessionId)
.tag("method", request.getMethod()) .tag("method", request.getMethod())
.tag("uri", uri) .tag("uri", uri)
.register(meterRegistry); .register(meterRegistry);

View File

@ -0,0 +1,34 @@
package stirling.software.SPDF.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.posthog.java.PostHog;
import jakarta.annotation.PreDestroy;
@Configuration
public class PostHogConfig {
@Value("${posthog.api.key}")
private String posthogApiKey;
@Value("${posthog.host}")
private String posthogHost;
private PostHog postHogClient;
@Bean
public PostHog postHogClient() {
postHogClient = new PostHog.Builder(posthogApiKey).host(posthogHost).build();
return postHogClient;
}
@PreDestroy
public void shutdownPostHog() {
if (postHogClient != null) {
postHogClient.shutdown();
}
}
}

View File

@ -0,0 +1,68 @@
// package stirling.software.SPDF.config.fingerprint;
//
// import java.io.IOException;
//
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.stereotype.Component;
// import org.springframework.web.filter.OncePerRequestFilter;
//
// import jakarta.servlet.FilterChain;
// import jakarta.servlet.ServletException;
// import jakarta.servlet.http.HttpServletRequest;
// import jakarta.servlet.http.HttpServletResponse;
// import jakarta.servlet.http.HttpSession;
// import lombok.extern.slf4j.Slf4j;
// import stirling.software.SPDF.utils.RequestUriUtils;
//
//// @Component
// @Slf4j
// public class FingerprintBasedSessionFilter extends OncePerRequestFilter {
// private final FingerprintGenerator fingerprintGenerator;
// private final FingerprintBasedSessionManager sessionManager;
//
// @Autowired
// public FingerprintBasedSessionFilter(
// FingerprintGenerator fingerprintGenerator,
// FingerprintBasedSessionManager sessionManager) {
// this.fingerprintGenerator = fingerprintGenerator;
// this.sessionManager = sessionManager;
// }
//
// @Override
// protected void doFilterInternal(
// HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
// throws ServletException, IOException {
//
// if (RequestUriUtils.isStaticResource(request.getContextPath(), request.getRequestURI())) {
// filterChain.doFilter(request, response);
// return;
// }
//
// String fingerprint = fingerprintGenerator.generateFingerprint(request);
// log.debug("Generated fingerprint for request: {}", fingerprint);
//
// HttpSession session = request.getSession();
// boolean isNewSession = session.isNew();
// String sessionId = session.getId();
//
// if (isNewSession) {
// log.info("New session created: {}", sessionId);
// }
//
// if (!sessionManager.isFingerPrintAllowed(fingerprint)) {
// log.info("Blocked fingerprint detected, redirecting: {}", fingerprint);
// response.sendRedirect(request.getContextPath() + "/too-many-requests");
// return;
// }
//
// session.setAttribute("userFingerprint", fingerprint);
// session.setAttribute(
// FingerprintBasedSessionManager.STARTUP_TIMESTAMP,
// FingerprintBasedSessionManager.APP_STARTUP_TIME);
//
// sessionManager.registerFingerprint(fingerprint, sessionId);
//
// log.debug("Proceeding with request: {}", request.getRequestURI());
// filterChain.doFilter(request, response);
// }
// }

View File

@ -0,0 +1,134 @@
// package stirling.software.SPDF.config.fingerprint;
//
// import java.util.Iterator;
// import java.util.Map;
// import java.util.concurrent.ConcurrentHashMap;
// import java.util.concurrent.TimeUnit;
//
// import org.springframework.scheduling.annotation.Scheduled;
// import org.springframework.stereotype.Component;
//
// import jakarta.servlet.http.HttpSession;
// import jakarta.servlet.http.HttpSessionAttributeListener;
// import jakarta.servlet.http.HttpSessionEvent;
// import jakarta.servlet.http.HttpSessionListener;
// import lombok.AllArgsConstructor;
// import lombok.Data;
// import lombok.extern.slf4j.Slf4j;
//
// @Slf4j
// @Component
// public class FingerprintBasedSessionManager
// implements HttpSessionListener, HttpSessionAttributeListener {
// private static final ConcurrentHashMap<String, FingerprintInfo> activeFingerprints =
// new ConcurrentHashMap<>();
//
// // To be reduced in later version to 8~
// private static final int MAX_ACTIVE_FINGERPRINTS = 30;
//
// static final String STARTUP_TIMESTAMP = "appStartupTimestamp";
// static final long APP_STARTUP_TIME = System.currentTimeMillis();
// private static final long FINGERPRINT_EXPIRATION = TimeUnit.MINUTES.toMillis(30);
//
// @Override
// public void sessionCreated(HttpSessionEvent se) {
// HttpSession session = se.getSession();
// String sessionId = session.getId();
// String fingerprint = (String) session.getAttribute("userFingerprint");
//
// if (fingerprint == null) {
// log.warn("Session created without fingerprint: {}", sessionId);
// return;
// }
//
// synchronized (activeFingerprints) {
// if (activeFingerprints.size() >= MAX_ACTIVE_FINGERPRINTS
// && !activeFingerprints.containsKey(fingerprint)) {
// log.info("Max fingerprints reached. Marking session as blocked: {}", sessionId);
// session.setAttribute("blocked", true);
// } else {
// activeFingerprints.put(
// fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
// log.info(
// "New fingerprint registered: {}. Total active fingerprints: {}",
// fingerprint,
// activeFingerprints.size());
// }
// session.setAttribute(STARTUP_TIMESTAMP, APP_STARTUP_TIME);
// }
// }
//
// @Override
// public void sessionDestroyed(HttpSessionEvent se) {
// HttpSession session = se.getSession();
// String fingerprint = (String) session.getAttribute("userFingerprint");
//
// if (fingerprint != null) {
// synchronized (activeFingerprints) {
// activeFingerprints.remove(fingerprint);
// log.info(
// "Fingerprint removed: {}. Total active fingerprints: {}",
// fingerprint,
// activeFingerprints.size());
// }
// }
// }
//
// public boolean isFingerPrintAllowed(String fingerprint) {
// synchronized (activeFingerprints) {
// return activeFingerprints.size() < MAX_ACTIVE_FINGERPRINTS
// || activeFingerprints.containsKey(fingerprint);
// }
// }
//
// public void registerFingerprint(String fingerprint, String sessionId) {
// synchronized (activeFingerprints) {
// activeFingerprints.put(
// fingerprint, new FingerprintInfo(sessionId, System.currentTimeMillis()));
// }
// }
//
// public void unregisterFingerprint(String fingerprint) {
// synchronized (activeFingerprints) {
// activeFingerprints.remove(fingerprint);
// }
// }
//
// @Scheduled(fixedRate = 1800000) // Run every 30 mins
// public void cleanupStaleFingerprints() {
// log.info("Starting cleanup of stale fingerprints");
// long now = System.currentTimeMillis();
// int removedCount = 0;
//
// synchronized (activeFingerprints) {
// Iterator<Map.Entry<String, FingerprintInfo>> iterator =
// activeFingerprints.entrySet().iterator();
// while (iterator.hasNext()) {
// Map.Entry<String, FingerprintInfo> entry = iterator.next();
// FingerprintInfo info = entry.getValue();
//
// if (now - info.getLastAccessTime() > FINGERPRINT_EXPIRATION) {
// iterator.remove();
// removedCount++;
// log.info("Removed stale fingerprint: {}", entry.getKey());
// }
// }
// }
//
// log.info("Cleanup complete. Removed {} stale fingerprints", removedCount);
// }
//
// public void updateLastAccessTime(String fingerprint) {
// FingerprintInfo info = activeFingerprints.get(fingerprint);
// if (info != null) {
// info.setLastAccessTime(System.currentTimeMillis());
// }
// }
//
// @Data
// @AllArgsConstructor
// private static class FingerprintInfo {
// private String sessionId;
// private long lastAccessTime;
// }
// }

View File

@ -0,0 +1,77 @@
// package stirling.software.SPDF.config.fingerprint;
//
// import java.security.MessageDigest;
// import java.security.NoSuchAlgorithmException;
//
// import org.springframework.stereotype.Component;
//
// import jakarta.servlet.http.HttpServletRequest;
//
// @Component
// public class FingerprintGenerator {
//
// public String generateFingerprint(HttpServletRequest request) {
// if (request == null) {
// return "";
// }
// StringBuilder fingerprintBuilder = new StringBuilder();
//
// // Add IP address
// fingerprintBuilder.append(request.getRemoteAddr());
//
// // Add X-Forwarded-For header if present (for clients behind proxies)
// String forwardedFor = request.getHeader("X-Forwarded-For");
// if (forwardedFor != null) {
// fingerprintBuilder.append(forwardedFor);
// }
//
// // Add User-Agent
// String userAgent = request.getHeader("User-Agent");
// if (userAgent != null) {
// fingerprintBuilder.append(userAgent);
// }
//
// // Add Accept-Language header
// String acceptLanguage = request.getHeader("Accept-Language");
// if (acceptLanguage != null) {
// fingerprintBuilder.append(acceptLanguage);
// }
//
// // Add Accept header
// String accept = request.getHeader("Accept");
// if (accept != null) {
// fingerprintBuilder.append(accept);
// }
//
// // Add Connection header
// String connection = request.getHeader("Connection");
// if (connection != null) {
// fingerprintBuilder.append(connection);
// }
//
// // Add server port
// fingerprintBuilder.append(request.getServerPort());
//
// // Add secure flag
// fingerprintBuilder.append(request.isSecure());
//
// // Generate a hash of the fingerprint
// return generateHash(fingerprintBuilder.toString());
// }
//
// private String generateHash(String input) {
// try {
// MessageDigest digest = MessageDigest.getInstance("SHA-256");
// byte[] hash = digest.digest(input.getBytes());
// StringBuilder hexString = new StringBuilder();
// for (byte b : hash) {
// String hex = Integer.toHexString(0xff & b);
// if (hex.length() == 1) hexString.append('0');
// hexString.append(hex);
// }
// return hexString.toString();
// } catch (NoSuchAlgorithmException e) {
// throw new RuntimeException("Failed to generate fingerprint hash", e);
// }
// }
// }

View File

@ -1,4 +1,4 @@
package stirling.software.SPDF.config; package stirling.software.SPDF.config.interfaces;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package stirling.software.SPDF.config; package stirling.software.SPDF.config.interfaces;
public interface ShowAdminInterface { public interface ShowAdminInterface {
default boolean getShowUpdateOnlyAdmins() { default boolean getShowUpdateOnlyAdmins() {

View File

@ -7,7 +7,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import stirling.software.SPDF.config.ShowAdminInterface; import stirling.software.SPDF.config.interfaces.ShowAdminInterface;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.User; import stirling.software.SPDF.model.User;
import stirling.software.SPDF.repository.UserRepository; import stirling.software.SPDF.repository.UserRepository;

View File

@ -1,6 +1,8 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional; import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -14,9 +16,12 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.User; import stirling.software.SPDF.model.User;
import stirling.software.SPDF.utils.RequestUriUtils; import stirling.software.SPDF.utils.RequestUriUtils;
@Slf4j
@Component @Component
public class FirstLoginFilter extends OncePerRequestFilter { public class FirstLoginFilter extends OncePerRequestFilter {
@ -50,6 +55,22 @@ public class FirstLoginFilter extends OncePerRequestFilter {
return; return;
} }
} }
if (log.isDebugEnabled()) {
HttpSession session = request.getSession(true);
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
String creationTime = timeFormat.format(new Date(session.getCreationTime()));
log.debug(
"Request Info - New: {}, creationTimeSession {}, ID: {}, IP: {}, User-Agent: {}, Referer: {}, Request URL: {}",
session.isNew(),
creationTime,
session.getId(),
request.getRemoteAddr(),
request.getHeader("User-Agent"),
request.getHeader("Referer"),
request.getRequestURL().toString());
}
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} }
} }

View File

@ -1,19 +1,14 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID; import java.util.UUID;
import org.simpleyaml.configuration.file.YamlFile;
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.DatabaseBackupInterface; import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.Role; import stirling.software.SPDF.model.Role;
@ -39,15 +34,6 @@ public class InitialSecuritySetup {
initializeInternalApiUser(); initializeInternalApiUser();
} }
@PostConstruct
public void initSecretKey() throws IOException {
String secretKey = applicationProperties.getAutomaticallyGenerated().getKey();
if (!isValidUUID(secretKey)) {
secretKey = UUID.randomUUID().toString(); // Generating a random UUID as the secret key
saveKeyToConfig(secretKey);
}
}
private void initializeAdminUser() throws IOException { private void initializeAdminUser() throws IOException {
String initialUsername = String initialUsername =
applicationProperties.getSecurity().getInitialLogin().getUsername(); applicationProperties.getSecurity().getInitialLogin().getUsername();
@ -89,33 +75,4 @@ public class InitialSecuritySetup {
log.info("Internal API user created: " + Role.INTERNAL_API_USER.getRoleId()); log.info("Internal API user created: " + Role.INTERNAL_API_USER.getRoleId());
} }
} }
private void saveKeyToConfig(String key) throws IOException {
Path path = Paths.get("configs", "settings.yml"); // Target the configs/settings.yml
final YamlFile settingsYml = new YamlFile(path.toFile());
DumperOptions yamlOptionssettingsYml =
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
yamlOptionssettingsYml.setSplitLines(false);
settingsYml.loadWithComments();
settingsYml
.path("AutomaticallyGenerated.key")
.set(key)
.comment("# Automatically Generated Settings (Do Not Edit Directly)");
settingsYml.save();
}
private boolean isValidUUID(String uuid) {
if (uuid == null) {
return false;
}
try {
UUID.fromString(uuid);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
} }

View File

@ -1,57 +1,55 @@
package stirling.software.SPDF.config.security; package stirling.software.SPDF.config.security;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.oauth2.client.registration.ClientRegistrations; import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.savedrequest.NullRequestCache;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationFailureHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2AuthenticationSuccessHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2LogoutSuccessHandler; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2LogoutSuccessHandler;
import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService; import stirling.software.SPDF.config.security.oauth2.CustomOAuth2UserService;
import stirling.software.SPDF.config.security.saml.ConvertResponseToAuthentication;
import stirling.software.SPDF.config.security.saml.CustomSAMLAuthenticationFailureHandler;
import stirling.software.SPDF.config.security.saml.CustomSAMLAuthenticationSuccessHandler;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.ApplicationProperties; import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2;
import stirling.software.SPDF.model.ApplicationProperties.Security.OAUTH2.Client;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.model.provider.GithubProvider;
import stirling.software.SPDF.model.provider.GoogleProvider;
import stirling.software.SPDF.model.provider.KeycloakProvider;
import stirling.software.SPDF.repository.JPATokenRepositoryImpl; import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@EnableMethodSecurity @EnableMethodSecurity
@Slf4j
public class SecurityConfiguration { public class SecurityConfiguration {
@Autowired private CustomUserDetailsService userDetailsService; @Autowired private CustomUserDetailsService userDetailsService;
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); @Autowired(required = false)
private GrantedAuthoritiesMapper userAuthoritiesMapper;
@Autowired(required = false)
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository;
@Bean @Bean
public PasswordEncoder passwordEncoder() { public PasswordEncoder passwordEncoder() {
@ -73,13 +71,18 @@ public class SecurityConfiguration {
@Autowired private FirstLoginFilter firstLoginFilter; @Autowired private FirstLoginFilter firstLoginFilter;
@Autowired private SessionPersistentRegistry sessionRegistry; @Autowired private SessionPersistentRegistry sessionRegistry;
@Autowired private ConvertResponseToAuthentication convertResponseToAuthentication;
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterBefore(userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); http.authenticationManager(authenticationManager(http));
if (loginEnabledValue) { if (loginEnabledValue) {
http.addFilterBefore(
userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
if (applicationProperties.getSecurity().getCsrfDisabled()) {
http.csrf(csrf -> csrf.disable()); http.csrf(csrf -> csrf.disable());
}
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
http.sessionManagement( http.sessionManagement(
@ -135,6 +138,7 @@ public class SecurityConfiguration {
return trimmedUri.startsWith("/login") return trimmedUri.startsWith("/login")
|| trimmedUri.startsWith("/oauth") || trimmedUri.startsWith("/oauth")
|| trimmedUri.startsWith("/saml2")
|| trimmedUri.endsWith(".svg") || trimmedUri.endsWith(".svg")
|| trimmedUri.startsWith( || trimmedUri.startsWith(
"/register") "/register")
@ -184,191 +188,82 @@ public class SecurityConfiguration {
userService, userService,
loginAttemptService)) loginAttemptService))
.userAuthoritiesMapper( .userAuthoritiesMapper(
userAuthoritiesMapper()))) userAuthoritiesMapper)))
.logout( .logout(
logout -> logout ->
logout.logoutSuccessHandler( logout.logoutSuccessHandler(
new CustomOAuth2LogoutSuccessHandler( new CustomOAuth2LogoutSuccessHandler(
applicationProperties))); applicationProperties)));
} }
// Handle SAML
if (applicationProperties.getSecurity().getSaml() != null
&& applicationProperties.getSecurity().getSaml().getEnabled()
&& !applicationProperties
.getSecurity()
.getLoginMethod()
.equalsIgnoreCase("normal")) {
http.saml2Login(
saml2 -> {
saml2.loginPage("/saml2")
.relyingPartyRegistrationRepository(
relyingPartyRegistrationRepository)
.successHandler(
new CustomSAMLAuthenticationSuccessHandler(
loginAttemptService,
userService,
applicationProperties))
.failureHandler(
new CustomSAMLAuthenticationFailureHandler());
})
.addFilterBefore(
userAuthenticationFilter, Saml2WebSsoAuthenticationFilter.class);
}
} else { } else {
http.csrf(csrf -> csrf.disable()) if (applicationProperties.getSecurity().getCsrfDisabled()) {
.authorizeHttpRequests(authz -> authz.anyRequest().permitAll()); http.csrf(csrf -> csrf.disable());
}
http.authorizeHttpRequests(authz -> authz.anyRequest().permitAll());
} }
return http.build(); return http.build();
} }
// Client Registration Repository for OAUTH2 OIDC Login
@Bean @Bean
@ConditionalOnProperty( @ConditionalOnProperty(
value = "security.oauth2.enabled", name = "security.saml.enabled",
havingValue = "true", havingValue = "true",
matchIfMissing = false) matchIfMissing = false)
public ClientRegistrationRepository clientRegistrationRepository() { public AuthenticationProvider samlAuthenticationProvider() {
List<ClientRegistration> registrations = new ArrayList<>(); OpenSaml4AuthenticationProvider authenticationProvider =
new OpenSaml4AuthenticationProvider();
githubClientRegistration().ifPresent(registrations::add); authenticationProvider.setResponseAuthenticationConverter(convertResponseToAuthentication);
oidcClientRegistration().ifPresent(registrations::add); return authenticationProvider;
googleClientRegistration().ifPresent(registrations::add);
keycloakClientRegistration().ifPresent(registrations::add);
if (registrations.isEmpty()) {
logger.error("At least one OAuth2 provider must be configured");
System.exit(1);
} }
return new InMemoryClientRegistrationRepository(registrations); // @Bean
} // public AuthenticationProvider daoAuthenticationProvider() {
// DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// provider.setUserDetailsService(userDetailsService); // UserDetailsService
// provider.setPasswordEncoder(passwordEncoder()); // PasswordEncoder
// return provider;
// }
private Optional<ClientRegistration> googleClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
GoogleProvider google = client.getGoogle();
return google != null && google.isSettingsValid()
? Optional.of(
ClientRegistration.withRegistrationId(google.getName())
.clientId(google.getClientId())
.clientSecret(google.getClientSecret())
.scope(google.getScopes())
.authorizationUri(google.getAuthorizationuri())
.tokenUri(google.getTokenuri())
.userInfoUri(google.getUserinfouri())
.userNameAttributeName(google.getUseAsUsername())
.clientName(google.getClientName())
.redirectUri("{baseUrl}/login/oauth2/code/" + google.getName())
.authorizationGrantType(
org.springframework.security.oauth2.core
.AuthorizationGrantType.AUTHORIZATION_CODE)
.build())
: Optional.empty();
}
private Optional<ClientRegistration> keycloakClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
KeycloakProvider keycloak = client.getKeycloak();
return keycloak != null && keycloak.isSettingsValid()
? Optional.of(
ClientRegistrations.fromIssuerLocation(keycloak.getIssuer())
.registrationId(keycloak.getName())
.clientId(keycloak.getClientId())
.clientSecret(keycloak.getClientSecret())
.scope(keycloak.getScopes())
.userNameAttributeName(keycloak.getUseAsUsername())
.clientName(keycloak.getClientName())
.build())
: Optional.empty();
}
private Optional<ClientRegistration> githubClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null || !oauth.getEnabled()) {
return Optional.empty();
}
Client client = oauth.getClient();
if (client == null) {
return Optional.empty();
}
GithubProvider github = client.getGithub();
return github != null && github.isSettingsValid()
? Optional.of(
ClientRegistration.withRegistrationId(github.getName())
.clientId(github.getClientId())
.clientSecret(github.getClientSecret())
.scope(github.getScopes())
.authorizationUri(github.getAuthorizationuri())
.tokenUri(github.getTokenuri())
.userInfoUri(github.getUserinfouri())
.userNameAttributeName(github.getUseAsUsername())
.clientName(github.getClientName())
.redirectUri("{baseUrl}/login/oauth2/code/" + github.getName())
.authorizationGrantType(
org.springframework.security.oauth2.core
.AuthorizationGrantType.AUTHORIZATION_CODE)
.build())
: Optional.empty();
}
private Optional<ClientRegistration> oidcClientRegistration() {
OAUTH2 oauth = applicationProperties.getSecurity().getOauth2();
if (oauth == null
|| oauth.getIssuer() == null
|| oauth.getIssuer().isEmpty()
|| oauth.getClientId() == null
|| oauth.getClientId().isEmpty()
|| oauth.getClientSecret() == null
|| oauth.getClientSecret().isEmpty()
|| oauth.getScopes() == null
|| oauth.getScopes().isEmpty()
|| oauth.getUseAsUsername() == null
|| oauth.getUseAsUsername().isEmpty()) {
return Optional.empty();
}
return Optional.of(
ClientRegistrations.fromIssuerLocation(oauth.getIssuer())
.registrationId("oidc")
.clientId(oauth.getClientId())
.clientSecret(oauth.getClientSecret())
.scope(oauth.getScopes())
.userNameAttributeName(oauth.getUseAsUsername())
.clientName("OIDC")
.build());
}
/*
This following function is to grant Authorities to the OAUTH2 user from the values stored in the database.
This is required for the internal; 'hasRole()' function to give out the correct role.
*/
@Bean @Bean
@ConditionalOnProperty( public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
value = "security.oauth2.enabled", AuthenticationManagerBuilder authenticationManagerBuilder =
havingValue = "true", http.getSharedObject(AuthenticationManagerBuilder.class);
matchIfMissing = false)
GrantedAuthoritiesMapper userAuthoritiesMapper() {
return (authorities) -> {
Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
authorities.forEach( // authenticationManagerBuilder =
authority -> { // authenticationManagerBuilder.authenticationProvider(
// Add existing OAUTH2 Authorities // daoAuthenticationProvider()); // Benutzername/Passwort
mappedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
// Add Authorities from database for existing user, if user is present. if (applicationProperties.getSecurity().getSaml() != null
if (authority instanceof OAuth2UserAuthority oauth2Auth) { && applicationProperties.getSecurity().getSaml().getEnabled()) {
String useAsUsername = authenticationManagerBuilder.authenticationProvider(
applicationProperties samlAuthenticationProvider()); // SAML
.getSecurity()
.getOauth2()
.getUseAsUsername();
Optional<User> userOpt =
userService.findByUsernameIgnoreCase(
(String) oauth2Auth.getAttributes().get(useAsUsername));
if (userOpt.isPresent()) {
User user = userOpt.get();
if (user != null) {
mappedAuthorities.add(
new SimpleGrantedAuthority(
userService.findRole(user).getAuthority()));
} }
} return authenticationManagerBuilder.build();
}
});
return mappedAuthorities;
};
} }
@Bean @Bean
@ -386,4 +281,14 @@ public class SecurityConfiguration {
public boolean activSecurity() { public boolean activSecurity() {
return true; return true;
} }
// // Only Dev test
// @Bean
// public WebSecurityCustomizer webSecurityCustomizer() {
// return (web) ->
// web.ignoring()
// .requestMatchers(
// "/css/**", "/images/**", "/js/**", "/**.svg",
// "/pdfjs-legacy/**");
// }
} }

View File

@ -5,7 +5,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
@ -30,13 +29,18 @@ import stirling.software.SPDF.model.User;
@Component @Component
public class UserAuthenticationFilter extends OncePerRequestFilter { public class UserAuthenticationFilter extends OncePerRequestFilter {
@Autowired @Lazy private UserService userService; private final UserService userService;
private final SessionPersistentRegistry sessionPersistentRegistry;
private final boolean loginEnabledValue;
@Autowired private SessionPersistentRegistry sessionPersistentRegistry; public UserAuthenticationFilter(
@Lazy UserService userService,
@Autowired SessionPersistentRegistry sessionPersistentRegistry,
@Qualifier("loginEnabled") @Qualifier("loginEnabled") boolean loginEnabledValue) {
public boolean loginEnabledValue; this.userService = userService;
this.sessionPersistentRegistry = sessionPersistentRegistry;
this.loginEnabledValue = loginEnabledValue;
}
@Override @Override
protected void doFilterInternal( protected void doFilterInternal(
@ -51,6 +55,19 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// Check for session expiration (unsure if needed)
// if (authentication != null && authentication.isAuthenticated()) {
// String sessionId = request.getSession().getId();
// SessionInformation sessionInfo =
// sessionPersistentRegistry.getSessionInformation(sessionId);
//
// if (sessionInfo != null && sessionInfo.isExpired()) {
// SecurityContextHolder.clearContext();
// response.sendRedirect(request.getContextPath() + "/login?expired=true");
// return;
// }
// }
// Check for API key in the request headers if no authentication exists // Check for API key in the request headers if no authentication exists
if (authentication == null || !authentication.isAuthenticated()) { if (authentication == null || !authentication.isAuthenticated()) {
String apiKey = request.getHeader("X-API-Key"); String apiKey = request.getHeader("X-API-Key");

View File

@ -19,7 +19,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import stirling.software.SPDF.config.DatabaseBackupInterface; import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface; import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.AuthenticationType; import stirling.software.SPDF.model.AuthenticationType;
@ -44,6 +44,10 @@ public class UserService implements UserServiceInterface {
@Autowired DatabaseBackupInterface databaseBackupHelper; @Autowired DatabaseBackupInterface databaseBackupHelper;
public long getTotalUserCount() {
return userRepository.count();
}
// Handle OAUTH2 login and user auto creation. // Handle OAUTH2 login and user auto creation.
public boolean processOAuth2PostLogin(String username, boolean autoCreateUser) public boolean processOAuth2PostLogin(String username, boolean autoCreateUser)
throws IllegalArgumentException, IOException { throws IllegalArgumentException, IOException {

View File

@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.DatabaseBackupInterface; import stirling.software.SPDF.config.interfaces.DatabaseBackupInterface;
import stirling.software.SPDF.utils.FileInfo; import stirling.software.SPDF.utils.FileInfo;
@Slf4j @Slf4j

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,16 +11,19 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class CustomHttpSessionListener implements HttpSessionListener { public class CustomHttpSessionListener implements HttpSessionListener {
@Autowired private SessionPersistentRegistry sessionPersistentRegistry; private SessionPersistentRegistry sessionPersistentRegistry;
@Autowired
public CustomHttpSessionListener(SessionPersistentRegistry sessionPersistentRegistry) {
super();
this.sessionPersistentRegistry = sessionPersistentRegistry;
}
@Override @Override
public void sessionCreated(HttpSessionEvent se) { public void sessionCreated(HttpSessionEvent se) {}
log.info("Session created: " + se.getSession().getId());
}
@Override @Override
public void sessionDestroyed(HttpSessionEvent se) { public void sessionDestroyed(HttpSessionEvent se) {
log.info("Session destroyed: " + se.getSession().getId());
sessionPersistentRegistry.expireSession(se.getSession().getId()); sessionPersistentRegistry.expireSession(se.getSession().getId());
} }
} }

View File

@ -84,6 +84,14 @@ public class SessionPersistentRegistry implements SessionRegistry {
} }
if (principalName != null) { if (principalName != null) {
// Clear old sessions for the principal (unsure if needed)
// List<SessionEntity> existingSessions =
// sessionRepository.findByPrincipalName(principalName);
// for (SessionEntity session : existingSessions) {
// session.setExpired(true);
// sessionRepository.save(session);
// }
SessionEntity sessionEntity = new SessionEntity(); SessionEntity sessionEntity = new SessionEntity();
sessionEntity.setSessionId(sessionId); sessionEntity.setSessionId(sessionId);
sessionEntity.setPrincipalName(principalName); sessionEntity.setPrincipalName(principalName);

View File

@ -25,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.CropPdfForm; import stirling.software.SPDF.model.api.general.CropPdfForm;
import stirling.software.SPDF.service.CustomPDDocumentFactory; import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.service.PostHogService;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController
@ -36,9 +37,13 @@ public class CropController {
private final CustomPDDocumentFactory pdfDocumentFactory; private final CustomPDDocumentFactory pdfDocumentFactory;
private final PostHogService postHogService;
@Autowired @Autowired
public CropController(CustomPDDocumentFactory pdfDocumentFactory) { public CropController(
CustomPDDocumentFactory pdfDocumentFactory, PostHogService postHogService) {
this.pdfDocumentFactory = pdfDocumentFactory; this.pdfDocumentFactory = pdfDocumentFactory;
this.postHogService = postHogService;
} }
@PostMapping(value = "/crop", consumes = "multipart/form-data") @PostMapping(value = "/crop", consumes = "multipart/form-data")

View File

@ -0,0 +1,37 @@
package stirling.software.SPDF.controller.api;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.utils.GeneralUtils;
@Controller
@Tag(name = "Settings", description = "Settings APIs")
@RequestMapping("/api/v1/settings")
@Hidden
public class SettingsController {
@Autowired ApplicationProperties applicationProperties;
@PostMapping("/update-enable-analytics")
@Hidden
public ResponseEntity<String> updateApiKey(@RequestBody Boolean enabled) throws IOException {
if (!"undefined".equals(applicationProperties.getSystem().getEnableAnalytics())) {
return ResponseEntity.status(HttpStatus.ALREADY_REPORTED)
.body(
"Setting has already been set, To adjust please edit /config/settings.yml");
}
GeneralUtils.saveKeyToConfig("system.enableAnalytics", String.valueOf(enabled), false);
applicationProperties.getSystem().setEnableAnalytics(String.valueOf(enabled));
return ResponseEntity.ok("Updated");
}
}

View File

@ -60,8 +60,6 @@ public class SplitPDFController {
// PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document); // PdfMetadata metadata = PdfMetadataService.extractMetadataFromPdf(document);
int totalPages = document.getNumberOfPages(); int totalPages = document.getNumberOfPages();
List<Integer> pageNumbers = request.getPageNumbersList(document, false); List<Integer> pageNumbers = request.getPageNumbersList(document, false);
System.out.println(
pageNumbers.stream().map(String::valueOf).collect(Collectors.joining(",")));
if (!pageNumbers.contains(totalPages - 1)) { if (!pageNumbers.contains(totalPages - 1)) {
// Create a mutable ArrayList so we can add to it // Create a mutable ArrayList so we can add to it
pageNumbers = new ArrayList<>(pageNumbers); pageNumbers = new ArrayList<>(pageNumbers);

View File

@ -32,9 +32,9 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import stirling.software.SPDF.config.PdfMetadataService;
import stirling.software.SPDF.model.PdfMetadata; import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest; import stirling.software.SPDF.model.api.SplitPdfByChaptersRequest;
import stirling.software.SPDF.service.PdfMetadataService;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
@RestController @RestController

View File

@ -30,6 +30,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.config.security.UserService; import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.config.security.session.SessionPersistentRegistry; import stirling.software.SPDF.config.security.session.SessionPersistentRegistry;
import stirling.software.SPDF.model.AuthenticationType; import stirling.software.SPDF.model.AuthenticationType;
@ -40,6 +41,7 @@ import stirling.software.SPDF.model.api.user.UsernameAndPass;
@Controller @Controller
@Tag(name = "User", description = "User APIs") @Tag(name = "User", description = "User APIs")
@RequestMapping("/api/v1/user") @RequestMapping("/api/v1/user")
@Slf4j
public class UserController { public class UserController {
@Autowired private UserService userService; @Autowired private UserService userService;
@ -191,13 +193,11 @@ public class UserController {
Map<String, String[]> paramMap = request.getParameterMap(); Map<String, String[]> paramMap = request.getParameterMap();
Map<String, String> updates = new HashMap<>(); Map<String, String> updates = new HashMap<>();
System.out.println("Received parameter map: " + paramMap);
for (Map.Entry<String, String[]> entry : paramMap.entrySet()) { for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {
updates.put(entry.getKey(), entry.getValue()[0]); updates.put(entry.getKey(), entry.getValue()[0]);
} }
System.out.println("Processed updates: " + updates); log.debug("Processed updates: " + updates);
// Assuming you have a method in userService to update the settings for a user // Assuming you have a method in userService to update the settings for a user
userService.updateUserSettings(principal.getName(), updates); userService.updateUserSettings(principal.getName(), updates);
@ -209,7 +209,7 @@ public class UserController {
@PostMapping("/admin/saveUser") @PostMapping("/admin/saveUser")
public RedirectView saveUser( public RedirectView saveUser(
@RequestParam(name = "username", required = true) String username, @RequestParam(name = "username", required = true) String username,
@RequestParam(name = "password", required = true) String password, @RequestParam(name = "password", required = false) String password,
@RequestParam(name = "role") String role, @RequestParam(name = "role") String role,
@RequestParam(name = "authType") String authType, @RequestParam(name = "authType") String authType,
@RequestParam(name = "forceChange", required = false, defaultValue = "false") @RequestParam(name = "forceChange", required = false, defaultValue = "false")

View File

@ -1,5 +1,6 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -14,7 +15,6 @@ import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now
// @RestController // @RestController
// @Tag(name = "Convert", description = "Convert APIs") // @Tag(name = "Convert", description = "Convert APIs")
// @RequestMapping("/api/v1/convert") // @RequestMapping("/api/v1/convert")
@ -24,7 +24,7 @@ public class ConvertBookToPDFController {
private final CustomPDDocumentFactory pdfDocumentFactory; private final CustomPDDocumentFactory pdfDocumentFactory;
// @Autowired @Autowired
public ConvertBookToPDFController( public ConvertBookToPDFController(
CustomPDDocumentFactory pdfDocumentFactory, CustomPDDocumentFactory pdfDocumentFactory,
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) { @Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
@ -66,6 +66,8 @@ public class ConvertBookToPDFController {
} }
byte[] pdfBytes = FileToPdf.convertBookTypeToPdf(fileInput.getBytes(), originalFilename); byte[] pdfBytes = FileToPdf.convertBookTypeToPdf(fileInput.getBytes(), originalFilename);
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
String outputFilename = String outputFilename =
originalFilename.replaceFirst("[.][^.]+$", "") originalFilename.replaceFirst("[.][^.]+$", "")
+ ".pdf"; // Remove file extension and append .pdf + ".pdf"; // Remove file extension and append .pdf

View File

@ -1,27 +1,39 @@
package stirling.software.SPDF.controller.api.converters; package stirling.software.SPDF.controller.api.converters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest; import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertHtmlToPDF { public class ConvertHtmlToPDF {
// @Autowired private final boolean bookAndHtmlFormatsInstalled;
@Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertHtmlToPDF(
CustomPDDocumentFactory pdfDocumentFactory,
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
this.pdfDocumentFactory = pdfDocumentFactory;
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
}
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf") @PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
@Operation( @Operation(
@ -49,6 +61,8 @@ public class ConvertHtmlToPDF {
originalFilename, originalFilename,
bookAndHtmlFormatsInstalled); bookAndHtmlFormatsInstalled);
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
String outputFilename = String outputFilename =
originalFilename.replaceFirst("[.][^.]+$", "") originalFilename.replaceFirst("[.][^.]+$", "")
+ ".pdf"; // Remove file extension and append .pdf + ".pdf"; // Remove file extension and append .pdf

View File

@ -10,28 +10,40 @@ import org.commonmark.node.Node;
import org.commonmark.parser.Parser; import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.AttributeProvider; import org.commonmark.renderer.html.AttributeProvider;
import org.commonmark.renderer.html.HtmlRenderer; import org.commonmark.renderer.html.HtmlRenderer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames; import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.GeneralFile; import stirling.software.SPDF.model.api.GeneralFile;
import stirling.software.SPDF.service.CustomPDDocumentFactory;
import stirling.software.SPDF.utils.FileToPdf; import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now @RestController
// @RestController @Tag(name = "Convert", description = "Convert APIs")
// @Tag(name = "Convert", description = "Convert APIs") @RequestMapping("/api/v1/convert")
// @RequestMapping("/api/v1/convert")
public class ConvertMarkdownToPdf { public class ConvertMarkdownToPdf {
// @Autowired private final boolean bookAndHtmlFormatsInstalled;
@Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private final CustomPDDocumentFactory pdfDocumentFactory;
@Autowired
public ConvertMarkdownToPdf(
CustomPDDocumentFactory pdfDocumentFactory,
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
this.pdfDocumentFactory = pdfDocumentFactory;
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
}
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf") @PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
@Operation( @Operation(
@ -70,7 +82,7 @@ public class ConvertMarkdownToPdf {
htmlContent.getBytes(), htmlContent.getBytes(),
"converted.html", "converted.html",
bookAndHtmlFormatsInstalled); bookAndHtmlFormatsInstalled);
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
String outputFilename = String outputFilename =
originalFilename.replaceFirst("[.][^.]+$", "") originalFilename.replaceFirst("[.][^.]+$", "")
+ ".pdf"; // Remove file extension and append .pdf + ".pdf"; // Remove file extension and append .pdf

View File

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
@ -20,13 +21,12 @@ import stirling.software.SPDF.utils.ProcessExecutor;
import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult; import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
import stirling.software.SPDF.utils.WebResponseUtils; import stirling.software.SPDF.utils.WebResponseUtils;
// Disabled for now
// @RestController // @RestController
// @Tag(name = "Convert", description = "Convert APIs") // @Tag(name = "Convert", description = "Convert APIs")
// @RequestMapping("/api/v1/convert") // @RequestMapping("/api/v1/convert")
public class ConvertPDFToBookController { public class ConvertPDFToBookController {
// @Autowired @Autowired
@Qualifier("bookAndHtmlFormatsInstalled") @Qualifier("bookAndHtmlFormatsInstalled")
private boolean bookAndHtmlFormatsInstalled; private boolean bookAndHtmlFormatsInstalled;

View File

@ -61,7 +61,7 @@ public class ConvertPDFToPDFA {
command.add("-dPDFA=" + ("pdfa".equals(outputFormat) ? "2" : "1")); command.add("-dPDFA=" + ("pdfa".equals(outputFormat) ? "2" : "1"));
command.add("-dNOPAUSE"); command.add("-dNOPAUSE");
command.add("-dBATCH"); command.add("-dBATCH");
command.add("-sColorConversionStrategy=UseDeviceIndependentColor"); command.add("-sColorConversionStrategy=sRGB");
command.add("-sDEVICE=pdfwrite"); command.add("-sDEVICE=pdfwrite");
command.add("-dPDFACompatibilityPolicy=2"); command.add("-dPDFACompatibilityPolicy=2");
command.add("-o"); command.add("-o");

View File

@ -60,8 +60,6 @@ public class ExtractImagesController {
MultipartFile file = request.getFileInput(); MultipartFile file = request.getFileInput();
String format = request.getFormat(); String format = request.getFormat();
boolean allowDuplicates = request.isAllowDuplicates(); boolean allowDuplicates = request.isAllowDuplicates();
System.out.println(
System.currentTimeMillis() + " file=" + file.getName() + ", format=" + format);
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());
// Determine if multithreading should be used based on PDF size or number of pages // Determine if multithreading should be used based on PDF size or number of pages

View File

@ -26,11 +26,13 @@ import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.api.misc.PrintFileRequest; import stirling.software.SPDF.model.api.misc.PrintFileRequest;
@RestController @RestController
@RequestMapping("/api/v1/misc") @RequestMapping("/api/v1/misc")
@Tag(name = "Misc", description = "Miscellaneous APIs") @Tag(name = "Misc", description = "Miscellaneous APIs")
@Slf4j
public class PrintFileController { public class PrintFileController {
// TODO // TODO
@ -59,7 +61,7 @@ public class PrintFileController {
new IllegalArgumentException( new IllegalArgumentException(
"No matching printer found")); "No matching printer found"));
System.out.println("Selected Printer: " + selectedService.getName()); log.info("Selected Printer: " + selectedService.getName());
if ("application/pdf".equals(contentType)) { if ("application/pdf".equals(contentType)) {
PDDocument document = Loader.loadPDF(file.getBytes()); PDDocument document = Loader.loadPDF(file.getBytes());

View File

@ -58,7 +58,6 @@ public class RedactController {
float customPadding = request.getCustomPadding(); float customPadding = request.getCustomPadding();
boolean convertPDFToImage = request.isConvertPDFToImage(); boolean convertPDFToImage = request.isConvertPDFToImage();
System.out.println(listOfTextString);
String[] listOfText = listOfTextString.split("\n"); String[] listOfText = listOfTextString.split("\n");
PDDocument document = pdfDocumentFactory.load(file); PDDocument document = pdfDocumentFactory.load(file);
@ -75,7 +74,6 @@ public class RedactController {
for (String text : listOfText) { for (String text : listOfText) {
text = text.trim(); text = text.trim();
System.out.println(text);
TextFinder textFinder = new TextFinder(text, useRegex, wholeWordSearchBool); TextFinder textFinder = new TextFinder(text, useRegex, wholeWordSearchBool);
List<PDFText> foundTexts = textFinder.getTextLocations(document); List<PDFText> foundTexts = textFinder.getTextLocations(document);
redactFoundText(document, foundTexts, customPadding, redactColor); redactFoundText(document, foundTexts, customPadding, redactColor);

View File

@ -108,6 +108,13 @@ public class GeneralWebController {
return "split-pdf-by-sections"; return "split-pdf-by-sections";
} }
@GetMapping("/split-pdf-by-chapters")
@Hidden
public String splitPdfByChapters(Model model) {
model.addAttribute("currentPage", "split-pdf-by-chapters");
return "split-pdf-by-chapters";
}
@GetMapping("/view-pdf") @GetMapping("/view-pdf")
@Hidden @Hidden
public String ViewPdfForm2(Model model) { public String ViewPdfForm2(Model model) {

View File

@ -11,6 +11,11 @@ import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import lombok.Data; import lombok.Data;
import lombok.ToString; import lombok.ToString;
@ -24,6 +29,7 @@ import stirling.software.SPDF.model.provider.UnsupportedProviderException;
@ConfigurationProperties(prefix = "") @ConfigurationProperties(prefix = "")
@PropertySource(value = "file:./configs/settings.yml", factory = YamlPropertySourceFactory.class) @PropertySource(value = "file:./configs/settings.yml", factory = YamlPropertySourceFactory.class)
@Data @Data
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApplicationProperties { public class ApplicationProperties {
private Legal legal = new Legal(); private Legal legal = new Legal();
@ -57,6 +63,7 @@ public class ApplicationProperties {
private Boolean csrfDisabled; private Boolean csrfDisabled;
private InitialLogin initialLogin = new InitialLogin(); private InitialLogin initialLogin = new InitialLogin();
private OAUTH2 oauth2 = new OAUTH2(); private OAUTH2 oauth2 = new OAUTH2();
private SAML saml = new SAML();
private int loginAttemptCount; private int loginAttemptCount;
private long loginResetTimeMinutes; private long loginResetTimeMinutes;
private String loginMethod = "all"; private String loginMethod = "all";
@ -67,6 +74,34 @@ public class ApplicationProperties {
@ToString.Exclude private String password; @ToString.Exclude private String password;
} }
@Data
public static class SAML {
private Boolean enabled = false;
private String entityId;
private String registrationId;
private String spBaseUrl;
private String idpMetadataLocation;
private KeyStore keystore;
@Data
public static class KeyStore {
private String keystoreLocation;
private String keystorePassword;
private String keyAlias;
private String keyPassword;
private String realmCertificateAlias;
public Resource getKeystoreResource() {
if (keystoreLocation.startsWith("classpath:")) {
return new ClassPathResource(
keystoreLocation.substring("classpath:".length()));
} else {
return new FileSystemResource(keystoreLocation);
}
}
}
}
@Data @Data
public static class OAUTH2 { public static class OAUTH2 {
private Boolean enabled = false; private Boolean enabled = false;
@ -136,6 +171,7 @@ public class ApplicationProperties {
private boolean customHTMLFiles; private boolean customHTMLFiles;
private String tessdataDir; private String tessdataDir;
private Boolean enableAlphaFunctionality; private Boolean enableAlphaFunctionality;
private String enableAnalytics;
} }
@Data @Data
@ -175,11 +211,14 @@ public class ApplicationProperties {
@Data @Data
public static class AutomaticallyGenerated { public static class AutomaticallyGenerated {
@ToString.Exclude private String key; @ToString.Exclude private String key;
private String UUID;
} }
@Data @Data
public static class EnterpriseEdition { public static class EnterpriseEdition {
private boolean enabled;
@ToString.Exclude private String key; @ToString.Exclude private String key;
private int maxUsers;
private CustomMetadata customMetadata = new CustomMetadata(); private CustomMetadata customMetadata = new CustomMetadata();
@Data @Data

View File

@ -10,8 +10,10 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper; import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition; import org.apache.pdfbox.text.TextPosition;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.PDFText; import stirling.software.SPDF.model.PDFText;
@Slf4j
public class TextFinder extends PDFTextStripper { public class TextFinder extends PDFTextStripper {
private final String searchText; private final String searchText;
@ -92,7 +94,7 @@ public class TextFinder extends PDFTextStripper {
public List<PDFText> getTextLocations(PDDocument document) throws Exception { public List<PDFText> getTextLocations(PDDocument document) throws Exception {
this.getText(document); this.getText(document);
System.out.println( log.debug(
"Found " "Found "
+ textOccurrences.size() + textOccurrences.size()
+ " occurrences of '" + " occurrences of '"

View File

@ -13,7 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import stirling.software.SPDF.config.PdfMetadataService;
import stirling.software.SPDF.model.PdfMetadata; import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
@ -35,6 +34,36 @@ public class CustomPDDocumentFactory {
return document; return document;
} }
public byte[] createNewBytesBasedOnOldDocument(byte[] oldDocument) throws IOException {
PDDocument document = Loader.loadPDF(oldDocument);
return createNewBytesBasedOnOldDocument(document);
}
public byte[] createNewBytesBasedOnOldDocument(File oldDocument) throws IOException {
PDDocument document = Loader.loadPDF(oldDocument);
return createNewBytesBasedOnOldDocument(document);
}
public byte[] createNewBytesBasedOnOldDocument(PDDocument oldDocument) throws IOException {
pdfMetadataService.setMetadataToPdf(
oldDocument, pdfMetadataService.extractMetadataFromPdf(oldDocument), true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
oldDocument.save(baos);
oldDocument.close();
return baos.toByteArray();
}
public PDDocument createNewDocumentBasedOnOldDocument(byte[] oldDocument) throws IOException {
PDDocument document = Loader.loadPDF(oldDocument);
return createNewDocumentBasedOnOldDocument(document);
}
public PDDocument createNewDocumentBasedOnOldDocument(File oldDocument) throws IOException {
PDDocument document = Loader.loadPDF(oldDocument);
return createNewDocumentBasedOnOldDocument(document);
}
public PDDocument createNewDocumentBasedOnOldDocument(PDDocument oldDocument) public PDDocument createNewDocumentBasedOnOldDocument(PDDocument oldDocument)
throws IOException { throws IOException {
PDDocument document = new PDDocument(); PDDocument document = new PDDocument();

View File

@ -0,0 +1,56 @@
package stirling.software.SPDF.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.search.Search;
@Service
public class MetricsAggregatorService {
private final MeterRegistry meterRegistry;
private final PostHogService postHogService;
private final Map<String, Double> lastSentMetrics = new ConcurrentHashMap<>();
@Autowired
public MetricsAggregatorService(MeterRegistry meterRegistry, PostHogService postHogService) {
this.meterRegistry = meterRegistry;
this.postHogService = postHogService;
}
@Scheduled(fixedRate = 900000) // Run every 15 minutes
public void aggregateAndSendMetrics() {
Map<String, Object> metrics = new HashMap<>();
Search.in(meterRegistry)
.name("http.requests")
.counters()
.forEach(
counter -> {
String key =
String.format(
"http_requests_%s_%s",
counter.getId().getTag("method"),
counter.getId().getTag("uri").replace("/", "_"));
double currentCount = counter.count();
double lastCount = lastSentMetrics.getOrDefault(key, 0.0);
double difference = currentCount - lastCount;
if (difference > 0) {
metrics.put(key, difference);
lastSentMetrics.put(key, currentCount);
}
});
// Send aggregated metrics to PostHog
if (!metrics.isEmpty()) {
postHogService.captureEvent("aggregated_metrics", metrics);
}
}
}

View File

@ -1,4 +1,4 @@
package stirling.software.SPDF.config; package stirling.software.SPDF.service;
import java.util.Calendar; import java.util.Calendar;
@ -15,16 +15,16 @@ import stirling.software.SPDF.model.PdfMetadata;
public class PdfMetadataService { public class PdfMetadataService {
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final String appVersion; private final String stirlingPDFLabel;
private final UserServiceInterface userService; private final UserServiceInterface userService;
@Autowired @Autowired
public PdfMetadataService( public PdfMetadataService(
ApplicationProperties applicationProperties, ApplicationProperties applicationProperties,
@Qualifier("appVersion") String appVersion, @Qualifier("StirlingPDFLabel") String stirlingPDFLabel,
@Autowired(required = false) UserServiceInterface userService) { @Autowired(required = false) UserServiceInterface userService) {
this.applicationProperties = applicationProperties; this.applicationProperties = applicationProperties;
this.appVersion = appVersion; this.stirlingPDFLabel = stirlingPDFLabel;
this.userService = userService; this.userService = userService;
} }
@ -59,51 +59,40 @@ public class PdfMetadataService {
private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) { private void setNewDocumentMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
String creator = "Stirling-PDF"; String creator = stirlingPDFLabel;
// if (applicationProperties if (applicationProperties
// .getEnterpriseEdition() .getEnterpriseEdition()
// .getCustomMetadata() .getCustomMetadata()
// .isAutoUpdateMetadata()) { .isAutoUpdateMetadata()) {
// producer = creator = applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator();
// pdf.getDocumentInformation().setProducer(stirlingPDFLabel);
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getProducer(); }
// creator =
// applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator();
// title = applicationProperties.getEnterpriseEdition().getCustomMetadata().getTitle();
// if ("{filename}".equals(title)) { pdf.getDocumentInformation().setCreator(creator);
// title = "Filename"; // Replace with actual filename logic
// } else if ("{unchanged}".equals(title)) {
// title = pdfMetadata.getTitle(); // Keep the original title
// }
// }
pdf.getDocumentInformation().setCreator(creator + " " + appVersion);
pdf.getDocumentInformation().setCreationDate(Calendar.getInstance()); pdf.getDocumentInformation().setCreationDate(Calendar.getInstance());
} }
private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) { private void setCommonMetadata(PDDocument pdf, PdfMetadata pdfMetadata) {
String producer = "Stirling-PDF";
String title = pdfMetadata.getTitle(); String title = pdfMetadata.getTitle();
pdf.getDocumentInformation().setTitle(title); pdf.getDocumentInformation().setTitle(title);
pdf.getDocumentInformation().setProducer(producer + " " + appVersion); pdf.getDocumentInformation().setProducer(stirlingPDFLabel);
pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject()); pdf.getDocumentInformation().setSubject(pdfMetadata.getSubject());
pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords()); pdf.getDocumentInformation().setKeywords(pdfMetadata.getKeywords());
pdf.getDocumentInformation().setModificationDate(Calendar.getInstance()); pdf.getDocumentInformation().setModificationDate(Calendar.getInstance());
String author = pdfMetadata.getAuthor(); String author = pdfMetadata.getAuthor();
// if (applicationProperties if (applicationProperties
// .getEnterpriseEdition() .getEnterpriseEdition()
// .getCustomMetadata() .getCustomMetadata()
// .isAutoUpdateMetadata()) { .isAutoUpdateMetadata()) {
// author = applicationProperties.getEnterpriseEdition().getCustomMetadata().getAuthor(); author = applicationProperties.getEnterpriseEdition().getCustomMetadata().getAuthor();
// if (userService != null) { if (userService != null) {
// author = author.replace("username", userService.getCurrentUsername()); author = author.replace("username", userService.getCurrentUsername());
// } }
// } }
pdf.getDocumentInformation().setAuthor(author); pdf.getDocumentInformation().setAuthor(author);
} }
} }

View File

@ -0,0 +1,379 @@
package stirling.software.SPDF.service;
import java.io.File;
import java.lang.management.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.posthog.java.PostHog;
import stirling.software.SPDF.model.ApplicationProperties;
@Service
public class PostHogService {
private final PostHog postHog;
private final String uniqueId;
private final ApplicationProperties applicationProperties;
@Autowired
public PostHogService(
PostHog postHog,
@Qualifier("UUID") String uuid,
ApplicationProperties applicationProperties) {
this.postHog = postHog;
this.uniqueId = uuid;
this.applicationProperties = applicationProperties;
captureSystemInfo();
}
private void captureSystemInfo() {
if (!Boolean.getBoolean(applicationProperties.getSystem().getEnableAnalytics())) {
return;
}
try {
postHog.capture(uniqueId, "system_info_captured", captureServerMetrics());
} catch (Exception e) {
// Handle exceptions
}
}
public void captureEvent(String eventName, Map<String, Object> properties) {
if (!Boolean.getBoolean(applicationProperties.getSystem().getEnableAnalytics())) {
return;
}
postHog.capture(uniqueId, eventName, properties);
}
public Map<String, Object> captureServerMetrics() {
Map<String, Object> metrics = new HashMap<>();
try {
// System info
metrics.put("os_name", System.getProperty("os.name"));
metrics.put("os_version", System.getProperty("os.version"));
metrics.put("java_version", System.getProperty("java.version"));
metrics.put("user_name", System.getProperty("user.name"));
metrics.put("user_home", System.getProperty("user.home"));
metrics.put("user_dir", System.getProperty("user.dir"));
// CPU and Memory
metrics.put("cpu_cores", Runtime.getRuntime().availableProcessors());
metrics.put("total_memory", Runtime.getRuntime().totalMemory());
metrics.put("free_memory", Runtime.getRuntime().freeMemory());
// Network and Server Identity
InetAddress localHost = InetAddress.getLocalHost();
metrics.put("ip_address", localHost.getHostAddress());
metrics.put("hostname", localHost.getHostName());
metrics.put("mac_address", getMacAddress());
// JVM info
metrics.put("jvm_vendor", System.getProperty("java.vendor"));
metrics.put("jvm_version", System.getProperty("java.vm.version"));
// Locale and Timezone
metrics.put("system_language", System.getProperty("user.language"));
metrics.put("system_country", System.getProperty("user.country"));
metrics.put("timezone", TimeZone.getDefault().getID());
metrics.put("locale", Locale.getDefault().toString());
// Disk info
File root = new File(".");
metrics.put("total_disk_space", root.getTotalSpace());
metrics.put("free_disk_space", root.getFreeSpace());
// Process info
metrics.put("process_id", ProcessHandle.current().pid());
// JVM metrics
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
metrics.put("jvm_uptime_ms", runtimeMXBean.getUptime());
metrics.put("jvm_start_time", runtimeMXBean.getStartTime());
// Memory metrics
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
metrics.put("heap_memory_usage", memoryMXBean.getHeapMemoryUsage().getUsed());
metrics.put("non_heap_memory_usage", memoryMXBean.getNonHeapMemoryUsage().getUsed());
// CPU metrics
OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
metrics.put("system_load_average", osMXBean.getSystemLoadAverage());
// Thread metrics
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
metrics.put("thread_count", threadMXBean.getThreadCount());
metrics.put("daemon_thread_count", threadMXBean.getDaemonThreadCount());
metrics.put("peak_thread_count", threadMXBean.getPeakThreadCount());
// Garbage collection metrics
for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
metrics.put("gc_" + gcBean.getName() + "_count", gcBean.getCollectionCount());
metrics.put("gc_" + gcBean.getName() + "_time", gcBean.getCollectionTime());
}
// Network interfaces
metrics.put("network_interfaces", getNetworkInterfacesInfo());
// Docker detection and stats
boolean isDocker = isRunningInDocker();
metrics.put("is_docker", isDocker);
if (isDocker) {
metrics.put("docker_metrics", getDockerMetrics());
}
metrics.put("application_properties", captureApplicationProperties());
} catch (Exception e) {
metrics.put("error", e.getMessage());
}
return metrics;
}
private boolean isRunningInDocker() {
return Files.exists(Paths.get("/.dockerenv"));
}
private Map<String, Object> getDockerMetrics() {
Map<String, Object> dockerMetrics = new HashMap<>();
// Network-related Docker info
dockerMetrics.put("docker_network_mode", System.getenv("DOCKER_NETWORK_MODE"));
// Container name (if set)
String containerName = System.getenv("CONTAINER_NAME");
if (containerName != null && !containerName.isEmpty()) {
dockerMetrics.put("container_name", containerName);
}
// Docker compose information
String composeProject = System.getenv("COMPOSE_PROJECT_NAME");
String composeService = System.getenv("COMPOSE_SERVICE_NAME");
if (composeProject != null && composeService != null) {
dockerMetrics.put("compose_project", composeProject);
dockerMetrics.put("compose_service", composeService);
}
// Kubernetes-specific info (if running in K8s)
String k8sPodName = System.getenv("KUBERNETES_POD_NAME");
if (k8sPodName != null) {
dockerMetrics.put("k8s_pod_name", k8sPodName);
dockerMetrics.put("k8s_namespace", System.getenv("KUBERNETES_NAMESPACE"));
dockerMetrics.put("k8s_node_name", System.getenv("KUBERNETES_NODE_NAME"));
}
// New environment variables
dockerMetrics.put("version_tag", System.getenv("VERSION_TAG"));
dockerMetrics.put("docker_enable_security", System.getenv("DOCKER_ENABLE_SECURITY"));
dockerMetrics.put("fat_docker", System.getenv("FAT_DOCKER"));
return dockerMetrics;
}
private void addIfNotEmpty(Map<String, Object> map, String key, Object value) {
if (value != null) {
if (value instanceof String) {
String strValue = (String) value;
if (!StringUtils.isBlank(strValue)) {
map.put(key, strValue.trim());
}
} else {
map.put(key, value);
}
}
}
public Map<String, Object> captureApplicationProperties() {
Map<String, Object> properties = new HashMap<>();
// Capture Legal properties
addIfNotEmpty(
properties,
"legal_termsAndConditions",
applicationProperties.getLegal().getTermsAndConditions());
addIfNotEmpty(
properties,
"legal_privacyPolicy",
applicationProperties.getLegal().getPrivacyPolicy());
addIfNotEmpty(
properties,
"legal_accessibilityStatement",
applicationProperties.getLegal().getAccessibilityStatement());
addIfNotEmpty(
properties,
"legal_cookiePolicy",
applicationProperties.getLegal().getCookiePolicy());
addIfNotEmpty(
properties, "legal_impressum", applicationProperties.getLegal().getImpressum());
// Capture Security properties
addIfNotEmpty(
properties,
"security_enableLogin",
applicationProperties.getSecurity().getEnableLogin());
addIfNotEmpty(
properties,
"security_csrfDisabled",
applicationProperties.getSecurity().getCsrfDisabled());
addIfNotEmpty(
properties,
"security_loginAttemptCount",
applicationProperties.getSecurity().getLoginAttemptCount());
addIfNotEmpty(
properties,
"security_loginResetTimeMinutes",
applicationProperties.getSecurity().getLoginResetTimeMinutes());
addIfNotEmpty(
properties,
"security_loginMethod",
applicationProperties.getSecurity().getLoginMethod());
// Capture OAuth2 properties (excluding sensitive information)
addIfNotEmpty(
properties,
"security_oauth2_enabled",
applicationProperties.getSecurity().getOauth2().getEnabled());
if (applicationProperties.getSecurity().getOauth2().getEnabled()) {
addIfNotEmpty(
properties,
"security_oauth2_autoCreateUser",
applicationProperties.getSecurity().getOauth2().getAutoCreateUser());
addIfNotEmpty(
properties,
"security_oauth2_blockRegistration",
applicationProperties.getSecurity().getOauth2().getBlockRegistration());
addIfNotEmpty(
properties,
"security_oauth2_useAsUsername",
applicationProperties.getSecurity().getOauth2().getUseAsUsername());
addIfNotEmpty(
properties,
"security_oauth2_provider",
applicationProperties.getSecurity().getOauth2().getProvider());
}
// Capture System properties
addIfNotEmpty(
properties,
"system_defaultLocale",
applicationProperties.getSystem().getDefaultLocale());
addIfNotEmpty(
properties,
"system_googlevisibility",
applicationProperties.getSystem().getGooglevisibility());
addIfNotEmpty(
properties, "system_showUpdate", applicationProperties.getSystem().isShowUpdate());
addIfNotEmpty(
properties,
"system_showUpdateOnlyAdmin",
applicationProperties.getSystem().getShowUpdateOnlyAdmin());
addIfNotEmpty(
properties,
"system_customHTMLFiles",
applicationProperties.getSystem().isCustomHTMLFiles());
addIfNotEmpty(
properties,
"system_tessdataDir",
applicationProperties.getSystem().getTessdataDir());
addIfNotEmpty(
properties,
"system_enableAlphaFunctionality",
applicationProperties.getSystem().getEnableAlphaFunctionality());
addIfNotEmpty(
properties,
"system_enableAnalytics",
applicationProperties.getSystem().getEnableAnalytics());
// Capture UI properties
addIfNotEmpty(properties, "ui_appName", applicationProperties.getUi().getAppName());
addIfNotEmpty(
properties,
"ui_homeDescription",
applicationProperties.getUi().getHomeDescription());
addIfNotEmpty(
properties, "ui_appNameNavbar", applicationProperties.getUi().getAppNameNavbar());
// Capture Metrics properties
addIfNotEmpty(
properties, "metrics_enabled", applicationProperties.getMetrics().getEnabled());
// Capture EnterpriseEdition properties
addIfNotEmpty(
properties,
"enterpriseEdition_enabled",
applicationProperties.getEnterpriseEdition().isEnabled());
if (applicationProperties.getEnterpriseEdition().isEnabled()) {
addIfNotEmpty(
properties,
"enterpriseEdition_customMetadata_autoUpdateMetadata",
applicationProperties
.getEnterpriseEdition()
.getCustomMetadata()
.isAutoUpdateMetadata());
addIfNotEmpty(
properties,
"enterpriseEdition_customMetadata_author",
applicationProperties.getEnterpriseEdition().getCustomMetadata().getAuthor());
addIfNotEmpty(
properties,
"enterpriseEdition_customMetadata_creator",
applicationProperties.getEnterpriseEdition().getCustomMetadata().getCreator());
addIfNotEmpty(
properties,
"enterpriseEdition_customMetadata_producer",
applicationProperties.getEnterpriseEdition().getCustomMetadata().getProducer());
}
// Capture AutoPipeline properties
addIfNotEmpty(
properties,
"autoPipeline_outputFolder",
applicationProperties.getAutoPipeline().getOutputFolder());
return properties;
}
private String getMacAddress() {
try {
Enumeration<NetworkInterface> networkInterfaces =
NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface ni = networkInterfaces.nextElement();
byte[] hardwareAddress = ni.getHardwareAddress();
if (hardwareAddress != null) {
String[] hexadecimal = new String[hardwareAddress.length];
for (int i = 0; i < hardwareAddress.length; i++) {
hexadecimal[i] = String.format("%02X", hardwareAddress[i]);
}
return String.join("-", hexadecimal);
}
}
} catch (Exception e) {
// Handle exception
}
return "Unknown";
}
private Map<String, String> getNetworkInterfacesInfo() {
Map<String, String> interfacesInfo = new HashMap<>();
try {
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {
NetworkInterface netint = nets.nextElement();
interfacesInfo.put(netint.getName(), netint.getDisplayName());
}
} catch (Exception e) {
interfacesInfo.put("error", e.getMessage());
}
return interfacesInfo;
}
}

View File

@ -0,0 +1,21 @@
package stirling.software.SPDF.utils;
import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.owasp.html.Sanitizers;
public class CustomHtmlSanitizer {
private static final PolicyFactory POLICY =
Sanitizers.FORMATTING
.and(Sanitizers.BLOCKS)
.and(Sanitizers.STYLES)
.and(Sanitizers.LINKS)
.and(Sanitizers.TABLES)
.and(Sanitizers.IMAGES)
.and(new HtmlPolicyBuilder().disallowElements("noscript").toFactory());
public static String sanitize(String html) {
String htmlAfter = POLICY.sanitize(html);
return htmlAfter;
}
}

View File

@ -2,16 +2,23 @@ package stirling.software.SPDF.utils;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import io.github.pixee.security.ZipSecurity; import io.github.pixee.security.ZipSecurity;
@ -33,19 +40,25 @@ public class FileToPdf {
try { try {
if (fileName.endsWith(".html")) { if (fileName.endsWith(".html")) {
tempInputFile = Files.createTempFile("input_", ".html"); tempInputFile = Files.createTempFile("input_", ".html");
Files.write(tempInputFile, fileBytes); String sanitizedHtml =
} else { sanitizeHtmlContent(new String(fileBytes, StandardCharsets.UTF_8));
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
} else if (fileName.endsWith(".zip")) {
tempInputFile = Files.createTempFile("input_", ".zip"); tempInputFile = Files.createTempFile("input_", ".zip");
Files.write(tempInputFile, fileBytes); Files.write(tempInputFile, fileBytes);
sanitizeHtmlFilesInZip(tempInputFile);
} else {
throw new IllegalArgumentException("Unsupported file format: " + fileName);
} }
List<String> command = new ArrayList<>(); List<String> command = new ArrayList<>();
if (!htmlFormatsInstalled) { if (!htmlFormatsInstalled) {
command.add("weasyprint"); command.add("weasyprint");
command.add("-e utf-8"); command.add("-e");
command.add("utf-8");
command.add("-v");
command.add(tempInputFile.toString()); command.add(tempInputFile.toString());
command.add(tempOutputFile.toString()); command.add(tempOutputFile.toString());
} else { } else {
command.add("ebook-convert"); command.add("ebook-convert");
command.add(tempInputFile.toString()); command.add(tempInputFile.toString());
@ -54,10 +67,8 @@ public class FileToPdf {
command.add("a4"); command.add("a4");
if (request != null && request.getZoom() != 1.0) { if (request != null && request.getZoom() != 1.0) {
// Create a temporary CSS file
File tempCssFile = Files.createTempFile("customStyle", ".css").toFile(); File tempCssFile = Files.createTempFile("customStyle", ".css").toFile();
try (FileWriter writer = new FileWriter(tempCssFile)) { try (FileWriter writer = new FileWriter(tempCssFile)) {
// Write the CSS rule to the file
writer.write("body { zoom: " + request.getZoom() + "; }"); writer.write("body { zoom: " + request.getZoom() + "; }");
} }
command.add("--extra-css"); command.add("--extra-css");
@ -65,9 +76,7 @@ public class FileToPdf {
} }
} }
ProcessExecutorResult returnCode; ProcessExecutorResult returnCode =
returnCode =
ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT) ProcessExecutor.getInstance(ProcessExecutor.Processes.WEASYPRINT)
.runCommandWithOutputHandling(command); .runCommandWithOutputHandling(command);
@ -78,8 +87,6 @@ public class FileToPdf {
throw e; throw e;
} }
} finally { } finally {
// Clean up temporary files
Files.deleteIfExists(tempOutputFile); Files.deleteIfExists(tempOutputFile);
Files.deleteIfExists(tempInputFile); Files.deleteIfExists(tempInputFile);
} }
@ -87,6 +94,81 @@ public class FileToPdf {
return pdfBytes; return pdfBytes;
} }
private static String sanitizeHtmlContent(String htmlContent) {
return CustomHtmlSanitizer.sanitize(htmlContent);
}
private static void sanitizeHtmlFilesInZip(Path zipFilePath) throws IOException {
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
try (ZipInputStream zipIn =
ZipSecurity.createHardenedInputStream(
new ByteArrayInputStream(Files.readAllBytes(zipFilePath)))) {
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
Path filePath = tempUnzippedDir.resolve(entry.getName());
if (!entry.isDirectory()) {
Files.createDirectories(filePath.getParent());
if (entry.getName().toLowerCase().endsWith(".html")
|| entry.getName().toLowerCase().endsWith(".htm")) {
String content = new String(zipIn.readAllBytes(), StandardCharsets.UTF_8);
String sanitizedContent = sanitizeHtmlContent(content);
Files.write(filePath, sanitizedContent.getBytes(StandardCharsets.UTF_8));
} else {
Files.copy(zipIn, filePath);
}
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
}
// Repack the sanitized files
zipDirectory(tempUnzippedDir, zipFilePath);
// Clean up
deleteDirectory(tempUnzippedDir);
}
private static void zipDirectory(Path sourceDir, Path zipFilePath) throws IOException {
try (ZipOutputStream zos =
new ZipOutputStream(new FileOutputStream(zipFilePath.toFile()))) {
Files.walk(sourceDir)
.filter(path -> !Files.isDirectory(path))
.forEach(
path -> {
ZipEntry zipEntry =
new ZipEntry(sourceDir.relativize(path).toString());
try {
zos.putNextEntry(zipEntry);
Files.copy(path, zos);
zos.closeEntry();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}
private static void deleteDirectory(Path dir) throws IOException {
Files.walkFileTree(
dir,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
private static Path unzipAndGetMainHtml(byte[] fileBytes) throws IOException { private static Path unzipAndGetMainHtml(byte[] fileBytes) throws IOException {
Path tempDirectory = Files.createTempDirectory("unzipped_"); Path tempDirectory = Files.createTempDirectory("unzipped_");
try (ZipInputStream zipIn = try (ZipInputStream zipIn =

View File

@ -5,18 +5,28 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor; import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.UUID;
import org.simpleyaml.configuration.file.YamlFile;
import org.simpleyaml.configuration.file.YamlFileWrapper;
import org.simpleyaml.configuration.implementation.SimpleYamlImplementation;
import org.simpleyaml.configuration.implementation.snakeyaml.lib.DumperOptions;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -262,4 +272,81 @@ public class GeneralUtils {
} }
return true; return true;
} }
public static boolean isValidUUID(String uuid) {
if (uuid == null) {
return false;
}
try {
UUID.fromString(uuid);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
public static void saveKeyToConfig(String id, String key) throws IOException {
saveKeyToConfig(id, key, true);
}
public static void saveKeyToConfig(String id, String key, boolean autoGenerated)
throws IOException {
Path path = Paths.get("configs", "settings.yml"); // Target the configs/settings.yml
final YamlFile settingsYml = new YamlFile(path.toFile());
DumperOptions yamlOptionssettingsYml =
((SimpleYamlImplementation) settingsYml.getImplementation()).getDumperOptions();
yamlOptionssettingsYml.setSplitLines(false);
settingsYml.loadWithComments();
YamlFileWrapper writer = settingsYml.path(id).set(key);
if (autoGenerated) {
writer.comment("# Automatically Generated Settings (Do Not Edit Directly)");
}
settingsYml.save();
}
public static String generateMachineFingerprint() {
try {
// Get the MAC address
StringBuilder sb = new StringBuilder();
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
Enumeration<NetworkInterface> networks = NetworkInterface.getNetworkInterfaces();
while (networks.hasMoreElements()) {
NetworkInterface net = networks.nextElement();
byte[] mac = net.getHardwareAddress();
if (mac != null) {
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X", mac[i]));
}
break; // Use the first network interface with a MAC address
}
}
} else {
byte[] mac = network.getHardwareAddress();
if (mac != null) {
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X", mac[i]));
}
}
}
// Hash the MAC address for privacy and consistency
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
StringBuilder fingerprint = new StringBuilder();
for (byte b : hash) {
fingerprint.append(String.format("%02x", b));
}
return fingerprint.toString();
} catch (Exception e) {
return "GenericID";
}
}
} }

View File

@ -191,7 +191,6 @@ public class PDFToFile {
Files.deleteIfExists(tempInputFile); Files.deleteIfExists(tempInputFile);
if (tempOutputDir != null) FileUtils.deleteDirectory(tempOutputDir.toFile()); if (tempOutputDir != null) FileUtils.deleteDirectory(tempOutputDir.toFile());
} }
System.out.println("fileBytes=" + fileBytes.length);
return WebResponseUtils.bytesToWebResponse( return WebResponseUtils.bytesToWebResponse(
fileBytes, fileName, MediaType.APPLICATION_OCTET_STREAM); fileBytes, fileName, MediaType.APPLICATION_OCTET_STREAM);
} }

View File

@ -17,6 +17,7 @@ public class RequestUriUtils {
|| requestURI.startsWith(contextPath + "/public/") || requestURI.startsWith(contextPath + "/public/")
|| requestURI.startsWith(contextPath + "/pdfjs/") || requestURI.startsWith(contextPath + "/pdfjs/")
|| requestURI.startsWith(contextPath + "/login") || requestURI.startsWith(contextPath + "/login")
|| requestURI.startsWith(contextPath + "/error")
|| requestURI.endsWith(".svg") || requestURI.endsWith(".svg")
|| requestURI.endsWith(".png") || requestURI.endsWith(".png")
|| requestURI.endsWith(".ico") || requestURI.endsWith(".ico")

View File

@ -6,11 +6,12 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile; import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.model.api.misc.ReplaceAndInvert; import stirling.software.SPDF.model.api.misc.ReplaceAndInvert;
@Data @Data
// @EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public abstract class ReplaceAndInvertColorStrategy extends PDFFile { public abstract class ReplaceAndInvertColorStrategy extends PDFFile {
protected ReplaceAndInvert replaceAndInvert; protected ReplaceAndInvert replaceAndInvert;

View File

@ -27,9 +27,9 @@ server.servlet.context-path=${SYSTEM_ROOTURIPATH:/}
spring.devtools.restart.enabled=true spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true spring.devtools.livereload.enabled=true
spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.encoding=UTF-8
spring.web.resources.mime-mappings.webmanifest=application/manifest+json
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000} spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/ #spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/
@ -41,7 +41,7 @@ spring.datasource.username=sa
spring.datasource.password= spring.datasource.password=
spring.h2.console.enabled=false spring.h2.console.enabled=false
spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=update
server.servlet.session.timeout: 30m
# Change the default URL path for OpenAPI JSON # Change the default URL path for OpenAPI JSON
springdoc.api-docs.path=/v1/api-docs springdoc.api-docs.path=/v1/api-docs
@ -49,3 +49,5 @@ springdoc.api-docs.path=/v1/api-docs
springdoc.swagger-ui.url=/v1/api-docs springdoc.swagger-ui.url=/v1/api-docs
posthog.api.key=phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq
posthog.host=https://eu.i.posthog.com

View File

@ -76,6 +76,7 @@ donate=تبرع
color=لون color=لون
sponsor=راعٍ sponsor=راعٍ
info=معلومات info=معلومات
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=خط الأنابيب:
pipelineOptions.saveButton=تنزيل pipelineOptions.saveButton=تنزيل
pipelineOptions.validateButton=تحقق pipelineOptions.validateButton=تحقق
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=تحويل من PDF
navbar.sections.security=التوقيع والأمان navbar.sections.security=التوقيع والأمان
navbar.sections.advance=متقدم navbar.sections.advance=متقدم
navbar.sections.edit=عرض وتعديل navbar.sections.edit=عرض وتعديل
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=لم يتم العثور على الملف
database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا
database.failedImportFile=فشل استيراد الملف database.failedImportFile=فشل استيراد الملف
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=ضبط حجم/مقياس الصفحة
home.scalePages.desc=تغيير حجم/مقياس الصفحة و/أو محتواها. home.scalePages.desc=تغيير حجم/مقياس الصفحة و/أو محتواها.
scalePages.tags=تغيير الحجم,تعديل,الأبعاد,تكييف scalePages.tags=تغيير الحجم,تعديل,الأبعاد,تكييف
home.pipeline.title=خط الأنابيب (متقدم) home.pipeline.title=خط الأنابيب
home.pipeline.desc=تشغيل إجراءات متعددة على ملفات PDF عن طريق تحديد نصوص خط الأنابيب home.pipeline.desc=تشغيل إجراءات متعددة على ملفات PDF عن طريق تحديد نصوص خط الأنابيب
pipeline.tags=أتمتة,تسلسل,مبرمج,معالجة دفعات pipeline.tags=أتمتة,تسلسل,مبرمج,معالجة دفعات
@ -482,6 +502,11 @@ home.removeImagePdf.title=إزالة الصورة
home.removeImagePdf.desc=إزالة الصورة من PDF لتقليل حجم الملف home.removeImagePdf.desc=إزالة الصورة من PDF لتقليل حجم الملف
removeImagePdf.tags=إزالة الصورة,عمليات الصفحة,الخلفية,جانب الخادم removeImagePdf.tags=إزالة الصورة,عمليات الصفحة,الخلفية,جانب الخادم
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=تم رفض الوصول
login.oauth2InvalidTokenResponse=استجابة الرمز المميز غير صالحة login.oauth2InvalidTokenResponse=استجابة الرمز المميز غير صالحة
login.oauth2InvalidIdToken=رمز الهوية غير صالح login.oauth2InvalidIdToken=رمز الهوية غير صالح
login.userIsDisabled=تم تعطيل المستخدم، تم حظر تسجيل الدخول حاليًا باستخدام اسم المستخدم هذا. يرجى الاتصال بالمسؤول. login.userIsDisabled=تم تعطيل المستخدم، تم حظر تسجيل الدخول حاليًا باستخدام اسم المستخدم هذا. يرجى الاتصال بالمسؤول.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=حجب تلقائي autoRedact.title=حجب تلقائي
@ -1154,6 +1182,8 @@ licenses.license=الترخيص
survey.nav=استطلاع survey.nav=استطلاع
survey.title=استطلاع Stirling-PDF survey.title=استطلاع Stirling-PDF
survey.description=Stirling-PDF لا يحتوي على تتبع لذا نريد أن نسمع من مستخدمينا لتحسين Stirling-PDF! survey.description=Stirling-PDF لا يحتوي على تتبع لذا نريد أن نسمع من مستخدمينا لتحسين Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=يرجى النظر في المشاركة في استطلاعنا! survey.please=يرجى النظر في المشاركة في استطلاعنا!
survey.disabled=(سيتم تعطيل النافذة المنبثقة للاستطلاع في التحديثات التالية ولكنها ستكون متاحة في أسفل الصفحة) survey.disabled=(سيتم تعطيل النافذة المنبثقة للاستطلاع في التحديثات التالية ولكنها ستكون متاحة في أسفل الصفحة)
survey.button=المشاركة في الاستطلاع survey.button=المشاركة في الاستطلاع
@ -1179,3 +1209,17 @@ removeImage.title=إزالة الصورة
removeImage.header=إزالة الصورة removeImage.header=إزالة الصورة
removeImage.removeImage=إزالة الصورة removeImage.removeImage=إزالة الصورة
removeImage.submit=إزالة الصورة removeImage.submit=إزالة الصورة
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Направете дарение
color=Цвят color=Цвят
sponsor=Спонсор sponsor=Спонсор
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Изтегли pipelineOptions.saveButton=Изтегли
pipelineOptions.validateButton=Валидирай pipelineOptions.validateButton=Валидирай
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Преобразуване от PDF
navbar.sections.security=Подписване и сигурност navbar.sections.security=Подписване и сигурност
navbar.sections.advance=Разширено navbar.sections.advance=Разширено
navbar.sections.edit=Преглед и редактиране navbar.sections.edit=Преглед и редактиране
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Отказан достъп
login.oauth2InvalidTokenResponse=Невалиден отговор на токена login.oauth2InvalidTokenResponse=Невалиден отговор на токена
login.oauth2InvalidIdToken=Невалиден токен за идентификатор login.oauth2InvalidIdToken=Невалиден токен за идентификатор
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Автоматично редактиране autoRedact.title=Автоматично редактиране
@ -1154,6 +1182,8 @@ licenses.license=Лиценз
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of page and/or its contents. home.scalePages.desc=Change the size/scale of page and/or its contents.
scalePages.tags=resize,modify,dimension,adapt scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=Pipeline (Advanced) home.pipeline.title=Pipeline
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
pipeline.tags=automate,sequence,scripted,batch-process pipeline.tags=automate,sequence,scripted,batch-process
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Přispějte
color=Barva color=Barva
sponsor=Sponzor sponsor=Sponzor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Stáhnout pipelineOptions.saveButton=Stáhnout
pipelineOptions.validateButton=Ověřit pipelineOptions.validateButton=Ověřit
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Převést z PDF
navbar.sections.security=Podpis a Bezpečnost navbar.sections.security=Podpis a Bezpečnost
navbar.sections.advance=Pokročilé navbar.sections.advance=Pokročilé
navbar.sections.edit=Prohlédnout a Upravit navbar.sections.edit=Prohlédnout a Upravit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Upravit velikost/škálu stránky
home.scalePages.desc=Změnit velikost/škálu stránky a/nebo její obsah. home.scalePages.desc=Změnit velikost/škálu stránky a/nebo její obsah.
scalePages.tags=změnit velikost,upravit,rozměr,přizpůsobit scalePages.tags=změnit velikost,upravit,rozměr,přizpůsobit
home.pipeline.title=Potrubí (Pokročilé) home.pipeline.title=Potrubí
home.pipeline.desc=Spustit více akcí na PDF s definicí skriptů potrubí home.pipeline.desc=Spustit více akcí na PDF s definicí skriptů potrubí
pipeline.tags=automatizovat,sekvence,skriptované,dávkové zpracování pipeline.tags=automatizovat,sekvence,skriptované,dávkové zpracování
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@ -1154,6 +1182,8 @@ licenses.license=Licence
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donér
color=Farve color=Farve
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validér pipelineOptions.validateButton=Validér
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Konvertér fra PDF
navbar.sections.security=Signér & Sikkerhed navbar.sections.security=Signér & Sikkerhed
navbar.sections.advance=Avanceret navbar.sections.advance=Avanceret
navbar.sections.edit=Vis & Redigér navbar.sections.edit=Vis & Redigér
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Fil ikke fundet
database.fileNullOrEmpty=Fil må ikke være null eller tom database.fileNullOrEmpty=Fil må ikke være null eller tom
database.failedImportFile=Kunne ikke importere fil database.failedImportFile=Kunne ikke importere fil
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Fjern billede
home.removeImagePdf.desc=Fjern billede fra PDF for at reducere filstørrelse home.removeImagePdf.desc=Fjern billede fra PDF for at reducere filstørrelse
removeImagePdf.tags=Fjern Billede,Sideoperationer,Back end,server side removeImagePdf.tags=Fjern Billede,Sideoperationer,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Adgang Nægtet
login.oauth2InvalidTokenResponse=Ugyldigt Token Svar login.oauth2InvalidTokenResponse=Ugyldigt Token Svar
login.oauth2InvalidIdToken=Ugyldigt Id Token login.oauth2InvalidIdToken=Ugyldigt Id Token
login.userIsDisabled=Bruger er deaktiveret, login er i øjeblikket blokeret med dette brugernavn. Kontakt venligst administratoren. login.userIsDisabled=Bruger er deaktiveret, login er i øjeblikket blokeret med dette brugernavn. Kontakt venligst administratoren.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Rediger autoRedact.title=Auto Rediger
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Undersøgelse survey.nav=Undersøgelse
survey.title=Stirling-PDF Undersøgelse survey.title=Stirling-PDF Undersøgelse
survey.description=Stirling-PDF har ingen sporing, så vi vil gerne høre fra vores brugere for at forbedre Stirling-PDF! survey.description=Stirling-PDF har ingen sporing, så vi vil gerne høre fra vores brugere for at forbedre Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Overvej venligst at deltage i vores undersøgelse! survey.please=Overvej venligst at deltage i vores undersøgelse!
survey.disabled=(Undersøgelsespop-up vil blive deaktiveret i følgende opdateringer, men vil være tilgængelig i bunden af siden) survey.disabled=(Undersøgelsespop-up vil blive deaktiveret i følgende opdateringer, men vil være tilgængelig i bunden af siden)
survey.button=Tag Undersøgelsen survey.button=Tag Undersøgelsen
@ -1179,3 +1209,17 @@ removeImage.title=Fjern billede
removeImage.header=Fjern billede removeImage.header=Fjern billede
removeImage.removeImage=Fjern billede removeImage.removeImage=Fjern billede
removeImage.submit=Fjern removeImage.submit=Fjern
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Spenden
color=Farbe color=Farbe
sponsor=Sponsor sponsor=Sponsor
info=Informationen info=Informationen
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Herunterladen pipelineOptions.saveButton=Herunterladen
pipelineOptions.validateButton=Validieren pipelineOptions.validateButton=Validieren
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Konvertieren von PDF
navbar.sections.security=Zeichen und Sicherheit navbar.sections.security=Zeichen und Sicherheit
navbar.sections.advance=Fortschrittlich navbar.sections.advance=Fortschrittlich
navbar.sections.edit=Anzeigen und Bearbeiten navbar.sections.edit=Anzeigen und Bearbeiten
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Datei nicht gefunden
database.fileNullOrEmpty=Datei darf nicht null oder leer sein database.fileNullOrEmpty=Datei darf nicht null oder leer sein
database.failedImportFile=Dateiimport fehlgeschlagen database.failedImportFile=Dateiimport fehlgeschlagen
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Seitengröße/Skalierung anpassen
home.scalePages.desc=Größe/Skalierung der Seite und/oder des Inhalts ändern home.scalePages.desc=Größe/Skalierung der Seite und/oder des Inhalts ändern
scalePages.tags=größe ändern,ändern,dimensionieren,anpassen scalePages.tags=größe ändern,ändern,dimensionieren,anpassen
home.pipeline.title=Pipeline (Fortgeschritten) home.pipeline.title=Pipeline
home.pipeline.desc=Mehrere Aktionen auf ein PDF anwenden, definiert durch ein Pipeline Skript home.pipeline.desc=Mehrere Aktionen auf ein PDF anwenden, definiert durch ein Pipeline Skript
pipeline.tags=automatisieren,sequenzieren,skriptgesteuert,batch prozess pipeline.tags=automatisieren,sequenzieren,skriptgesteuert,batch prozess
@ -482,6 +502,11 @@ home.removeImagePdf.title=Bild entfernen
home.removeImagePdf.desc=Bild aus PDF entfernen, um die Dateigröße zu verringern home.removeImagePdf.desc=Bild aus PDF entfernen, um die Dateigröße zu verringern
removeImagePdf.tags=bild entfernen,seitenoperationen,back end,server side removeImagePdf.tags=bild entfernen,seitenoperationen,back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Zugriff abgelehnt
login.oauth2InvalidTokenResponse=Ungültige Token-Antwort login.oauth2InvalidTokenResponse=Ungültige Token-Antwort
login.oauth2InvalidIdToken=Ungültiges ID-Token login.oauth2InvalidIdToken=Ungültiges ID-Token
login.userIsDisabled=Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benutzernamen derzeit gesperrt. Bitte wenden Sie sich an den Administrator. login.userIsDisabled=Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benutzernamen derzeit gesperrt. Bitte wenden Sie sich an den Administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatisch zensieren/schwärzen autoRedact.title=Automatisch zensieren/schwärzen
@ -1154,6 +1182,8 @@ licenses.license=Lizenz
survey.nav=Umfrage survey.nav=Umfrage
survey.title=Stirling-PDF-Umfrage survey.title=Stirling-PDF-Umfrage
survey.description=Stirling-PDF hat kein Tracking, daher möchten wir von unseren Benutzern hören, wie wir Stirling-PDF verbessern können! survey.description=Stirling-PDF hat kein Tracking, daher möchten wir von unseren Benutzern hören, wie wir Stirling-PDF verbessern können!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Bitte nehmen Sie an unserer Umfrage teil! survey.please=Bitte nehmen Sie an unserer Umfrage teil!
survey.disabled=(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.) survey.disabled=(Das Umfrage-Popup wird in folgenden Updates deaktiviert, ist aber am Fuß der Seite verfügbar.)
survey.button=Umfrage durchführen survey.button=Umfrage durchführen
@ -1179,3 +1209,17 @@ removeImage.title=Bild entfernen
removeImage.header=Bild entfernen removeImage.header=Bild entfernen
removeImage.removeImage=Bild entfernen removeImage.removeImage=Bild entfernen
removeImage.submit=Bild entfernen removeImage.submit=Bild entfernen
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Δωρισε
color=Χρώμα color=Χρώμα
sponsor=οστηρικτής sponsor=οστηρικτής
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Λήψη pipelineOptions.saveButton=Λήψη
pipelineOptions.validateButton=Επικυρώνω pipelineOptions.validateButton=Επικυρώνω
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Αυτόματο Μαύρισμα Κειμένου autoRedact.title=Αυτόματο Μαύρισμα Κειμένου
@ -1154,6 +1182,8 @@ licenses.license=Άδεια
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed to import file database.failedImportFile=Failed to import file
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Adjust page size/scale
home.scalePages.desc=Change the size/scale of a page and/or its contents. home.scalePages.desc=Change the size/scale of a page and/or its contents.
scalePages.tags=resize,modify,dimension,adapt scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=Pipeline (Advanced) home.pipeline.title=Pipeline
home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts home.pipeline.desc=Run multiple actions on PDFs by defining pipeline scripts
pipeline.tags=automate,sequence,scripted,batch-process pipeline.tags=automate,sequence,scripted,batch-process
@ -482,10 +502,15 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Advanced Colour options
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
home.replaceColorPdf.title=Replace and Invert Color home.replaceColorPdf.title=Advanced Colour options
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side replaceColorPdf.tags=Replace Color,Page operations,Back end,server side
replace-color.selectText.1=Replace or Invert color Options replace-color.selectText.1=Replace or Invert color Options
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@ -1154,7 +1182,9 @@ licenses.license=Licence
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.please=Please consider taking our survey! survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey to have input on the future of Stirling-PDF!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
survey.dontShowAgain=Don't show again survey.dontShowAgain=Don't show again
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donar
color=Color color=Color
sponsor=Patrocinador sponsor=Patrocinador
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Canalización:
pipelineOptions.saveButton=Descargar pipelineOptions.saveButton=Descargar
pipelineOptions.validateButton=Validar pipelineOptions.validateButton=Validar
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convertir desde PDF
navbar.sections.security=Señalización y seguridad navbar.sections.security=Señalización y seguridad
navbar.sections.advance=Avanzado navbar.sections.advance=Avanzado
navbar.sections.edit=Ver y Editar navbar.sections.edit=Ver y Editar
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Archivo no encontrado
database.fileNullOrEmpty=El archivo no debe ser nulo o vacío. database.fileNullOrEmpty=El archivo no debe ser nulo o vacío.
database.failedImportFile=Archivo de importación fallido database.failedImportFile=Archivo de importación fallido
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Escalar/ajustar tamaño de página
home.scalePages.desc=Escalar/cambiar el tamaño de una pagina y/o su contenido home.scalePages.desc=Escalar/cambiar el tamaño de una pagina y/o su contenido
scalePages.tags=cambiar tamaño,modificar,dimensionar,adaptar scalePages.tags=cambiar tamaño,modificar,dimensionar,adaptar
home.pipeline.title=Secuencia (Avanzado) home.pipeline.title=Secuencia
home.pipeline.desc=Ejecutar varias tareas a PDFs definiendo una secuencia de comandos home.pipeline.desc=Ejecutar varias tareas a PDFs definiendo una secuencia de comandos
pipeline.tags=automatizar,secuencia,con script,proceso por lotes pipeline.tags=automatizar,secuencia,con script,proceso por lotes
@ -482,6 +502,11 @@ home.removeImagePdf.title=Eliminar imagen
home.removeImagePdf.desc=Eliminar imagen del PDF> para reducir el tamaño de archivo home.removeImagePdf.desc=Eliminar imagen del PDF> para reducir el tamaño de archivo
removeImagePdf.tags=Eliminar imagen,Operaciones de página,Back end,lado del servidor removeImagePdf.tags=Eliminar imagen,Operaciones de página,Back end,lado del servidor
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Acceso denegado
login.oauth2InvalidTokenResponse=Respuesta de token no válida login.oauth2InvalidTokenResponse=Respuesta de token no válida
login.oauth2InvalidIdToken=Token de identificación no válido login.oauth2InvalidIdToken=Token de identificación no válido
login.userIsDisabled=El usuario está desactivado, actualmente el acceso está bloqueado para ese nombre de usuario. Por favor, póngase en contacto con el administrador. login.userIsDisabled=El usuario está desactivado, actualmente el acceso está bloqueado para ese nombre de usuario. Por favor, póngase en contacto con el administrador.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redactar autoRedact.title=Auto Redactar
@ -1154,6 +1182,8 @@ licenses.license=Licencia
survey.nav=Encuesta survey.nav=Encuesta
survey.title=Encuesta Stirling-PDF survey.title=Encuesta Stirling-PDF
survey.description=Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF. survey.description=Stirling-PDF no tiene seguimiento, por lo que queremos escuchar a nuestros usuarios para mejorar Stirling-PDF.
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=¡Considere realizar nuestra encuesta! survey.please=¡Considere realizar nuestra encuesta!
survey.disabled=(La ventana emergente de la encuesta se desactivará en las siguientes actualizaciones, pero estará disponible al pie de la página.) survey.disabled=(La ventana emergente de la encuesta se desactivará en las siguientes actualizaciones, pero estará disponible al pie de la página.)
survey.button=Realizar encuesta survey.button=Realizar encuesta
@ -1179,3 +1209,17 @@ removeImage.title=Eliminar imagen
removeImage.header=Eliminar imagen removeImage.header=Eliminar imagen
removeImage.removeImage=Eliminar imagen removeImage.removeImage=Eliminar imagen
removeImage.submit=Eliminar imagen removeImage.submit=Eliminar imagen
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Idatzi autoRedact.title=Auto Idatzi
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Faire un don
color=Couleur color=Couleur
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Télécharger pipelineOptions.saveButton=Télécharger
pipelineOptions.validateButton=Valider pipelineOptions.validateButton=Valider
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convertir depuis PDF
navbar.sections.security=Signature et sécurité navbar.sections.security=Signature et sécurité
navbar.sections.advance=Mode avancé navbar.sections.advance=Mode avancé
navbar.sections.edit=Voir et modifier navbar.sections.edit=Voir et modifier
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Ajuster léchelle ou la taille
home.scalePages.desc=Modifiez la taille ou léchelle dune page et/ou de son contenu. home.scalePages.desc=Modifiez la taille ou léchelle dune page et/ou de son contenu.
scalePages.tags=ajuster,redimensionner,resize,modify,dimension,adapt scalePages.tags=ajuster,redimensionner,resize,modify,dimension,adapt
home.pipeline.title=Pipeline (avancé) home.pipeline.title=Pipeline
home.pipeline.desc=Exécutez plusieurs actions sur les PDF en définissant des scripts de pipeline. home.pipeline.desc=Exécutez plusieurs actions sur les PDF en définissant des scripts de pipeline.
pipeline.tags=automatiser,séquencer,automate,sequence,scripted,batch-process pipeline.tags=automatiser,séquencer,automate,sequence,scripted,batch-process
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Accès refusé
login.oauth2InvalidTokenResponse=Réponse contenant le jeton est invalide login.oauth2InvalidTokenResponse=Réponse contenant le jeton est invalide
login.oauth2InvalidIdToken=Jeton d'identification invalide login.oauth2InvalidIdToken=Jeton d'identification invalide
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Caviarder automatiquement autoRedact.title=Caviarder automatiquement
@ -1154,6 +1182,8 @@ licenses.license=Licence
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Síntiúis
color=Dath color=Dath
sponsor=Urraitheoir sponsor=Urraitheoir
info=Eolas info=Eolas
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Píblíne:
pipelineOptions.saveButton=Íosluchtaigh pipelineOptions.saveButton=Íosluchtaigh
pipelineOptions.validateButton=Bailíochtaigh pipelineOptions.validateButton=Bailíochtaigh
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Tiontaigh ó PDF
navbar.sections.security=Comhartha & Slándáil navbar.sections.security=Comhartha & Slándáil
navbar.sections.advance=Casta navbar.sections.advance=Casta
navbar.sections.edit=Féach ar & Cuir in Eagar navbar.sections.edit=Féach ar & Cuir in Eagar
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Comhad gan aimsiú
database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh database.fileNullOrEmpty=Níor cheart go mbeadh an comhad ar neamhní nó folamh
database.failedImportFile=Theip ar iompórtáil an chomhaid database.failedImportFile=Theip ar iompórtáil an chomhaid
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Rochtain Diúltaithe
login.oauth2InvalidTokenResponse=Freagra Comhartha Neamhbhailí login.oauth2InvalidTokenResponse=Freagra Comhartha Neamhbhailí
login.oauth2InvalidIdToken=Comhartha Aitheantais Neamhbhailí login.oauth2InvalidIdToken=Comhartha Aitheantais Neamhbhailí
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Redact autoRedact.title=Auto Redact
@ -1154,6 +1182,8 @@ licenses.license=Ceadúnas
survey.nav=Suirbhé survey.nav=Suirbhé
survey.title=Suirbhé Stirling-PDF survey.title=Suirbhé Stirling-PDF
survey.description=Níl aon rian ar Stirling-PDF agus mar sin ba mhaith linn cloisteáil ónár n-úsáideoirí chun feabhas a chur ar Stirling-PDF! survey.description=Níl aon rian ar Stirling-PDF agus mar sin ba mhaith linn cloisteáil ónár n-úsáideoirí chun feabhas a chur ar Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Smaoinigh ar ár suirbhé a dhéanamh le do thoil! survey.please=Smaoinigh ar ár suirbhé a dhéanamh le do thoil!
survey.disabled=(Díchumasófar aníos an tsuirbhé sna nuashonruithe seo a leanas ach beidh siad ar fáil ag bun an leathanaigh) survey.disabled=(Díchumasófar aníos an tsuirbhé sna nuashonruithe seo a leanas ach beidh siad ar fáil ag bun an leathanaigh)
survey.button=Tóg Suirbhé survey.button=Tóg Suirbhé
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=पृष्ठ page=पृष्ठ
pages=पृष्ठों pages=पृष्ठों
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=पीडीएफ से कनवर्ट कर
navbar.sections.security=संकेत और सुरक्षा navbar.sections.security=संकेत और सुरक्षा
navbar.sections.advance=उन्नत navbar.sections.advance=उन्नत
navbar.sections.edit=देखें और संपादित करें navbar.sections.edit=देखें और संपादित करें
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=स्वत: गोपनीयकरण autoRedact.title=स्वत: गोपनीयकरण
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Doniraj
color=Boja color=Boja
sponsor=Sponzor sponsor=Sponzor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Preuzmi datoteku pipelineOptions.saveButton=Preuzmi datoteku
pipelineOptions.validateButton=Potvrdi pipelineOptions.validateButton=Potvrdi
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Pretvori iz PDF
navbar.sections.security=Potpis & sigurnost navbar.sections.security=Potpis & sigurnost
navbar.sections.advance=Napredno navbar.sections.advance=Napredno
navbar.sections.edit=Pregled & Uređivanje navbar.sections.edit=Pregled & Uređivanje
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Prilagodite veličinu/razmjer stranice
home.scalePages.desc=Promijenite veličinu/razmjer stranice i/ili njezin sadržaj. home.scalePages.desc=Promijenite veličinu/razmjer stranice i/ili njezin sadržaj.
scalePages.tags=izmjena,modifikacija,dimenzija,adaptacija scalePages.tags=izmjena,modifikacija,dimenzija,adaptacija
home.pipeline.title=Pipeline (Advanced) home.pipeline.title=Pipeline
home.pipeline.desc=Izvršite više radnji na PDF-ovima definiranjem skripti u pipeline-u home.pipeline.desc=Izvršite više radnji na PDF-ovima definiranjem skripti u pipeline-u
pipeline.tags=automatizacija,sekvenciranje,skriptirano,batch-process pipeline.tags=automatizacija,sekvenciranje,skriptirano,batch-process
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Pristup odbijen
login.oauth2InvalidTokenResponse=Nevažeći odgovor tokena login.oauth2InvalidTokenResponse=Nevažeći odgovor tokena
login.oauth2InvalidIdToken=Nevažeći ID token login.oauth2InvalidIdToken=Nevažeći ID token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatsko uređivanje autoRedact.title=Automatsko uređivanje
@ -1154,6 +1182,8 @@ licenses.license=Licenca
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Érzékeny tartalom eltávolítása autoRedact.title=Érzékeny tartalom eltávolítása
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate pipelineOptions.validateButton=Validate
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Menyesuaikan ukuran/skala halaman
home.scalePages.desc=Mengubah ukuran/skala halaman dan/atau isinya. home.scalePages.desc=Mengubah ukuran/skala halaman dan/atau isinya.
scalePages.tags=mengubah ukuran, memodifikasi, dimensi, mengadaptasi scalePages.tags=mengubah ukuran, memodifikasi, dimensi, mengadaptasi
home.pipeline.title=Pipeline (Lanjutan) home.pipeline.title=Pipeline
home.pipeline.desc=Menjalankan beberapa tindakan pada PDF dengan mendefinisikan skrip pipeline home.pipeline.desc=Menjalankan beberapa tindakan pada PDF dengan mendefinisikan skrip pipeline
pipeline.tags=mengotomatiskan, mengurutkan, menulis, proses batch pipeline.tags=mengotomatiskan, mengurutkan, menulis, proses batch
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Redaksional Otomatis autoRedact.title=Redaksional Otomatis
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donazione
color=Colore color=Colore
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Convalidare pipelineOptions.validateButton=Convalidare
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Converti da PDF
navbar.sections.security=Firma & Sicurezza navbar.sections.security=Firma & Sicurezza
navbar.sections.advance=Avanzate navbar.sections.advance=Avanzate
navbar.sections.edit=Visualizza & Modifica navbar.sections.edit=Visualizza & Modifica
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File non trovato
database.fileNullOrEmpty=Il file non deve essere nullo o vuoto database.fileNullOrEmpty=Il file non deve essere nullo o vuoto
database.failedImportFile=Importazione file non riuscita database.failedImportFile=Importazione file non riuscita
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Regola le dimensioni/scala della pagina
home.scalePages.desc=Modificare le dimensioni/scala della pagina e/o dei suoi contenuti. home.scalePages.desc=Modificare le dimensioni/scala della pagina e/o dei suoi contenuti.
scalePages.tags=ridimensionare,modificare,dimensionare,adattare scalePages.tags=ridimensionare,modificare,dimensionare,adattare
home.pipeline.title=Pipeline (avanzato) home.pipeline.title=Pipeline
home.pipeline.desc=Esegui più azioni sui PDF definendo script di pipeline home.pipeline.desc=Esegui più azioni sui PDF definendo script di pipeline
pipeline.tags=automatizzare,sequenziare,scriptare,elaborare in batch pipeline.tags=automatizzare,sequenziare,scriptare,elaborare in batch
@ -482,6 +502,11 @@ home.removeImagePdf.title=Rimuovi immagine
home.removeImagePdf.desc=Rimuovi le immagini dal PDF per ridurre la dimensione del file home.removeImagePdf.desc=Rimuovi le immagini dal PDF per ridurre la dimensione del file
removeImagePdf.tags=Rimuovi immagine,operazioni sulla pagina,back-end,lato server removeImagePdf.tags=Rimuovi immagine,operazioni sulla pagina,back-end,lato server
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Sostituisci-Inverti-Colore replace-color.title=Sostituisci-Inverti-Colore
replace-color.header=Sostituisci-Inverti colore PDF replace-color.header=Sostituisci-Inverti colore PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Accesso negato
login.oauth2InvalidTokenResponse=Risposta token non valida login.oauth2InvalidTokenResponse=Risposta token non valida
login.oauth2InvalidIdToken=Id Token non valido login.oauth2InvalidIdToken=Id Token non valido
login.userIsDisabled=L'utente è disattivato, l'accesso è attualmente bloccato con questo nome utente. Si prega di contattare l'amministratore. login.userIsDisabled=L'utente è disattivato, l'accesso è attualmente bloccato con questo nome utente. Si prega di contattare l'amministratore.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Redazione automatica autoRedact.title=Redazione automatica
@ -1154,6 +1182,8 @@ licenses.license=Licenza
survey.nav=Sondaggio survey.nav=Sondaggio
survey.title=Sondaggio Stirling-PDF survey.title=Sondaggio Stirling-PDF
survey.description=Stirling-PDF non fa tracciamento, quindi vogliamo sentire i nostri utenti per migliorare Stirling-PDF! survey.description=Stirling-PDF non fa tracciamento, quindi vogliamo sentire i nostri utenti per migliorare Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Ti invitiamo a prendere in considerazione la possibilità di partecipare al nostro sondaggio! survey.please=Ti invitiamo a prendere in considerazione la possibilità di partecipare al nostro sondaggio!
survey.disabled=(Il popup del sondaggio verrà disabilitato nei prossimi aggiornamenti ma sarà disponibile a piè di pagina) survey.disabled=(Il popup del sondaggio verrà disabilitato nei prossimi aggiornamenti ma sarà disponibile a piè di pagina)
survey.button=Partecipa al sondaggio survey.button=Partecipa al sondaggio
@ -1179,3 +1209,17 @@ removeImage.title=Rimuovere immagine
removeImage.header=Rimuovi immagine removeImage.header=Rimuovi immagine
removeImage.removeImage=Rimuovi immagine removeImage.removeImage=Rimuovi immagine
removeImage.submit=Rimuovi immagine removeImage.submit=Rimuovi immagine
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=寄付する
color= color=
sponsor=スポンサー sponsor=スポンサー
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=パイプライン:
pipelineOptions.saveButton=ダウンロード pipelineOptions.saveButton=ダウンロード
pipelineOptions.validateButton=検証 pipelineOptions.validateButton=検証
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=PDFから変換
navbar.sections.security=署名とセキュリティ navbar.sections.security=署名とセキュリティ
navbar.sections.advance=アドバンスド navbar.sections.advance=アドバンスド
navbar.sections.edit=閲覧と編集 navbar.sections.edit=閲覧と編集
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=ファイルが見つかりません
database.fileNullOrEmpty=ファイルは null または空であってはなりません database.fileNullOrEmpty=ファイルは null または空であってはなりません
database.failedImportFile=ファイルのインポートに失敗 database.failedImportFile=ファイルのインポートに失敗
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=ページの縮尺の調整
home.scalePages.desc=ページやコンテンツの縮尺を変更します。 home.scalePages.desc=ページやコンテンツの縮尺を変更します。
scalePages.tags=resize,modify,dimension,adapt scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=パイプライン (高度) home.pipeline.title=パイプライン
home.pipeline.desc=パイプラインスクリプトを定義してPDF上で複数のアクションを実行します。 home.pipeline.desc=パイプラインスクリプトを定義してPDF上で複数のアクションを実行します。
pipeline.tags=automate,sequence,scripted,batch-process pipeline.tags=automate,sequence,scripted,batch-process
@ -482,6 +502,11 @@ home.removeImagePdf.title=画像の削除
home.removeImagePdf.desc=PDFから画像を削除してファイルサイズを小さくします home.removeImagePdf.desc=PDFから画像を削除してファイルサイズを小さくします
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=アクセス拒否
login.oauth2InvalidTokenResponse=無効なトークン応答 login.oauth2InvalidTokenResponse=無効なトークン応答
login.oauth2InvalidIdToken=無効なIDトークン login.oauth2InvalidIdToken=無効なIDトークン
login.userIsDisabled=ユーザーは非アクティブ化されており、現在このユーザー名でのログインはブロックされています。管理者に連絡してください。 login.userIsDisabled=ユーザーは非アクティブ化されており、現在このユーザー名でのログインはブロックされています。管理者に連絡してください。
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=自動塗りつぶし autoRedact.title=自動塗りつぶし
@ -1154,6 +1182,8 @@ licenses.license=ライセンス
survey.nav=アンケート survey.nav=アンケート
survey.title=Stirling-PDFのアンケート survey.title=Stirling-PDFのアンケート
survey.description=Stirling-PDFには追跡機能がないため、Stirling-PDFをより良くするために皆様の意見を聞かせてください survey.description=Stirling-PDFには追跡機能がないため、Stirling-PDFをより良くするために皆様の意見を聞かせてください
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=アンケートにご協力ください! survey.please=アンケートにご協力ください!
survey.disabled=(アンケートのポップアップは、次の更新では無効になりますが、ページの下部に表示されます。) survey.disabled=(アンケートのポップアップは、次の更新では無効になりますが、ページの下部に表示されます。)
survey.button=アンケートに答える survey.button=アンケートに答える
@ -1179,3 +1209,17 @@ removeImage.title=画像の削除
removeImage.header=画像の削除 removeImage.header=画像の削除
removeImage.removeImage=画像の削除 removeImage.removeImage=画像の削除
removeImage.submit=画像を削除 removeImage.submit=画像を削除
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=기부하기
color=색상 color=색상
sponsor=스폰서 sponsor=스폰서
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=파이프라인:
pipelineOptions.saveButton=다운로드 pipelineOptions.saveButton=다운로드
pipelineOptions.validateButton=확인 pipelineOptions.validateButton=확인
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=자동 검열 autoRedact.title=자동 검열
@ -1154,6 +1182,8 @@ licenses.license=라이센스
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Doneer
color=Kleur color=Kleur
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pijplijn:
pipelineOptions.saveButton=Downloaden pipelineOptions.saveButton=Downloaden
pipelineOptions.validateButton=Valideren pipelineOptions.validateButton=Valideren
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Converteren van PDF
navbar.sections.security=Ondertekenen & beveiliging navbar.sections.security=Ondertekenen & beveiliging
navbar.sections.advance=Geavanceerd navbar.sections.advance=Geavanceerd
navbar.sections.edit=Bekijken & wijzigen navbar.sections.edit=Bekijken & wijzigen
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Aanpassen paginaformaat/schaal
home.scalePages.desc=Wijzig de grootte/schaal van een pagina en/of de inhoud ervan. home.scalePages.desc=Wijzig de grootte/schaal van een pagina en/of de inhoud ervan.
scalePages.tags=resize,aanpassen,dimensie,aanpassen scalePages.tags=resize,aanpassen,dimensie,aanpassen
home.pipeline.title=Pijplijn (Geavanceerd) home.pipeline.title=Pijplijn
home.pipeline.desc=Voer meerdere acties uit op PDF's door pipelinescripts te definiëren home.pipeline.desc=Voer meerdere acties uit op PDF's door pipelinescripts te definiëren
pipeline.tags=automatiseren,volgorde,gescrript,batch-verwerking pipeline.tags=automatiseren,volgorde,gescrript,batch-verwerking
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Toegang geweigerd
login.oauth2InvalidTokenResponse=Ongeldige tokenreactie login.oauth2InvalidTokenResponse=Ongeldige tokenreactie
login.oauth2InvalidIdToken=Ongeldige ID token login.oauth2InvalidIdToken=Ongeldige ID token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatisch censureren autoRedact.title=Automatisch censureren
@ -1154,6 +1182,8 @@ licenses.license=Licentie
survey.nav=Enquête survey.nav=Enquête
survey.title=Stirling-PDF Enquête survey.title=Stirling-PDF Enquête
survey.description=Stirling-PDF heeft geen tracking, dus we willen van onze gebruikers horen om Stirling-PDF te verbeteren. survey.description=Stirling-PDF heeft geen tracking, dus we willen van onze gebruikers horen om Stirling-PDF te verbeteren.
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Overweeg alstublieft om onze enquête in te vullen! survey.please=Overweeg alstublieft om onze enquête in te vullen!
survey.disabled=(Enquête popup wordt in een toekomstige update weggehaald, maar is beschikbaar aan de onderkant van de pagina.) survey.disabled=(Enquête popup wordt in een toekomstige update weggehaald, maar is beschikbaar aan de onderkant van de pagina.)
survey.button=Vul enquête in. survey.button=Vul enquête in.
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Doner
color=Farge color=Farge
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Last ned pipelineOptions.saveButton=Last ned
pipelineOptions.validateButton=Valider pipelineOptions.validateButton=Valider
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Konverter fra PDF
navbar.sections.security=Signer & Sikkerhet navbar.sections.security=Signer & Sikkerhet
navbar.sections.advance=Avansert navbar.sections.advance=Avansert
navbar.sections.edit=Vis & Rediger navbar.sections.edit=Vis & Rediger
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Fil ikke funnet
database.fileNullOrEmpty=Fil må ikke være tom eller null database.fileNullOrEmpty=Fil må ikke være tom eller null
database.failedImportFile=Import av fil mislyktes database.failedImportFile=Import av fil mislyktes
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Tilgang nektet
login.oauth2InvalidTokenResponse=Ugyldig tokenrespons login.oauth2InvalidTokenResponse=Ugyldig tokenrespons
login.oauth2InvalidIdToken=Ugyldig Id Token login.oauth2InvalidIdToken=Ugyldig Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatisk Sensurering autoRedact.title=Automatisk Sensurering
@ -1154,6 +1182,8 @@ licenses.license=Lisens
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Podaruj
color=kolor color=kolor
sponsor=sponsor sponsor=sponsor
info=informacje info=informacje
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Automatyzacja
pipelineOptions.saveButton=Pobierz pipelineOptions.saveButton=Pobierz
pipelineOptions.validateButton=Waliduj pipelineOptions.validateButton=Waliduj
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Przetwórz z PDF
navbar.sections.security=Podpis i bezpieczeństwo navbar.sections.security=Podpis i bezpieczeństwo
navbar.sections.advance=Zaawansowane navbar.sections.advance=Zaawansowane
navbar.sections.edit=Podgląd i edycja navbar.sections.edit=Podgląd i edycja
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Plik nie znaleziony
database.fileNullOrEmpty=Plik nie może być pusty database.fileNullOrEmpty=Plik nie może być pusty
database.failedImportFile=Nie udało się zaimportować pliku database.failedImportFile=Nie udało się zaimportować pliku
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Dopasuj rozmiar stron
home.scalePages.desc=Dopasuj rozmiar stron wybranego dokumentu PDF home.scalePages.desc=Dopasuj rozmiar stron wybranego dokumentu PDF
scalePages.tags=resize,modify,dimension,adapt scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=Automatyzacja (Zaawansowane) home.pipeline.title=Automatyzacja
home.pipeline.desc=Wykonaj wiele akcji na dokumentach PDF, tworząc automatyzację home.pipeline.desc=Wykonaj wiele akcji na dokumentach PDF, tworząc automatyzację
pipeline.tags=automate,sequence,scripted,batch-process pipeline.tags=automate,sequence,scripted,batch-process
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Brak dostępu
login.oauth2InvalidTokenResponse=Nieprawidłowa odpowiedź na token login.oauth2InvalidTokenResponse=Nieprawidłowa odpowiedź na token
login.oauth2InvalidIdToken=Nieprawidłowa wartość tokenu login.oauth2InvalidIdToken=Nieprawidłowa wartość tokenu
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatyczne zaciemnienie autoRedact.title=Automatyczne zaciemnienie
@ -1154,6 +1182,8 @@ licenses.license=Licencja
survey.nav=Ankieta survey.nav=Ankieta
survey.title=Ankieta Stirling-PDF survey.title=Ankieta Stirling-PDF
survey.description=Stirling-PDF nie śledzi swoich użytkowników, więc chciałby poznać opinie swoich użytkowników! survey.description=Stirling-PDF nie śledzi swoich użytkowników, więc chciałby poznać opinie swoich użytkowników!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Wypełnij proszę ankietę dla nas! survey.please=Wypełnij proszę ankietę dla nas!
survey.disabled=(Blokada wyskakującego okienka z ankieta zostanie dodane w następnych aktualizacjach, ale będzie dostępna na dole strony) survey.disabled=(Blokada wyskakującego okienka z ankieta zostanie dodane w następnych aktualizacjach, ale będzie dostępna na dole strony)
survey.button=Wypełnij ankietę survey.button=Wypełnij ankietę
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Doar
color=Cor color=Cor
sponsor=Patrocine sponsor=Patrocine
info=Informações info=Informações
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Baixar pipelineOptions.saveButton=Baixar
pipelineOptions.validateButton=Validar pipelineOptions.validateButton=Validar
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Converter de PDF
navbar.sections.security=Assinatura & Segurança navbar.sections.security=Assinatura & Segurança
navbar.sections.advance=Avançado navbar.sections.advance=Avançado
navbar.sections.edit=Visualizar & editar navbar.sections.edit=Visualizar & editar
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Arquivo não encontrado
database.fileNullOrEmpty=O arquivo não estar nulo ou vazio database.fileNullOrEmpty=O arquivo não estar nulo ou vazio
database.failedImportFile=Falha ao importar arquivo database.failedImportFile=Falha ao importar arquivo
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Ajustar Tamanho/Escala de Página
home.scalePages.desc=Alterar o tamanho/escala da página e/ou seu conteúdo. home.scalePages.desc=Alterar o tamanho/escala da página e/ou seu conteúdo.
scalePages.tags=redimensionar,modificar,dimensão,adaptar scalePages.tags=redimensionar,modificar,dimensão,adaptar
home.pipeline.title=Pipeline (Avançado) home.pipeline.title=Pipeline
home.pipeline.desc=Executar várias ações em PDFs definindo scripts de pipeline home.pipeline.desc=Executar várias ações em PDFs definindo scripts de pipeline
pipeline.tags=automatizar,sequência,scriptado,processo-em-lote pipeline.tags=automatizar,sequência,scriptado,processo-em-lote
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remover imagem
home.removeImagePdf.desc=Remova a imagem do PDF para reduzir o tamanho do arquivo home.removeImagePdf.desc=Remova a imagem do PDF para reduzir o tamanho do arquivo
removeImagePdf.tags=Remover imagem,operações de página,back-end,lado do servidor removeImagePdf.tags=Remover imagem,operações de página,back-end,lado do servidor
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Acesso negado
login.oauth2InvalidTokenResponse=Resposta de token inválida login.oauth2InvalidTokenResponse=Resposta de token inválida
login.oauth2InvalidIdToken=Id de token inválido login.oauth2InvalidIdToken=Id de token inválido
login.userIsDisabled=O usuário está desativado, o login está atualmente bloqueado com este nome de usuário. Entre em contato com o administrador. login.userIsDisabled=O usuário está desativado, o login está atualmente bloqueado com este nome de usuário. Entre em contato com o administrador.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Redigir automaticamente autoRedact.title=Redigir automaticamente
@ -1154,6 +1182,8 @@ licenses.license=Licença
survey.nav=Pesquisa survey.nav=Pesquisa
survey.title=Pesquisa Stirling-PDF survey.title=Pesquisa Stirling-PDF
survey.description=Stirling-PDF não tem rastreamento, então queremos ouvir nossos usuários para melhorar o Stirling-PDF! survey.description=Stirling-PDF não tem rastreamento, então queremos ouvir nossos usuários para melhorar o Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Por favor, considere responder à nossa pesquisa! survey.please=Por favor, considere responder à nossa pesquisa!
survey.disabled=(O pop-up da pesquisa será desativado nas atualizações seguintes, mas estará disponível no final da página) survey.disabled=(O pop-up da pesquisa será desativado nas atualizações seguintes, mas estará disponível no final da página)
survey.button=Responda a pesquisa survey.button=Responda a pesquisa
@ -1179,3 +1209,17 @@ removeImage.title=Remover imagem
removeImage.header=Remover imagem removeImage.header=Remover imagem
removeImage.removeImage=Remover imagem removeImage.removeImage=Remover imagem
removeImage.submit=Remover imagem removeImage.submit=Remover imagem
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Descarregar pipelineOptions.saveButton=Descarregar
pipelineOptions.validateButton=Validar pipelineOptions.validateButton=Validar
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Edição Automática autoRedact.title=Edição Automática
@ -1154,6 +1182,8 @@ licenses.license=Licença
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donează
color=Culoare color=Culoare
sponsor=Sponsor sponsor=Sponsor
info=Informații info=Informații
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Descarcă pipelineOptions.saveButton=Descarcă
pipelineOptions.validateButton=Validează pipelineOptions.validateButton=Validează
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convertește din PDF
navbar.sections.security=Semnează & Securitate navbar.sections.security=Semnează & Securitate
navbar.sections.advance=Avansat navbar.sections.advance=Avansat
navbar.sections.edit=Vizualizează & Editează navbar.sections.edit=Vizualizează & Editează
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Fișierul nu a fost găsit
database.fileNullOrEmpty=Fișierul nu trebuie să fie nul sau gol database.fileNullOrEmpty=Fișierul nu trebuie să fie nul sau gol
database.failedImportFile=Importul Fișierului a Eșuat database.failedImportFile=Importul Fișierului a Eșuat
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Elimină imagine
home.removeImagePdf.desc=Elimină imaginea din PDF pentru a reduce dimensiunea fișierului home.removeImagePdf.desc=Elimină imaginea din PDF pentru a reduce dimensiunea fișierului
removeImagePdf.tags=Elimină Imagine,Operații pagină,Back end,server side removeImagePdf.tags=Elimină Imagine,Operații pagină,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Acces Refuzat
login.oauth2InvalidTokenResponse=Răspuns Invalid la Token login.oauth2InvalidTokenResponse=Răspuns Invalid la Token
login.oauth2InvalidIdToken=Token de Id Invalid login.oauth2InvalidIdToken=Token de Id Invalid
login.userIsDisabled=Utilizatorul este dezactivat, conectarea este în prezent blocată cu acest nume de utilizator. Te rugăm să contactezi administratorul. login.userIsDisabled=Utilizatorul este dezactivat, conectarea este în prezent blocată cu acest nume de utilizator. Te rugăm să contactezi administratorul.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Redactare Automată autoRedact.title=Redactare Automată
@ -1154,6 +1182,8 @@ licenses.license=Licență
survey.nav=Sondaj survey.nav=Sondaj
survey.title=Sondaj Stirling-PDF survey.title=Sondaj Stirling-PDF
survey.description=Stirling-PDF nu are urmărire, așa că vrem să auzim de la utilizatorii noștri pentru a îmbunătăți Stirling-PDF! survey.description=Stirling-PDF nu are urmărire, așa că vrem să auzim de la utilizatorii noștri pentru a îmbunătăți Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Te rugăm să iei în considerare completarea sondajului nostru! survey.please=Te rugăm să iei în considerare completarea sondajului nostru!
survey.disabled=(Fereastra pop-up a sondajului va fi dezactivată în următoarele actualizări, dar va fi disponibilă în subsolul paginii) survey.disabled=(Fereastra pop-up a sondajului va fi dezactivată în următoarele actualizări, dar va fi disponibilă în subsolul paginii)
survey.button=Completează Sondajul survey.button=Completează Sondajul
@ -1179,3 +1209,17 @@ removeImage.title=Elimină imagine
removeImage.header=Elimină imagine removeImage.header=Elimină imagine
removeImage.removeImage=Elimină imagine removeImage.removeImage=Elimină imagine
removeImage.submit=Elimină imagine removeImage.submit=Elimină imagine
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Пожертвовать
color=Цвет color=Цвет
sponsor=Спонсор sponsor=Спонсор
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Конвейер:
pipelineOptions.saveButton=Скачать pipelineOptions.saveButton=Скачать
pipelineOptions.validateButton=Проверить pipelineOptions.validateButton=Проверить
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Автоматическое редактирование autoRedact.title=Автоматическое редактирование
@ -1154,6 +1182,8 @@ licenses.license=Лицензия
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Darovať
color=Farba color=Farba
sponsor=Sponzorovať sponsor=Sponzorovať
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Stiahnuť pipelineOptions.saveButton=Stiahnuť
pipelineOptions.validateButton=Overiť pipelineOptions.validateButton=Overiť
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Prispôsobiť veľkosť/škálovanie stránok
home.scalePages.desc=Zmeniť veľkosť/škálovanie stránky a/alebo jej obsahu. home.scalePages.desc=Zmeniť veľkosť/škálovanie stránky a/alebo jej obsahu.
scalePages.tags=veľkosť,modifikovať,rozmery,prispôsobiť scalePages.tags=veľkosť,modifikovať,rozmery,prispôsobiť
home.pipeline.title=Pipeline (Pokročilé) home.pipeline.title=Pipeline
home.pipeline.desc=Spustiť viacero akcií na PDF definovaním pipeline skriptov home.pipeline.desc=Spustiť viacero akcií na PDF definovaním pipeline skriptov
pipeline.tags=automatizovať,sekvencia,skriptované,dávkové spracovanie pipeline.tags=automatizovať,sekvencia,skriptované,dávkové spracovanie
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Automatické redigovanie autoRedact.title=Automatické redigovanie
@ -1154,6 +1182,8 @@ licenses.license=Licencia
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donate
color=Color color=Color
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Preuzmi pipelineOptions.saveButton=Preuzmi
pipelineOptions.validateButton=Proveri pipelineOptions.validateButton=Proveri
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit navbar.sections.edit=View & Edit
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File database.failedImportFile=Failed Import File
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token login.oauth2InvalidIdToken=Invalid Id Token
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto Cenzura autoRedact.title=Auto Cenzura
@ -1154,6 +1182,8 @@ licenses.license=License
survey.nav=Survey survey.nav=Survey
survey.title=Stirling-PDF Survey survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF! survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey! survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page) survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey survey.button=Take Survey
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Donera
color=Färg color=Färg
sponsor=Sponsor sponsor=Sponsor
info=Info info=Info
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Ladda ner pipelineOptions.saveButton=Ladda ner
pipelineOptions.validateButton=Validera pipelineOptions.validateButton=Validera
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=Konvertera från PDF
navbar.sections.security=Signera & Säkerhet navbar.sections.security=Signera & Säkerhet
navbar.sections.advance=Avancerat navbar.sections.advance=Avancerat
navbar.sections.edit=Visa & Redigera navbar.sections.edit=Visa & Redigera
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Filen hittades inte
database.fileNullOrEmpty=Filen får inte vara null eller tom database.fileNullOrEmpty=Filen får inte vara null eller tom
database.failedImportFile=Misslyckades med att importera fil database.failedImportFile=Misslyckades med att importera fil
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Ta bort bild
home.removeImagePdf.desc=Ta bort bild från PDF för att minska filstorlek home.removeImagePdf.desc=Ta bort bild från PDF för att minska filstorlek
removeImagePdf.tags=Ta bort bild,Sidoperationer,Backend,serversida removeImagePdf.tags=Ta bort bild,Sidoperationer,Backend,serversida
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Åtkomst nekad
login.oauth2InvalidTokenResponse=Ogiltigt token-svar login.oauth2InvalidTokenResponse=Ogiltigt token-svar
login.oauth2InvalidIdToken=Ogiltigt Id-token login.oauth2InvalidIdToken=Ogiltigt Id-token
login.userIsDisabled=Användaren är inaktiverad, inloggning är för närvarande blockerad med detta användarnamn. Kontakta administratören. login.userIsDisabled=Användaren är inaktiverad, inloggning är för närvarande blockerad med detta användarnamn. Kontakta administratören.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Auto-redigera autoRedact.title=Auto-redigera
@ -1154,6 +1182,8 @@ licenses.license=Licens
survey.nav=Undersökning survey.nav=Undersökning
survey.title=Stirling-PDF-undersökning survey.title=Stirling-PDF-undersökning
survey.description=Stirling-PDF har ingen spårning så vi vill höra från våra användare för att förbättra Stirling-PDF! survey.description=Stirling-PDF har ingen spårning så vi vill höra från våra användare för att förbättra Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Vänligen överväg att delta i vår undersökning! survey.please=Vänligen överväg att delta i vår undersökning!
survey.disabled=(Undersökningspopup kommer att inaktiveras i kommande uppdateringar men finns tillgänglig längst ner på sidan) survey.disabled=(Undersökningspopup kommer att inaktiveras i kommande uppdateringar men finns tillgänglig längst ner på sidan)
survey.button=Delta i undersökningen survey.button=Delta i undersökningen
@ -1179,3 +1209,17 @@ removeImage.title=Ta bort bild
removeImage.header=Ta bort bild removeImage.header=Ta bort bild
removeImage.removeImage=Ta bort bild removeImage.removeImage=Ta bort bild
removeImage.submit=Ta bort bild removeImage.submit=Ta bort bild
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=บริจาค
color=สี color=สี
sponsor=ผู้สนับสนุน sponsor=ผู้สนับสนุน
info=ข้อมูล info=ข้อมูล
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=ดาวน์โหลด pipelineOptions.saveButton=ดาวน์โหลด
pipelineOptions.validateButton=ตรวจสอบความถูกต้อง pipelineOptions.validateButton=ตรวจสอบความถูกต้อง
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=แปลงจาก PDF
navbar.sections.security=ลงนามและความปลอดภัย navbar.sections.security=ลงนามและความปลอดภัย
navbar.sections.advance=ขั้นสูง navbar.sections.advance=ขั้นสูง
navbar.sections.edit=ดูและแก้ไข navbar.sections.edit=ดูและแก้ไข
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=ไม่พบไฟล์
database.fileNullOrEmpty=ไฟล์ต้องไม่ว่างเปล่าหรือไม่มีข้อมูล database.fileNullOrEmpty=ไฟล์ต้องไม่ว่างเปล่าหรือไม่มีข้อมูล
database.failedImportFile=การนำเข้าไฟล์ล้มเหลว database.failedImportFile=การนำเข้าไฟล์ล้มเหลว
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -482,6 +502,11 @@ home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=การเข้าถึงถูกปฏิเส
login.oauth2InvalidTokenResponse=การตอบกลับโทเค็นไม่ถูกต้อง login.oauth2InvalidTokenResponse=การตอบกลับโทเค็นไม่ถูกต้อง
login.oauth2InvalidIdToken=โทเค็น Id ไม่ถูกต้อง login.oauth2InvalidIdToken=โทเค็น Id ไม่ถูกต้อง
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator. login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=ซ่อนข้อมูลอัตโนมัติ autoRedact.title=ซ่อนข้อมูลอัตโนมัติ
@ -1154,6 +1182,8 @@ licenses.license=ใบอนุญาต
survey.nav=สำรวจ survey.nav=สำรวจ
survey.title=สำรวจ Stirling-PDF survey.title=สำรวจ Stirling-PDF
survey.description=Stirling-PDF ไม่มีการติดตาม ดังนั้นเราต้องการฟังความคิดเห็นจากผู้ใช้เพื่อปรับปรุง Stirling-PDF! survey.description=Stirling-PDF ไม่มีการติดตาม ดังนั้นเราต้องการฟังความคิดเห็นจากผู้ใช้เพื่อปรับปรุง Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=กรุณาพิจารณาการสำรวจของเรา! survey.please=กรุณาพิจารณาการสำรวจของเรา!
survey.disabled=(ป๊อปอัปการสำรวจจะถูกปิดใช้งานในการอัปเดตต่อไปนี้ แต่สามารถใช้ได้ที่ส่วนท้ายของหน้า) survey.disabled=(ป๊อปอัปการสำรวจจะถูกปิดใช้งานในการอัปเดตต่อไปนี้ แต่สามารถใช้ได้ที่ส่วนท้ายของหน้า)
survey.button=เริ่มสำรวจ survey.button=เริ่มสำรวจ
@ -1179,3 +1209,17 @@ removeImage.title=Remove image
removeImage.header=Remove image removeImage.header=Remove image
removeImage.removeImage=Remove image removeImage.removeImage=Remove image
removeImage.submit=Remove image removeImage.submit=Remove image
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@ -76,6 +76,7 @@ donate=Bağış Yapın
color=Renk color=Renk
sponsor=Bağış sponsor=Bağış
info=Bilgi info=Bilgi
pro=Pro
page=Page page=Page
pages=Pages pages=Pages
@ -110,8 +111,24 @@ pipelineOptions.pipelineHeader=Çoklu İşlemler:
pipelineOptions.saveButton=İndir pipelineOptions.saveButton=İndir
pipelineOptions.validateButton=Doğrula pipelineOptions.validateButton=Doğrula
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
############# #############
# NAVBAR # # NAVBAR #
@ -128,6 +145,7 @@ navbar.sections.convertFrom=PDF'den dönüştür
navbar.sections.security=Oturum ve Güvenlik navbar.sections.security=Oturum ve Güvenlik
navbar.sections.advance=Gelişmiş navbar.sections.advance=Gelişmiş
navbar.sections.edit=Görüntüle ve Düzenle navbar.sections.edit=Görüntüle ve Düzenle
navbar.sections.popular=Popular
############# #############
# SETTINGS # # SETTINGS #
@ -225,6 +243,8 @@ database.fileNotFound=Dosya bulunamadı
database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır database.fileNullOrEmpty=Dosya yok veya boş olmamalıdır
database.failedImportFile=Dosya İçe Aktarılamadı database.failedImportFile=Dosya İçe Aktarılamadı
session.expired=Your session has expired. Please refresh the page and try again.
############# #############
# HOME-PAGE # # HOME-PAGE #
############# #############
@ -382,7 +402,7 @@ home.scalePages.title=Sayfa boyutunu/ölçeğini ayarla
home.scalePages.desc=Bir sayfanın ve/veya içeriğinin boyutunu/ölçeğini değiştirir home.scalePages.desc=Bir sayfanın ve/veya içeriğinin boyutunu/ölçeğini değiştirir
scalePages.tags=boyutlandır,değiştir,boyut,uyarla scalePages.tags=boyutlandır,değiştir,boyut,uyarla
home.pipeline.title=Çoklu İşlemler (İleri Seviye) home.pipeline.title=Çoklu İşlemler
home.pipeline.desc=Çoklu İşlemler tanımlayarak PDF'lere birden fazla işlemi çalıştır home.pipeline.desc=Çoklu İşlemler tanımlayarak PDF'lere birden fazla işlemi çalıştır
pipeline.tags=otomatikleştir,sıralı,betikli,toplu-işlem pipeline.tags=otomatikleştir,sıralı,betikli,toplu-işlem
@ -482,6 +502,11 @@ home.removeImagePdf.title=Resmi kaldır
home.removeImagePdf.desc=Dosya boyutunu küçültmek için PDF'den resmi kaldırın home.removeImagePdf.desc=Dosya boyutunu küçültmek için PDF'den resmi kaldırın
removeImagePdf.tags=Resmi Kaldır,Sayfa İşlemleri,Arka uç,sunucu tarafı removeImagePdf.tags=Resmi Kaldır,Sayfa İşlemleri,Arka uç,sunucu tarafı
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color #replace-invert-color
replace-color.title=Replace-Invert-Color replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF replace-color.header=Replace-Invert Color PDF
@ -526,7 +551,10 @@ login.oauth2AccessDenied=Erişim Reddedildi
login.oauth2InvalidTokenResponse=Geçersiz Belirteç Yanıtı login.oauth2InvalidTokenResponse=Geçersiz Belirteç Yanıtı
login.oauth2InvalidIdToken=Geçersiz Kimlik Belirteci login.oauth2InvalidIdToken=Geçersiz Kimlik Belirteci
login.userIsDisabled=Kullanıcı devre dışı bırakıldı, şu anda bu kullanıcı adıyla giriş engellendi. Lütfen yöneticiyle iletişime geçin. login.userIsDisabled=Kullanıcı devre dışı bırakıldı, şu anda bu kullanıcı adıyla giriş engellendi. Lütfen yöneticiyle iletişime geçin.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact #auto-redact
autoRedact.title=Otomatik Karartma autoRedact.title=Otomatik Karartma
@ -1154,6 +1182,8 @@ licenses.license=Lisans
survey.nav=Anket survey.nav=Anket
survey.title=Stirling-PDF Anketi survey.title=Stirling-PDF Anketi
survey.description=Stirling-PDF'te izleme yok, bu yüzden Stirling-PDF'i iyileştirmek için kullanıcılarımızdan geri bildirim almak istiyoruz! survey.description=Stirling-PDF'te izleme yok, bu yüzden Stirling-PDF'i iyileştirmek için kullanıcılarımızdan geri bildirim almak istiyoruz!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Lütfen anketimize katılmayı düşünün! survey.please=Lütfen anketimize katılmayı düşünün!
survey.disabled=(Anket açılır penceresi sonraki güncellemelerde devre dışı bırakılacak ancak sayfanın alt kısmında yer alacaktır) survey.disabled=(Anket açılır penceresi sonraki güncellemelerde devre dışı bırakılacak ancak sayfanın alt kısmında yer alacaktır)
survey.button=Ankete Katıl survey.button=Ankete Katıl
@ -1179,3 +1209,17 @@ removeImage.title=Resmi kaldır
removeImage.header=Resmi kaldır removeImage.header=Resmi kaldır
removeImage.removeImage=Resmi kaldır removeImage.removeImage=Resmi kaldır
removeImage.submit=Resmi kaldır removeImage.submit=Resmi kaldır
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

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